bo4e_core/com/
contact_method.rs

1//! Contact method (Kontaktweg) component.
2
3use serde::{Deserialize, Serialize};
4
5use crate::enums::ContactType;
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8/// Method of contact (email, phone, etc.).
9///
10/// Used to represent contact information for a person within business objects.
11///
12/// German: Kontaktweg
13///
14/// # Example
15///
16/// ```rust
17/// use bo4e_core::com::ContactMethod;
18/// use bo4e_core::enums::ContactType;
19///
20/// let contact = ContactMethod {
21///     contact_type: Some(ContactType::Email),
22///     contact_value: Some("info@example.com".to_string()),
23///     is_preferred: Some(true),
24///     ..Default::default()
25/// };
26/// ```
27#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
28#[serde(rename_all = "camelCase")]
29pub struct ContactMethod {
30    /// BO4E metadata
31    #[serde(flatten)]
32    pub meta: Bo4eMeta,
33
34    /// Type of contact (Kontaktart)
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub contact_type: Option<ContactType>,
37
38    /// Contact value - phone number, email address, etc. (Kontaktwert)
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub contact_value: Option<String>,
41
42    /// Description/specification, e.g., "direct line", "switchboard" (Beschreibung)
43    #[serde(skip_serializing_if = "Option::is_none")]
44    pub description: Option<String>,
45
46    /// Whether this is the preferred contact method (IstBevorzugterKontaktweg)
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub is_preferred: Option<bool>,
49}
50
51impl Bo4eObject for ContactMethod {
52    fn type_name_german() -> &'static str {
53        "Kontaktweg"
54    }
55
56    fn type_name_english() -> &'static str {
57        "ContactMethod"
58    }
59
60    fn meta(&self) -> &Bo4eMeta {
61        &self.meta
62    }
63
64    fn meta_mut(&mut self) -> &mut Bo4eMeta {
65        &mut self.meta
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn test_contact_method_default() {
75        let contact = ContactMethod::default();
76        assert!(contact.contact_type.is_none());
77        assert!(contact.contact_value.is_none());
78        assert!(contact.is_preferred.is_none());
79    }
80
81    #[test]
82    fn test_email_contact() {
83        let contact = ContactMethod {
84            contact_type: Some(ContactType::Email),
85            contact_value: Some("test@example.com".to_string()),
86            is_preferred: Some(true),
87            ..Default::default()
88        };
89
90        let json = serde_json::to_string(&contact).unwrap();
91        assert!(json.contains(r#""contactType":"E_MAIL""#));
92        assert!(json.contains(r#""contactValue":"test@example.com""#));
93        assert!(json.contains(r#""isPreferred":true"#));
94
95        let parsed: ContactMethod = serde_json::from_str(&json).unwrap();
96        assert_eq!(contact, parsed);
97    }
98
99    #[test]
100    fn test_phone_contact() {
101        let contact = ContactMethod {
102            contact_type: Some(ContactType::Phone),
103            contact_value: Some("+49 221 1234567".to_string()),
104            description: Some("Direct line".to_string()),
105            ..Default::default()
106        };
107
108        let json = serde_json::to_string(&contact).unwrap();
109        assert!(json.contains(r#""contactType":"TELEFON""#));
110        assert!(json.contains(r#""description":"Direct line""#));
111
112        let parsed: ContactMethod = serde_json::from_str(&json).unwrap();
113        assert_eq!(contact, parsed);
114    }
115
116    #[test]
117    fn test_contact_method_roundtrip() {
118        let contact = ContactMethod {
119            meta: Bo4eMeta::with_type("Kontaktweg"),
120            contact_type: Some(ContactType::Fax),
121            contact_value: Some("+49 221 1234568".to_string()),
122            description: Some("Fax number".to_string()),
123            is_preferred: Some(false),
124        };
125
126        let json = serde_json::to_string(&contact).unwrap();
127        let parsed: ContactMethod = serde_json::from_str(&json).unwrap();
128        assert_eq!(contact, parsed);
129    }
130
131    #[test]
132    fn test_bo4e_object_impl() {
133        assert_eq!(ContactMethod::type_name_german(), "Kontaktweg");
134        assert_eq!(ContactMethod::type_name_english(), "ContactMethod");
135    }
136}