srad_types/
property_set.rs1use std::collections::HashMap;
2
3use crate::{
4 constants::QUALITY,
5 payload::{self, property_value},
6 quality::Quality,
7 traits, PropertyValue as PropertyValueValue,
8};
9
10#[derive(Debug)]
11struct PropertyValue {
12 value: Option<PropertyValueValue>,
13 datatype: Option<payload::DataType>,
14}
15
16impl From<PropertyValue> for payload::PropertyValue {
17 fn from(value: PropertyValue) -> Self {
18 let mut is_null = None;
19 let mut pvv = None;
20 match value.value {
21 Some(v) => pvv = Some(v.into()),
22 None => is_null = Some(true),
23 }
24 payload::PropertyValue {
25 r#type: value.datatype.map(|x| x as u32),
26 is_null,
27 value: pvv,
28 }
29 }
30}
31
32impl TryFrom<payload::PropertyValue> for PropertyValue {
33 type Error = ();
34
35 fn try_from(payload: payload::PropertyValue) -> Result<Self, Self::Error> {
36 let value = if let Some(value) = payload.value {
37 Some(PropertyValueValue::new(value))
38 } else if let Some(is_null) = payload.is_null {
39 if is_null {
40 None
41 } else {
42 return Err(());
43 }
44 } else {
45 return Err(());
46 };
47
48 let ty = match payload.r#type {
49 Some(v) => Some(v.try_into()?),
50 None => None,
51 };
52 Ok(Self {
53 value,
54 datatype: ty,
55 })
56 }
57}
58
59#[derive(Debug)]
61pub struct PropertySet(HashMap<String, PropertyValue>);
62
63impl Default for PropertySet {
64 fn default() -> Self {
65 Self::new()
66 }
67}
68
69impl PropertySet {
70 pub fn new_with_quality(quality: Quality) -> Self {
71 let mut pset = PropertySet(HashMap::new());
72 pset.0.insert(
73 QUALITY.to_string(),
74 PropertyValue {
75 value: Some(quality.into()),
76 datatype: Some(payload::DataType::Int32),
77 },
78 );
79 pset
80 }
81
82 pub fn new() -> Self {
83 Self::new_with_quality(Quality::Good)
84 }
85
86 #[allow(clippy::result_unit_err)]
87 pub fn insert<K: Into<String>, V: traits::PropertyValue>(
88 &mut self,
89 k: K,
90 v: Option<V>,
91 ) -> Result<(), ()> {
92 let key = k.into();
93 if key == QUALITY {
94 return Err(());
95 }
96 let pv = PropertyValue {
97 value: v.map(V::into),
98 datatype: Some(V::default_datatype()),
99 };
100 self.0.insert(key, pv);
101 Ok(())
102 }
103}
104
105impl traits::HasDataType for PropertySet {
106 fn supported_datatypes() -> &'static [payload::DataType] {
107 static SUPPORTED_TYPES: [payload::DataType; 1] = [payload::DataType::PropertySet];
108 &SUPPORTED_TYPES
109 }
110}
111
112impl TryFrom<PropertyValueValue> for PropertySet {
113 type Error = ();
114
115 fn try_from(value: PropertyValueValue) -> Result<Self, Self::Error> {
116 let value: payload::property_value::Value = value.into();
117 if let payload::property_value::Value::PropertysetValue(v) = value {
118 Ok(v.try_into()?)
119 } else {
120 Err(())
121 }
122 }
123}
124
125impl From<PropertySet> for PropertyValueValue {
126 fn from(value: PropertySet) -> Self {
127 PropertyValueValue::new(property_value::Value::PropertysetValue(value.into()))
128 }
129}
130
131impl traits::PropertyValue for PropertySet {}
132
133impl From<PropertySet> for payload::PropertySet {
134 fn from(value: PropertySet) -> Self {
135 let len = value.0.len();
136 let mut keys = Vec::with_capacity(len);
137 let mut values: Vec<payload::PropertyValue> = Vec::with_capacity(len);
138 value.0.into_iter().for_each(|(k, v)| {
139 keys.push(k);
140 values.push(v.into());
141 });
142 payload::PropertySet { keys, values }
143 }
144}
145
146impl TryFrom<payload::PropertySet> for PropertySet {
147 type Error = ();
148
149 fn try_from(value: payload::PropertySet) -> Result<Self, Self::Error> {
150 let keys = value.keys;
151 let values = value.values;
152 let len = keys.len();
153 if len != values.len() {
154 return Err(());
155 }
156
157 let mut hashmap: HashMap<String, PropertyValue> = HashMap::with_capacity(len);
158 for (k, v) in keys.into_iter().zip(values) {
159 let value = v.try_into()?;
160 hashmap.insert(k, value);
161 }
162
163 Ok(PropertySet(hashmap))
164 }
165}
166
167type PropertySetList = Vec<PropertySet>;
168
169impl From<PropertySetList> for payload::PropertySetList {
170 fn from(value: PropertySetList) -> Self {
171 let mut out = Vec::with_capacity(value.len());
172 for x in value.into_iter() {
173 out.push(x.into())
174 }
175 payload::PropertySetList { propertyset: out }
176 }
177}
178
179impl TryFrom<payload::PropertySetList> for PropertySetList {
180 type Error = ();
181
182 fn try_from(value: payload::PropertySetList) -> Result<Self, Self::Error> {
183 let mut out = Vec::with_capacity(value.propertyset.len());
184 for x in value.propertyset.into_iter() {
185 out.push(x.try_into()?)
186 }
187 Ok(out)
188 }
189}
190
191impl traits::HasDataType for PropertySetList {
192 fn supported_datatypes() -> &'static [payload::DataType] {
193 static SUPPORTED_TYPES: [payload::DataType; 1] = [payload::DataType::PropertySetList];
194 &SUPPORTED_TYPES
195 }
196}
197
198impl TryFrom<PropertyValueValue> for PropertySetList {
199 type Error = ();
200
201 fn try_from(value: PropertyValueValue) -> Result<Self, Self::Error> {
202 let value: payload::property_value::Value = value.into();
203 if let payload::property_value::Value::PropertysetsValue(v) = value {
204 Ok(v.try_into()?)
205 } else {
206 Err(())
207 }
208 }
209}
210
211impl From<PropertySetList> for PropertyValueValue {
212 fn from(value: PropertySetList) -> Self {
213 PropertyValueValue::new(property_value::Value::PropertysetsValue(value.into()))
214 }
215}
216
217impl traits::PropertyValue for PropertySetList {}