1use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
3
4use impl_trait_for_tuples::impl_for_tuples;
5
6use crate::{SimpleValue, Value};
7
8pub trait Encode {
10 fn is_empty(&self) -> bool {
12 false
13 }
14
15 fn into_cbor_value(self) -> Value;
17}
18
19pub trait EncodeAsMap: Encode {
21 fn into_cbor_value_map(self) -> Value
23 where
24 Self: Sized,
25 {
26 self.into_cbor_value()
27 }
28
29 fn into_cbor_map(self) -> Vec<(Value, Value)>
31 where
32 Self: Sized,
33 {
34 match self.into_cbor_value() {
35 Value::Map(items) => items,
36 _ => vec![],
37 }
38 }
39}
40
41#[impl_for_tuples(1, 10)]
42impl Encode for Tuple {
43 fn is_empty(&self) -> bool {
44 for_tuples!( #( Tuple.is_empty() )&* );
45 }
46
47 #[allow(clippy::vec_init_then_push)]
48 fn into_cbor_value(self) -> Value {
49 let mut values = vec![];
50 for_tuples!( #( values.push(Tuple.into_cbor_value()); )* );
51 Value::Array(values)
52 }
53}
54
55macro_rules! impl_uint {
56 ($name:ty) => {
57 impl Encode for $name {
58 fn is_empty(&self) -> bool {
59 *self == 0
60 }
61
62 fn into_cbor_value(self) -> Value {
63 Value::Unsigned(self as u64)
64 }
65 }
66
67 impl Encode for &$name {
68 fn is_empty(&self) -> bool {
69 **self == 0
70 }
71
72 fn into_cbor_value(self) -> Value {
73 Encode::into_cbor_value(*self)
74 }
75 }
76 };
77}
78
79macro_rules! impl_int {
80 ($name:ty) => {
81 impl Encode for $name {
82 fn is_empty(&self) -> bool {
83 *self == 0
84 }
85
86 fn into_cbor_value(self) -> Value {
87 Value::integer(self as i64)
88 }
89 }
90
91 impl Encode for &$name {
92 fn is_empty(&self) -> bool {
93 **self == 0
94 }
95
96 fn into_cbor_value(self) -> Value {
97 Encode::into_cbor_value(*self)
98 }
99 }
100 };
101}
102
103impl_uint!(u8);
104impl_uint!(u16);
105impl_uint!(u32);
106impl_uint!(u64);
107impl_int!(i8);
108impl_int!(i16);
109impl_int!(i32);
110impl_int!(i64);
111
112impl Encode for u128 {
113 fn is_empty(&self) -> bool {
114 *self == 0
115 }
116
117 fn into_cbor_value(self) -> Value {
118 Value::ByteString(self.to_be_bytes()[self.leading_zeros() as usize / 8..].to_vec())
119 }
120}
121
122impl Encode for &u128 {
123 fn is_empty(&self) -> bool {
124 **self == 0
125 }
126
127 fn into_cbor_value(self) -> Value {
128 Encode::into_cbor_value(*self)
129 }
130}
131
132impl Encode for bool {
133 fn is_empty(&self) -> bool {
134 !*self
135 }
136
137 fn into_cbor_value(self) -> Value {
138 if self {
139 Value::Simple(SimpleValue::TrueValue)
140 } else {
141 Value::Simple(SimpleValue::FalseValue)
142 }
143 }
144}
145
146impl Encode for String {
147 fn is_empty(&self) -> bool {
148 String::is_empty(self)
149 }
150
151 fn into_cbor_value(self) -> Value {
152 Value::TextString(self)
153 }
154}
155
156impl Encode for &str {
157 fn is_empty(&self) -> bool {
158 str::is_empty(self)
159 }
160
161 fn into_cbor_value(self) -> Value {
162 Value::TextString(self.to_string())
163 }
164}
165
166impl Encode for char {
167 fn into_cbor_value(self) -> Value {
168 Value::Unsigned(self as u64)
169 }
170 fn is_empty(&self) -> bool {
171 *self == '\x00'
172 }
173}
174
175impl<T: Encode> Encode for Vec<T> {
176 default fn is_empty(&self) -> bool {
177 Vec::is_empty(self)
178 }
179
180 default fn into_cbor_value(self) -> Value {
181 Value::Array(self.into_iter().map(Encode::into_cbor_value).collect())
182 }
183}
184
185impl Encode for Vec<u8> {
186 fn into_cbor_value(self) -> Value {
187 Value::ByteString(self)
188 }
189}
190
191impl<T: Encode, const N: usize> Encode for [T; N] {
192 default fn into_cbor_value(self) -> Value {
193 Value::Array(
194 IntoIterator::into_iter(self)
195 .map(Encode::into_cbor_value)
196 .collect(),
197 )
198 }
199}
200
201impl<const N: usize> Encode for [u8; N] {
202 fn into_cbor_value(self) -> Value {
203 Value::ByteString(self.into())
204 }
205}
206
207impl<T: Encode> Encode for Option<T> {
208 fn is_empty(&self) -> bool {
209 self.is_none()
210 }
211
212 fn into_cbor_value(self) -> Value {
213 match self {
214 Some(v) => Encode::into_cbor_value(v),
215 None => Value::Simple(SimpleValue::NullValue),
216 }
217 }
218}
219
220impl Encode for Value {
221 fn is_empty(&self) -> bool {
222 matches!(
223 self,
224 Value::Simple(SimpleValue::NullValue | SimpleValue::Undefined)
225 )
226 }
227
228 fn into_cbor_value(self) -> Value {
229 self
230 }
231}
232
233impl<K: Encode, V: Encode> Encode for BTreeMap<K, V> {
234 fn is_empty(&self) -> bool {
235 BTreeMap::is_empty(self)
236 }
237
238 fn into_cbor_value(self) -> Value {
239 Value::Map(
240 self.into_iter()
241 .map(|(k, v)| (k.into_cbor_value(), v.into_cbor_value()))
242 .collect(),
243 )
244 }
245}
246
247impl<K: Encode, V: Encode> EncodeAsMap for BTreeMap<K, V> {}
248
249impl<V: Encode> Encode for BTreeSet<V> {
250 fn is_empty(&self) -> bool {
251 BTreeSet::is_empty(self)
252 }
253
254 fn into_cbor_value(self) -> Value {
255 Value::Array(self.into_iter().map(Encode::into_cbor_value).collect())
256 }
257}
258
259impl<K: Encode, V: Encode> Encode for HashMap<K, V> {
260 fn is_empty(&self) -> bool {
261 HashMap::is_empty(self)
262 }
263
264 fn into_cbor_value(self) -> Value {
265 Value::Map(
266 self.into_iter()
267 .map(|(k, v)| (k.into_cbor_value(), v.into_cbor_value()))
268 .collect(),
269 )
270 }
271}
272
273impl<K: Encode, V: Encode> EncodeAsMap for HashMap<K, V> {}
274
275impl<V: Encode> Encode for HashSet<V> {
276 fn is_empty(&self) -> bool {
277 HashSet::is_empty(self)
278 }
279
280 fn into_cbor_value(self) -> Value {
281 Value::Array(self.into_iter().map(Encode::into_cbor_value).collect())
282 }
283}
284
285impl Encode for () {
286 fn is_empty(&self) -> bool {
287 true
288 }
289
290 fn into_cbor_value(self) -> Value {
291 Value::Simple(SimpleValue::NullValue)
292 }
293}