Skip to main content

dynamodb_facade/values/
impls.rs

1use std::{
2    borrow::Cow,
3    collections::{BTreeSet, HashSet},
4};
5
6use aws_sdk_dynamodb::primitives::Blob;
7
8use super::*;
9
10// -- Identity -----------------------------------------------------------------
11
12impl IntoAttributeValue for AttributeValue {
13    #[inline]
14    fn into_attribute_value(self) -> AttributeValue {
15        self
16    }
17}
18
19// -- Strings ------------------------------------------------------------------
20
21impl IntoAttributeValue for String {
22    #[inline]
23    fn into_attribute_value(self) -> AttributeValue {
24        AttributeValue::S(self)
25    }
26}
27impl IntoStringAttributeValue for String {}
28
29impl IntoAttributeValue for &str {
30    #[inline]
31    fn into_attribute_value(self) -> AttributeValue {
32        AttributeValue::S(self.to_owned())
33    }
34}
35impl IntoStringAttributeValue for &str {}
36
37impl IntoAttributeValue for &String {
38    #[inline]
39    fn into_attribute_value(self) -> AttributeValue {
40        AttributeValue::S(self.to_owned())
41    }
42}
43impl IntoStringAttributeValue for &String {}
44
45impl IntoAttributeValue for Cow<'_, str> {
46    #[inline]
47    fn into_attribute_value(self) -> AttributeValue {
48        AttributeValue::S(self.into_owned())
49    }
50}
51impl IntoStringAttributeValue for Cow<'_, str> {}
52
53// -- Bool ---------------------------------------------------------------------
54
55impl IntoAttributeValue for bool {
56    #[inline]
57    fn into_attribute_value(self) -> AttributeValue {
58        AttributeValue::Bool(self)
59    }
60}
61
62// -- Numerics -----------------------------------------------------------------
63
64/// Implements [`IntoAttributeValue`] (→ `N`) and [`IntoNumberAttributeValue`] for numeric types.
65macro_rules! impl_numeric {
66    ($($t:ty),*) => {
67        $(
68            impl IntoAttributeValue for $t {
69                #[inline]
70                fn into_attribute_value(self) -> AttributeValue {
71                    AttributeValue::N(self.to_string())
72                }
73            }
74            impl IntoNumberAttributeValue for $t {}
75        )*
76    };
77}
78
79impl_numeric!(
80    i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64
81);
82
83impl<T: Into<String>> IntoAttributeValue for AsNumber<T> {
84    #[inline]
85    fn into_attribute_value(self) -> AttributeValue {
86        AttributeValue::N(self.0.into())
87    }
88}
89impl<T: Into<String>> IntoNumberAttributeValue for AsNumber<T> {}
90
91// -- Binary (Vec<u8>) → B ----------------------------------------------------
92
93impl IntoAttributeValue for Vec<u8> {
94    #[inline]
95    fn into_attribute_value(self) -> AttributeValue {
96        AttributeValue::B(Blob::new(self))
97    }
98}
99impl IntoBinaryAttributeValue for Vec<u8> {}
100
101impl IntoAttributeValue for &[u8] {
102    #[inline]
103    fn into_attribute_value(self) -> AttributeValue {
104        AttributeValue::B(Blob::new(self))
105    }
106}
107impl IntoBinaryAttributeValue for &[u8] {}
108
109// -- Vec<T> → L (list) -------------------------------------------------------
110// Explicit impls for each supported inner type to avoid blanket conflicts.
111
112// -- Vec<Vec<u8>> → L(B, B, …) -----------------------------------------------
113
114/// Implements [`IntoAttributeValue`] (→ `L`) for `Vec<T>` by mapping each element.
115macro_rules! impl_vec_list {
116    ($($t:ty),*) => {
117        $(
118            impl IntoAttributeValue for Vec<$t> {
119                #[inline]
120                fn into_attribute_value(self) -> AttributeValue {
121                    AttributeValue::L(
122                        self.into_iter()
123                            .map(IntoAttributeValue::into_attribute_value)
124                            .collect(),
125                    )
126                }
127            }
128        )*
129    };
130}
131
132impl_vec_list!(
133    String,
134    &str,
135    bool,
136    i8,
137    i16,
138    i32,
139    i64,
140    i128,
141    isize,
142    u16,
143    u32,
144    u64,
145    u128,
146    usize,
147    f32,
148    f64,
149    AttributeValue,
150    Vec<u8>
151);
152
153// -- &[T] → L (list) ---------------------------------------------------------
154
155/// Implements [`IntoAttributeValue`] (→ `L`) for `&[T]` by cloning and mapping each element.
156macro_rules! impl_slice_list {
157    ($($t:ty),*) => {
158        $(
159            impl IntoAttributeValue for &[$t] {
160                #[inline]
161                fn into_attribute_value(self) -> AttributeValue {
162                    AttributeValue::L(
163                        self.into_iter()
164                            .cloned()
165                            .map(IntoAttributeValue::into_attribute_value)
166                            .collect(),
167                    )
168                }
169            }
170        )*
171    };
172}
173
174// Numeric & bool slices — each element is cloned/converted via to_string().
175impl_slice_list!(
176    String,
177    &str,
178    bool,
179    i8,
180    i16,
181    i32,
182    i64,
183    i128,
184    isize,
185    u16,
186    u32,
187    u64,
188    u128,
189    usize,
190    f32,
191    f64,
192    Vec<u8>,
193    &[u8]
194);
195
196impl IntoAttributeValue for &[AttributeValue] {
197    #[inline]
198    fn into_attribute_value(self) -> AttributeValue {
199        AttributeValue::L(self.to_vec())
200    }
201}
202
203// -- HashSet<String> → Ss -----------------------------------------------------
204
205impl IntoAttributeValue for HashSet<String> {
206    #[inline]
207    fn into_attribute_value(self) -> AttributeValue {
208        AttributeValue::Ss(self.into_iter().collect())
209    }
210}
211
212impl IntoAttributeValue for HashSet<&str> {
213    #[inline]
214    fn into_attribute_value(self) -> AttributeValue {
215        AttributeValue::Ss(self.into_iter().map(ToOwned::to_owned).collect())
216    }
217}
218
219impl IntoAttributeValue for BTreeSet<String> {
220    #[inline]
221    fn into_attribute_value(self) -> AttributeValue {
222        AttributeValue::Ss(self.into_iter().collect())
223    }
224}
225
226impl IntoAttributeValue for BTreeSet<&str> {
227    #[inline]
228    fn into_attribute_value(self) -> AttributeValue {
229        AttributeValue::Ss(self.into_iter().map(ToOwned::to_owned).collect())
230    }
231}
232
233impl IntoAttributeValue for AsSet<String> {
234    #[inline]
235    fn into_attribute_value(self) -> AttributeValue {
236        AttributeValue::Ss(self.0)
237    }
238}
239
240impl IntoAttributeValue for AsSet<&str> {
241    #[inline]
242    fn into_attribute_value(self) -> AttributeValue {
243        AttributeValue::Ss(self.into_iter().map(ToOwned::to_owned).collect())
244    }
245}
246
247// -- HashSet<number> → Ns -----------------------------------------------------
248
249/// Implements [`IntoAttributeValue`] (→ `Ns`) for set collections of numeric types.
250macro_rules! impl_number_set {
251    ($col:ident, $($t:ty),*) => {
252        $(
253            impl IntoAttributeValue for $col<$t> {
254                #[inline]
255                fn into_attribute_value(self) -> AttributeValue {
256                    AttributeValue::Ns(self.into_iter().map(|v| v.to_string()).collect())
257                }
258            }
259        )*
260    };
261}
262
263impl_number_set!(
264    HashSet, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64
265);
266impl_number_set!(
267    BTreeSet, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64
268);
269impl_number_set!(
270    AsSet, i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64
271);
272
273// -- HashSet<Vec<u8>> → Bs ---------------------------------------------------
274
275impl IntoAttributeValue for HashSet<Vec<u8>> {
276    #[inline]
277    fn into_attribute_value(self) -> AttributeValue {
278        AttributeValue::Bs(self.into_iter().map(Blob::new).collect())
279    }
280}
281
282impl IntoAttributeValue for BTreeSet<Vec<u8>> {
283    #[inline]
284    fn into_attribute_value(self) -> AttributeValue {
285        AttributeValue::Bs(self.into_iter().map(Blob::new).collect())
286    }
287}
288
289impl IntoAttributeValue for AsSet<Vec<u8>> {
290    #[inline]
291    fn into_attribute_value(self) -> AttributeValue {
292        AttributeValue::Bs(self.into_iter().map(Blob::new).collect())
293    }
294}