debil_dynamodb/
attribute.rs

1use bytes::Bytes;
2use rusoto_dynamodb::AttributeValue;
3use std::collections::HashMap;
4use std::error::Error;
5
6#[derive(Debug)]
7pub enum AttributeError {
8    MissingField(String),
9    InvalidFormat(Box<dyn Error>),
10}
11
12pub trait Attribute: Sized {
13    fn into_attr(self) -> AttributeValue;
14    fn from_attr(attr: AttributeValue) -> Result<Self, AttributeError>;
15}
16
17impl Attribute for Bytes {
18    fn into_attr(self) -> AttributeValue {
19        AttributeValue {
20            b: Some(self),
21            ..Default::default()
22        }
23    }
24
25    fn from_attr(attr: AttributeValue) -> Result<Self, AttributeError> {
26        attr.b.ok_or(AttributeError::MissingField("B".to_string()))
27    }
28}
29
30impl Attribute for bool {
31    fn into_attr(self) -> AttributeValue {
32        AttributeValue {
33            bool: Some(self),
34            ..Default::default()
35        }
36    }
37
38    fn from_attr(attr: AttributeValue) -> Result<Self, AttributeError> {
39        attr.bool
40            .ok_or(AttributeError::MissingField("BOOL".to_string()))
41    }
42}
43
44pub struct BSVec(pub Vec<Bytes>);
45
46impl Attribute for BSVec {
47    fn into_attr(self) -> AttributeValue {
48        AttributeValue {
49            bs: Some(self.0),
50            ..Default::default()
51        }
52    }
53
54    fn from_attr(attr: AttributeValue) -> Result<Self, AttributeError> {
55        let items = attr
56            .bs
57            .ok_or(AttributeError::MissingField("BS".to_string()))?;
58        Ok(BSVec(items))
59    }
60}
61
62impl<T: Attribute> Attribute for Vec<T> {
63    fn into_attr(self) -> AttributeValue {
64        AttributeValue {
65            l: Some(self.into_iter().map(|a| a.into_attr()).collect::<Vec<_>>()),
66            ..Default::default()
67        }
68    }
69
70    fn from_attr(attr: AttributeValue) -> Result<Self, AttributeError> {
71        let vec = attr
72            .l
73            .ok_or(AttributeError::MissingField("L".to_string()))?;
74
75        vec.into_iter()
76            .map(|v| Attribute::from_attr(v))
77            .collect::<Result<_, _>>()
78    }
79}
80
81impl<T: Attribute> Attribute for HashMap<String, T> {
82    fn into_attr(self) -> AttributeValue {
83        AttributeValue {
84            m: Some(self.into_iter().map(|(k, v)| (k, v.into_attr())).collect()),
85            ..Default::default()
86        }
87    }
88
89    fn from_attr(attr: AttributeValue) -> Result<Self, AttributeError> {
90        let hm = attr
91            .m
92            .ok_or(AttributeError::MissingField("M".to_string()))?;
93
94        hm.into_iter()
95            .map(|(k, v)| {
96                let w = Attribute::from_attr(v)?;
97
98                Ok((k, w))
99            })
100            .collect::<Result<_, _>>()
101    }
102}
103
104macro_rules! derive_number_for {
105    ($t: tt) => {
106        impl Attribute for $t {
107            fn into_attr(self) -> AttributeValue {
108                AttributeValue {
109                    n: Some(self.to_string()),
110                    ..Default::default()
111                }
112            }
113
114            fn from_attr(attr: AttributeValue) -> Result<Self, AttributeError> {
115                let rep = attr
116                    .n
117                    .ok_or(AttributeError::MissingField("N".to_string()))?;
118                rep.parse()
119                    .map_err(|err| AttributeError::InvalidFormat(Box::new(err)))
120            }
121        }
122    };
123}
124
125derive_number_for!(i32);
126derive_number_for!(u32);
127derive_number_for!(i64);
128derive_number_for!(u64);
129derive_number_for!(f32);
130derive_number_for!(f64);
131
132pub struct NSVec<T>(pub Vec<T>);
133
134impl<T: Attribute + ToString> Attribute for NSVec<T> {
135    fn into_attr(self) -> AttributeValue {
136        AttributeValue {
137            ns: Some(self.0.into_iter().map(|t| t.to_string()).collect()),
138            ..Default::default()
139        }
140    }
141
142    fn from_attr(attr: AttributeValue) -> Result<Self, AttributeError> {
143        let vec = attr
144            .ns
145            .ok_or(AttributeError::MissingField("NS".to_string()))?;
146
147        vec.into_iter()
148            .map(|rep| {
149                Attribute::from_attr(AttributeValue {
150                    n: Some(rep),
151                    ..Default::default()
152                })
153            })
154            .collect::<Result<_, _>>()
155            .map(|v| NSVec(v))
156    }
157}
158
159impl<T: Attribute> Attribute for Option<T> {
160    fn into_attr(self) -> AttributeValue {
161        match self {
162            Some(t) => t.into_attr(),
163            None => AttributeValue {
164                null: Some(true),
165                ..Default::default()
166            },
167        }
168    }
169
170    fn from_attr(attr: AttributeValue) -> Result<Self, AttributeError> {
171        if attr.null.is_some() {
172            return Ok(None);
173        }
174
175        Attribute::from_attr(attr).map(|v| Some(v))
176    }
177}
178
179impl Attribute for String {
180    fn into_attr(self) -> AttributeValue {
181        AttributeValue {
182            s: Some(self),
183            ..Default::default()
184        }
185    }
186
187    fn from_attr(attr: AttributeValue) -> Result<Self, AttributeError> {
188        attr.s.ok_or(AttributeError::MissingField("S".to_string()))
189    }
190}
191
192pub struct SSVec(pub Vec<String>);
193
194impl Attribute for SSVec {
195    fn into_attr(self) -> AttributeValue {
196        AttributeValue {
197            ss: Some(self.0),
198            ..Default::default()
199        }
200    }
201
202    fn from_attr(attr: AttributeValue) -> Result<Self, AttributeError> {
203        attr.ss
204            .ok_or(AttributeError::MissingField("SS".to_string()))
205            .map(|v| SSVec(v))
206    }
207}