relay_event_schema/protocol/contexts/
culture.rs

1use relay_protocol::{Annotated, Empty, FromValue, IntoValue, Object, Value};
2
3use crate::processor::ProcessValue;
4
5/// Culture information.
6///
7/// Culture context describes the cultural properties relevant to how software is used
8/// in specific regions or locales.
9#[derive(Clone, Debug, Default, PartialEq, Empty, FromValue, IntoValue, ProcessValue)]
10pub struct CultureContext {
11    /// The calendar system in use.
12    ///
13    /// For example, `GregorianCalendar`.
14    #[metastructure(pii = "maybe")]
15    pub calendar: Annotated<String>,
16
17    /// Human-readable name of the culture.
18    ///
19    /// For example, `English (United States)`.
20    #[metastructure(pii = "maybe")]
21    pub display_name: Annotated<String>,
22
23    /// The name identifier, usually following the RFC 4646.
24    ///
25    /// For example, `en-US` or `pt-BR`.
26    #[metastructure(pii = "maybe")]
27    pub locale: Annotated<String>,
28
29    /// Whether the locale uses 24-hour time format.
30    #[metastructure(pii = "maybe")]
31    pub is_24_hour_format: Annotated<bool>,
32
33    /// The timezone of the locale.
34    ///
35    /// For example, `Europe/Vienna`.
36    #[metastructure(pii = "maybe")]
37    pub timezone: Annotated<String>,
38
39    /// Additional arbitrary fields for forwards compatibility.
40    #[metastructure(additional_properties, retain = true, pii = "maybe")]
41    pub other: Object<Value>,
42}
43
44impl super::DefaultContext for CultureContext {
45    fn default_key() -> &'static str {
46        "culture"
47    }
48
49    fn from_context(context: super::Context) -> Option<Self> {
50        match context {
51            super::Context::Culture(c) => Some(*c),
52            _ => None,
53        }
54    }
55
56    fn cast(context: &super::Context) -> Option<&Self> {
57        match context {
58            super::Context::Culture(c) => Some(c),
59            _ => None,
60        }
61    }
62
63    fn cast_mut(context: &mut super::Context) -> Option<&mut Self> {
64        match context {
65            super::Context::Culture(c) => Some(c),
66            _ => None,
67        }
68    }
69
70    fn into_context(self) -> super::Context {
71        super::Context::Culture(Box::new(self))
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78    use crate::protocol::Context;
79
80    #[test]
81    fn test_culture_context_roundtrip() {
82        let json = r#"{
83  "calendar": "GregorianCalendar",
84  "display_name": "English (United States)",
85  "locale": "en-US",
86  "is_24_hour_format": false,
87  "timezone": "Europe/Vienna",
88  "other": "value",
89  "type": "culture"
90}"#;
91        let context = Annotated::new(Context::Culture(Box::new(CultureContext {
92            calendar: Annotated::new("GregorianCalendar".to_owned()),
93            display_name: Annotated::new("English (United States)".to_owned()),
94            locale: Annotated::new("en-US".to_owned()),
95            is_24_hour_format: Annotated::new(false),
96            timezone: Annotated::new("Europe/Vienna".to_owned()),
97            other: {
98                let mut map = Object::new();
99                map.insert(
100                    "other".to_owned(),
101                    Annotated::new(Value::String("value".to_owned())),
102                );
103                map
104            },
105        })));
106
107        assert_eq!(context, Annotated::from_json(json).unwrap());
108        assert_eq!(json, context.to_json_pretty().unwrap());
109    }
110}