1use crate::AdditionalAttribute;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
26#[serde(rename_all = "camelCase")]
27pub struct Bo4eMeta {
28 #[serde(rename = "_typ", skip_serializing_if = "Option::is_none")]
30 pub typ: Option<String>,
31
32 #[serde(rename = "_version", skip_serializing_if = "Option::is_none")]
34 pub version: Option<String>,
35
36 #[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
38 pub id: Option<String>,
39
40 #[serde(default, skip_serializing_if = "Vec::is_empty")]
42 pub zusatz_attribute: Vec<AdditionalAttribute>,
43}
44
45impl Bo4eMeta {
46 pub fn with_type(typ: impl Into<String>) -> Self {
48 Self {
49 typ: Some(typ.into()),
50 ..Default::default()
51 }
52 }
53
54 pub fn version(mut self, version: impl Into<String>) -> Self {
56 self.version = Some(version.into());
57 self
58 }
59
60 pub fn id(mut self, id: impl Into<String>) -> Self {
62 self.id = Some(id.into());
63 self
64 }
65
66 pub fn with_attribute(mut self, attr: AdditionalAttribute) -> Self {
68 self.zusatz_attribute.push(attr);
69 self
70 }
71}
72
73pub trait Bo4eObject {
78 fn type_name_german() -> &'static str;
82
83 fn type_name_english() -> &'static str;
87
88 fn meta(&self) -> &Bo4eMeta;
90
91 fn meta_mut(&mut self) -> &mut Bo4eMeta;
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn test_meta_default() {
101 let meta = Bo4eMeta::default();
102 assert!(meta.typ.is_none());
103 assert!(meta.version.is_none());
104 assert!(meta.id.is_none());
105 assert!(meta.zusatz_attribute.is_empty());
106 }
107
108 #[test]
109 fn test_meta_builder() {
110 let meta = Bo4eMeta::with_type("Zaehler")
111 .version("202401.0.1")
112 .id("ext-123");
113
114 assert_eq!(meta.typ, Some("Zaehler".to_string()));
115 assert_eq!(meta.version, Some("202401.0.1".to_string()));
116 assert_eq!(meta.id, Some("ext-123".to_string()));
117 }
118
119 #[test]
120 fn test_meta_serialize() {
121 let meta = Bo4eMeta::with_type("Zaehler").version("202401.0.1");
122 let json = serde_json::to_string(&meta).unwrap();
123
124 assert!(json.contains(r#""_typ":"Zaehler""#));
125 assert!(json.contains(r#""_version":"202401.0.1""#));
126 assert!(!json.contains("zusatzAttribute")); }
128
129 #[test]
130 fn test_meta_deserialize() {
131 let json = r#"{"_typ":"Zaehler","_version":"202401.0.1","_id":"123"}"#;
132 let meta: Bo4eMeta = serde_json::from_str(json).unwrap();
133
134 assert_eq!(meta.typ, Some("Zaehler".to_string()));
135 assert_eq!(meta.version, Some("202401.0.1".to_string()));
136 assert_eq!(meta.id, Some("123".to_string()));
137 }
138
139 #[test]
140 fn test_meta_with_zusatz_attribute() {
141 let meta = Bo4eMeta::with_type("Zaehler")
142 .with_attribute(crate::AdditionalAttribute::string("sap_id", "SAP001"));
143
144 assert_eq!(meta.zusatz_attribute.len(), 1);
145 assert_eq!(meta.zusatz_attribute[0].name, "sap_id");
146 }
147}