messagebird_async/sms/
typedetails.rs1use super::*;
2use std::collections::{hash_set::Iter, HashSet};
3use std::fmt;
4
5use serde::de::{Deserialize, Deserializer, MapAccess, Visitor};
6use serde::ser::{Serialize, SerializeMap, Serializer};
7
8#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
12pub enum TypeDetail {
13 #[serde(rename = "udh")]
16 UserDataHeader(String),
17}
18
19use std::hash::{Hash, Hasher};
20
21impl Hash for TypeDetail {
22 fn hash<H: Hasher>(&self, state: &mut H) {
23 match self {
24 TypeDetail::UserDataHeader(_) => 1.hash(state),
25 }
27 }
28}
29
30impl TypeDetail {
31 pub fn try_from(src: (String, String)) -> Result<Self, MessageBirdError> {
32 match src.0.as_str() {
33 "udh" => Ok(TypeDetail::UserDataHeader(src.1)),
34 x => Err(MessageBirdError::TypeError {
35 msg: format!("Unknown TypeDetail \"{}\"", x),
36 }),
37 }
38 }
39
40 pub fn as_tuple(self) -> (String, String) {
41 match self {
42 TypeDetail::UserDataHeader(x) => (String::from("udh"), x),
43 }
45 }
46}
47
48#[derive(Clone, Debug, Eq, PartialEq)]
52pub struct TypeDetails {
53 inner: HashSet<TypeDetail>,
54}
55
56impl TypeDetails {
57 pub fn new() -> Self {
58 Self {
59 inner: HashSet::new(),
61 }
62 }
63
64 pub fn add(&mut self, td: TypeDetail) {
66 self.inner.insert(td);
67 }
68
69 pub fn iter(&mut self) -> Iter<TypeDetail> {
71 self.inner.iter()
72 }
73}
74
75impl Default for TypeDetails {
76 fn default() -> Self {
77 Self::new()
78 }
79}
80
81impl Serialize for TypeDetails {
82 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
83 where
84 S: Serializer,
85 {
86 let mut map = serializer.serialize_map(Some(self.inner.len()))?;
87 for x in &self.inner {
88 let (k, v) = x.clone().as_tuple();
89 map.serialize_entry(&k, &v)?;
90 }
91 map.end()
92 }
93}
94
95struct TypeDetailsVisitor;
96
97impl<'de> Visitor<'de> for TypeDetailsVisitor {
98 type Value = TypeDetails;
99
100 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
101 formatter.write_str("a TypeDetails Map")
102 }
103
104 fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
105 where
106 M: MapAccess<'de>,
107 {
108 let mut set = TypeDetails::new();
109
110 while let Some((key, value)) = access.next_entry()? {
111 let p: (String, String) = (key, value);
112 println!("TypeDetail key: {:?} value: {:?}", p.0, p.1);
113 let td = TypeDetail::try_from(p).expect("Expected a valid type detail");
115 set.add(td);
116 }
117
118 Ok(set)
119 }
120}
121
122impl<'de> Deserialize<'de> for TypeDetails {
123 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
124 where
125 D: Deserializer<'de>,
126 {
127 deserializer.deserialize_map(TypeDetailsVisitor)
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 static RAW_TYPE_DETAILS_EMPTY: &str = r#"
136{}
137"#;
138 static RAW_TYPE_DETAILS_WITH_UDH: &str = r#"
139{
140 "udh" : "UserDataHeaderContent:)"
141}
142"#;
143
144 lazy_static! {
145 static ref DETAILS: TypeDetails = {
146 let mut details = TypeDetails::new();
147 details.add(TypeDetail::UserDataHeader("some".to_string()));
148 details
149 };
150 }
151
152 serde_roundtrip!(serde_typedetails_empty, TypeDetails, TypeDetails::new());
153 deser_roundtrip!(deser_typedetails_empty, TypeDetails, RAW_TYPE_DETAILS_EMPTY);
154
155 serde_roundtrip!(serde_typedetails_with_udh, TypeDetails, DETAILS.clone());
156 deser_roundtrip!(
157 deser_typedetails_with_udh,
158 TypeDetails,
159 RAW_TYPE_DETAILS_WITH_UDH
160 );
161
162 serde_roundtrip!(
163 serde_typedetail_udh,
164 TypeDetail,
165 TypeDetail::UserDataHeader("some".to_string())
166 );
167
168}