diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f91b9d5d30..7eb39bf07c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ **Features**: - Apply clock drift correction to logs and trace metrics. ([#5609](https://github.com/getsentry/relay/pull/5609)) +- Add Culture context to event schema. ([#5615](https://github.com/getsentry/relay/pull/5615)) **Internal**: diff --git a/relay-event-schema/src/protocol/contexts/culture.rs b/relay-event-schema/src/protocol/contexts/culture.rs new file mode 100644 index 00000000000..ac1d349646e --- /dev/null +++ b/relay-event-schema/src/protocol/contexts/culture.rs @@ -0,0 +1,110 @@ +use relay_protocol::{Annotated, Empty, FromValue, IntoValue, Object, Value}; + +use crate::processor::ProcessValue; + +/// Culture information. +/// +/// Culture context describes the cultural properties relevant to how software is used +/// in specific regions or locales. +#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)] +pub struct CultureContext { + /// The calendar system in use. + /// + /// For example, `GregorianCalendar`. + #[metastructure(pii = "maybe")] + pub calendar: Annotated, + + /// Human-readable name of the culture. + /// + /// For example, `English (United States)`. + #[metastructure(pii = "maybe")] + pub display_name: Annotated, + + /// The name identifier, usually following the RFC 4646. + /// + /// For example, `en-US` or `pt-BR`. + #[metastructure(pii = "maybe")] + pub locale: Annotated, + + /// Whether the locale uses 24-hour time format. + #[metastructure(pii = "maybe")] + pub is_24_hour_format: Annotated, + + /// The timezone of the locale. + /// + /// For example, `Europe/Vienna`. + #[metastructure(pii = "maybe")] + pub timezone: Annotated, + + /// Additional arbitrary fields for forwards compatibility. + #[metastructure(additional_properties, retain = true, pii = "maybe")] + pub other: Object, +} + +impl super::DefaultContext for CultureContext { + fn default_key() -> &'static str { + "culture" + } + + fn from_context(context: super::Context) -> Option { + match context { + super::Context::Culture(c) => Some(*c), + _ => None, + } + } + + fn cast(context: &super::Context) -> Option<&Self> { + match context { + super::Context::Culture(c) => Some(c), + _ => None, + } + } + + fn cast_mut(context: &mut super::Context) -> Option<&mut Self> { + match context { + super::Context::Culture(c) => Some(c), + _ => None, + } + } + + fn into_context(self) -> super::Context { + super::Context::Culture(Box::new(self)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::protocol::Context; + + #[test] + fn test_culture_context_roundtrip() { + let json = r#"{ + "calendar": "GregorianCalendar", + "display_name": "English (United States)", + "locale": "en-US", + "is_24_hour_format": false, + "timezone": "Europe/Vienna", + "other": "value", + "type": "culture" +}"#; + let context = Annotated::new(Context::Culture(Box::new(CultureContext { + calendar: Annotated::new("GregorianCalendar".to_owned()), + display_name: Annotated::new("English (United States)".to_owned()), + locale: Annotated::new("en-US".to_owned()), + is_24_hour_format: Annotated::new(false), + timezone: Annotated::new("Europe/Vienna".to_owned()), + other: { + let mut map = Object::new(); + map.insert( + "other".to_owned(), + Annotated::new(Value::String("value".to_owned())), + ); + map + }, + }))); + + assert_eq!(context, Annotated::from_json(json).unwrap()); + assert_eq!(json, context.to_json_pretty().unwrap()); + } +} diff --git a/relay-event-schema/src/protocol/contexts/mod.rs b/relay-event-schema/src/protocol/contexts/mod.rs index f9c63b20c37..43afa71e7b3 100644 --- a/relay-event-schema/src/protocol/contexts/mod.rs +++ b/relay-event-schema/src/protocol/contexts/mod.rs @@ -2,6 +2,7 @@ mod app; mod browser; mod chromium_stability_report; mod cloud_resource; +mod culture; mod device; mod flags; mod gpu; @@ -26,6 +27,7 @@ pub use app::*; pub use browser::*; pub use chromium_stability_report::*; pub use cloud_resource::*; +pub use culture::*; pub use device::*; pub use gpu::*; pub use memory_info::*; @@ -101,6 +103,8 @@ pub enum Context { Otel(Box), /// Cloud resource information. CloudResource(Box), + /// Culture information. + Culture(Box), /// Nel information. Nel(Box), /// Performance score information.