debil_dynamodb/
attribute.rs1use 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}