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