vcard_parser/vcard/property/
property_email.rs

1use crate::constants::{Cardinality, ParameterName, PropertyName, ValueType};
2use crate::traits::{HasCardinality, HasGroup, HasName, HasParameters, HasValue};
3use crate::vcard::parameter::Parameter;
4use crate::vcard::value::value_text::ValueTextData;
5use crate::vcard::value::value_uri::ValueUriData;
6use crate::vcard::value::Value;
7use crate::vcard::value::Value::{ValueText, ValueUri};
8use crate::VcardError;
9
10#[derive(Clone, Debug, PartialEq)]
11pub struct PropertyEmailData {
12    group: Option<String>,
13    parameters: Vec<Parameter>,
14    value: Value,
15}
16
17impl HasCardinality for PropertyEmailData {
18    fn cardinality(&self) -> &str {
19        Cardinality::MULTIPLE
20    }
21}
22
23impl HasGroup for PropertyEmailData {
24    fn group(&self) -> &Option<String> {
25        &self.group
26    }
27}
28
29impl HasName for PropertyEmailData {
30    fn name(&self) -> &str {
31        PropertyName::EMAIL
32    }
33}
34
35impl HasParameters for PropertyEmailData {
36    fn allowed_parameters<'a>(&self) -> Vec<&'a str> {
37        Vec::from([
38            ParameterName::ALTID,
39            ParameterName::ANY,
40            ParameterName::INDEX,
41            ParameterName::PID,
42            ParameterName::PREF,
43            ParameterName::TYPE,
44            ParameterName::VALUE,
45        ])
46    }
47
48    fn get_parameters(&self) -> Vec<Parameter> {
49        self.parameters.clone()
50    }
51
52    fn set_parameters(&mut self, parameters: Vec<Parameter>) {
53        self.parameters = parameters;
54    }
55}
56
57impl HasValue for PropertyEmailData {
58    fn get_value(&self) -> &Value {
59        &self.value
60    }
61
62    fn set_value(&mut self, value: Value) -> Result<(), VcardError> {
63        if !matches!(value, ValueText(_)) && !matches!(value, ValueUri(_)) {
64            return Err(VcardError::ValueNotAllowed(value.to_string(), self.name().to_string()));
65        }
66
67        if let Some(value_type) = self.has_value_type() {
68            if matches!(value, ValueText(_)) && value_type != ValueType::TEXT {
69                return Err(VcardError::ValueMismatch(value.to_string(), value_type, self.name().to_string()));
70            }
71            if matches!(value, ValueUri(_)) && value_type != ValueType::URI {
72                return Err(VcardError::ValueMismatch(value.to_string(), value_type, self.name().to_string()));
73            }
74        }
75
76        self.value = value;
77
78        Ok(())
79    }
80}
81
82impl Default for PropertyEmailData {
83    fn default() -> Self {
84        Self {
85            group: None,
86            parameters: Vec::new(),
87            value: ValueText(ValueTextData::default()),
88        }
89    }
90}
91
92impl TryFrom<(Option<String>, &str, Vec<Parameter>)> for PropertyEmailData {
93    type Error = VcardError;
94    fn try_from((group, value, parameters): (Option<String>, &str, Vec<Parameter>)) -> Result<Self, Self::Error> {
95        let mut property = Self { group, ..Self::default() };
96
97        property.add_parameters(parameters)?;
98
99        if let Some(value_type) = property.has_value_type() {
100            if value_type == ValueType::TEXT {
101                property.set_value(ValueText(ValueTextData::from(value)))?;
102            } else if value_type == ValueType::URI {
103                property.set_value(ValueUri(ValueUriData::try_from(value)?))?;
104            }
105        } else {
106            property.set_value(match ValueUriData::try_from(value) {
107                Ok(data) => ValueUri(data),
108                Err(_) => ValueText(ValueTextData::from(value)),
109            })?;
110        }
111
112        Ok(property)
113    }
114}