1
use crate::model::param::{Param, ParamInner};
2
use crate::model::property::{ComponentPropertiesInner, ComponentProperty, ComponentPropertyInner};
3

            
4
pub trait ComponentAccess {
5
    fn properties(&self) -> &[ComponentProperty];
6

            
7
18
    fn get_property<T>(&self) -> Option<&T>
8
18
    where
9
18
        ComponentProperty: ComponentPropertyInner<T>,
10
18
    {
11
52
        self.properties().iter().find_map(|p| p.property_inner())
12
18
    }
13

            
14
7
    fn get_properties<T>(&self) -> Vec<&T>
15
7
    where
16
7
        ComponentProperty: ComponentPropertiesInner<T>,
17
7
    {
18
7
        self.properties()
19
7
            .iter()
20
119
            .filter_map(|p| p.many_property_inner())
21
7
            .collect()
22
7
    }
23

            
24
2
    fn get_iana_properties(&self, name: &str) -> Vec<&str> {
25
2
        self.properties()
26
2
            .iter()
27
63
            .filter_map(|p| match p {
28
2
                ComponentProperty::IanaProperty(p) if p.name == name => Some(p.value.as_str()),
29
60
                _ => None,
30
63
            })
31
2
            .collect()
32
2
    }
33

            
34
2
    fn get_x_properties(&self, name: &str) -> Vec<&str> {
35
2
        self.properties()
36
2
            .iter()
37
63
            .filter_map(|p| match p {
38
2
                ComponentProperty::XProperty(p) if p.name == name => Some(p.value.as_str()),
39
60
                _ => None,
40
63
            })
41
2
            .collect()
42
2
    }
43
}
44

            
45
macro_rules! impl_component_access {
46
    ($for_type:ty) => {
47
        impl $crate::model::access::ComponentAccess for $for_type {
48
66
            fn properties(&self) -> &[$crate::model::property::ComponentProperty] {
49
66
                &self.properties
50
66
            }
51
        }
52
    };
53
}
54

            
55
pub(crate) use impl_component_access;
56

            
57
pub trait PropertyAccess<V> {
58
    fn value(&self) -> &V;
59

            
60
    fn params(&self) -> &[Param];
61

            
62
7
    fn get_param<T>(&self) -> Option<&T>
63
7
    where
64
7
        Param: ParamInner<T>,
65
7
    {
66
13
        self.params().iter().find_map(|p| p.param_inner())
67
7
    }
68

            
69
12
    fn get_iana_params(&self, name: &str) -> Vec<&str> {
70
12
        self.params()
71
12
            .iter()
72
34
            .filter_map(|p| match p {
73
24
                Param::Other {
74
24
                    name: param_name,
75
24
                    value,
76
24
                } if param_name == name => Some(value.as_str()),
77
16
                _ => None,
78
34
            })
79
12
            .collect()
80
12
    }
81

            
82
12
    fn get_x_params(&self, name: &str) -> Vec<&str> {
83
12
        self.params()
84
12
            .iter()
85
34
            .filter_map(|p| match p {
86
24
                Param::Other {
87
24
                    name: param_name,
88
24
                    value,
89
24
                } if param_name == name => Some(value.as_str()),
90
16
                _ => None,
91
34
            })
92
12
            .collect()
93
12
    }
94
}
95

            
96
macro_rules! impl_property_access {
97
    ($for_type:ty, $value_type:ty) => {
98
        impl $crate::model::access::PropertyAccess<$value_type> for $for_type {
99
54
            fn value(&self) -> &$value_type {
100
54
                &self.value
101
54
            }
102

            
103
90
            fn params(&self) -> &[$crate::model::param::Param] {
104
90
                &self.params
105
90
            }
106
        }
107
    };
108
}
109

            
110
pub(crate) use impl_property_access;