bo4e_core/
additional_attribute.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7#[serde(untagged)]
8pub enum AttributeValue {
9 String(String),
11 Number(f64),
13 Boolean(bool),
15 Object(Vec<AdditionalAttribute>),
17 Array(Vec<AttributeValue>),
19 Null,
21}
22
23#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
40#[serde(rename_all = "camelCase")]
41pub struct AdditionalAttribute {
42 pub name: String,
44 #[serde(skip_serializing_if = "Option::is_none")]
46 pub value: Option<AttributeValue>,
47}
48
49impl AdditionalAttribute {
50 pub fn string(name: impl Into<String>, value: impl Into<String>) -> Self {
52 Self {
53 name: name.into(),
54 value: Some(AttributeValue::String(value.into())),
55 }
56 }
57
58 pub fn number(name: impl Into<String>, value: f64) -> Self {
60 Self {
61 name: name.into(),
62 value: Some(AttributeValue::Number(value)),
63 }
64 }
65
66 pub fn boolean(name: impl Into<String>, value: bool) -> Self {
68 Self {
69 name: name.into(),
70 value: Some(AttributeValue::Boolean(value)),
71 }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn test_string_attribute() {
81 let attr = AdditionalAttribute::string("system_id", "ABC123");
82 assert_eq!(attr.name, "system_id");
83 assert_eq!(
84 attr.value,
85 Some(AttributeValue::String("ABC123".to_string()))
86 );
87 }
88
89 #[test]
90 fn test_number_attribute() {
91 let attr = AdditionalAttribute::number("priority", 42.0);
92 assert_eq!(attr.name, "priority");
93 assert_eq!(attr.value, Some(AttributeValue::Number(42.0)));
94 }
95
96 #[test]
97 fn test_serialize_attribute() {
98 let attr = AdditionalAttribute::string("key", "value");
99 let json = serde_json::to_string(&attr).unwrap();
100 assert_eq!(json, r#"{"name":"key","value":"value"}"#);
101 }
102
103 #[test]
104 fn test_deserialize_attribute() {
105 let json = r#"{"name":"key","value":"value"}"#;
106 let attr: AdditionalAttribute = serde_json::from_str(json).unwrap();
107 assert_eq!(attr.name, "key");
108 assert_eq!(
109 attr.value,
110 Some(AttributeValue::String("value".to_string()))
111 );
112 }
113
114 #[test]
115 fn test_deserialize_nested_attribute() {
116 let json = r#"{"name":"parent","value":[{"name":"child","value":123}]}"#;
117 let attr: AdditionalAttribute = serde_json::from_str(json).unwrap();
118 assert_eq!(attr.name, "parent");
119 match attr.value {
120 Some(AttributeValue::Object(children)) => {
121 assert_eq!(children.len(), 1);
122 assert_eq!(children[0].name, "child");
123 }
124 _ => panic!("Expected nested object"),
125 }
126 }
127}