bencodex/codec/
types.rs

1use num_bigint::BigInt;
2use std::{collections::BTreeMap, fmt::Debug};
3
4/// The type alias of `BTreepMap<BencodexKey, BencodexValue>` to reduce code size.
5///
6/// ```
7/// use bencodex::{ Encode, BencodexDictionary };
8///
9/// let mut dict = BencodexDictionary::new();
10/// dict.insert("foo".into(), "bar".into());
11///
12/// let mut buf = vec![];
13/// dict.encode(&mut buf);
14/// assert_eq!(buf, b"du3:foou3:bare")
15/// ```
16pub type BencodexDictionary = BTreeMap<BencodexKey, BencodexValue>;
17/// The type alias of `Vec<BencodexValue>` to reduce code size.
18///
19/// ```
20/// use bencodex::{ Encode, BencodexList };
21///
22/// let mut list = BencodexList::new();
23/// list.push("foo".to_string().into());
24/// list.push("bar".to_string().into());
25///
26/// let mut buf = vec![];
27/// list.encode(&mut buf);
28/// assert_eq!(buf, b"lu3:foou3:bare")
29/// ```
30pub type BencodexList = Vec<BencodexValue>;
31
32/// The constant of `BencodexValue::Null`.
33///
34/// ```
35/// use bencodex::{ Encode, BENCODEX_NULL };
36///
37/// let mut buf = vec![];
38/// BENCODEX_NULL.encode(&mut buf);
39/// assert_eq!(buf, b"n")
40/// ```
41pub const BENCODEX_NULL: BencodexValue = BencodexValue::Null;
42
43#[derive(PartialEq, Debug, Clone)]
44pub enum BencodexValue {
45    Binary(Vec<u8>),
46    Text(String),
47    Boolean(bool),
48    Number(BigInt),
49    List(BencodexList),
50    Dictionary(BencodexDictionary),
51    Null,
52}
53
54#[derive(PartialEq, Eq, Debug, PartialOrd, Clone, Ord)]
55pub enum BencodexKey {
56    Binary(Vec<u8>),
57    Text(String),
58}
59
60impl From<&str> for BencodexKey {
61    fn from(val: &str) -> Self {
62        BencodexKey::Text(val.to_string())
63    }
64}
65
66impl From<String> for BencodexKey {
67    fn from(val: String) -> Self {
68        BencodexKey::Text(val)
69    }
70}
71
72impl From<&String> for BencodexKey {
73    fn from(val: &String) -> Self {
74        BencodexKey::Text(val.clone())
75    }
76}
77
78impl From<Vec<u8>> for BencodexKey {
79    fn from(val: Vec<u8>) -> Self {
80        BencodexKey::Binary(val)
81    }
82}
83
84impl From<&Vec<u8>> for BencodexKey {
85    fn from(val: &Vec<u8>) -> Self {
86        BencodexKey::Binary(val.clone())
87    }
88}
89
90impl From<&[u8]> for BencodexKey {
91    fn from(val: &[u8]) -> Self {
92        BencodexKey::Binary(val.to_vec())
93    }
94}
95
96impl From<&[u8]> for BencodexValue {
97    fn from(val: &[u8]) -> Self {
98        BencodexValue::Binary(val.to_vec())
99    }
100}
101
102impl From<Vec<u8>> for BencodexValue {
103    fn from(val: Vec<u8>) -> Self {
104        BencodexValue::Binary(val)
105    }
106}
107
108impl From<&str> for BencodexValue {
109    fn from(val: &str) -> Self {
110        BencodexValue::Text(val.to_string())
111    }
112}
113
114impl From<String> for BencodexValue {
115    fn from(val: String) -> Self {
116        BencodexValue::Text(val)
117    }
118}
119
120macro_rules! bencodex_value_number_impl {
121    ($x:tt) => {
122        impl From<$x> for BencodexValue {
123            fn from(val: $x) -> Self {
124                BencodexValue::Number(val.into())
125            }
126        }
127    };
128}
129
130bencodex_value_number_impl!(u16);
131bencodex_value_number_impl!(u32);
132bencodex_value_number_impl!(u64);
133bencodex_value_number_impl!(i8);
134bencodex_value_number_impl!(i16);
135bencodex_value_number_impl!(i32);
136bencodex_value_number_impl!(i64);
137
138impl From<bool> for BencodexValue {
139    fn from(val: bool) -> Self {
140        BencodexValue::Boolean(val)
141    }
142}
143
144impl<T> From<Vec<T>> for BencodexValue
145where
146    T: Into<BencodexValue>,
147{
148    fn from(val: Vec<T>) -> Self {
149        let mut vec = Vec::new();
150        for v in val {
151            vec.push(v.into());
152        }
153
154        BencodexValue::List(vec)
155    }
156}
157
158impl<T, U> From<BTreeMap<T, U>> for BencodexValue
159where
160    T: Into<BencodexKey>,
161    U: Into<BencodexValue>,
162{
163    fn from(val: BTreeMap<T, U>) -> Self {
164        let mut map = BTreeMap::<BencodexKey, BencodexValue>::new();
165        for (key, value) in val {
166            map.insert(key.into(), value.into());
167        }
168
169        BencodexValue::Dictionary(map)
170    }
171}
172
173#[cfg(test)]
174mod tests {
175    mod into {
176        use std::array::IntoIter;
177        use std::{collections::BTreeMap, iter::FromIterator};
178
179        use super::super::{BencodexKey, BencodexValue};
180
181        #[test]
182        fn text() {
183            let s: &str = "value";
184            let value: BencodexKey = s.into();
185            assert_eq!(value, BencodexKey::Text("value".to_string()));
186
187            let s: String = "value".to_string();
188            let value: BencodexKey = s.into();
189            assert_eq!(value, BencodexKey::Text("value".to_string()));
190
191            let s: &str = "value";
192            let value: BencodexValue = s.into();
193            assert_eq!(value, BencodexValue::Text("value".to_string()));
194
195            let s: String = "value".to_string();
196            let value: BencodexValue = s.into();
197            assert_eq!(value, BencodexValue::Text("value".to_string()));
198        }
199
200        #[test]
201        fn binary() {
202            let b: &[u8] = &[0, 1, 2, 3];
203            let value: BencodexKey = b.into();
204            assert_eq!(value, BencodexKey::Binary(vec![0, 1, 2, 3]));
205
206            let b: Vec<u8> = vec![0, 1, 2, 3];
207            let value: BencodexKey = b.into();
208            assert_eq!(value, BencodexKey::Binary(vec![0, 1, 2, 3]));
209
210            let b: &[u8] = &[0, 1, 2, 3];
211            let value: BencodexValue = b.into();
212            assert_eq!(value, BencodexValue::Binary(vec![0, 1, 2, 3]));
213
214            let b: Vec<u8> = vec![0, 1, 2, 3];
215            let value: BencodexValue = b.into();
216            assert_eq!(value, BencodexValue::Binary(vec![0, 1, 2, 3]));
217        }
218
219        #[test]
220        fn number() {
221            let n: u16 = 0;
222            let value: BencodexValue = n.into();
223            assert_eq!(value, BencodexValue::Number(0.into()));
224
225            let n: u32 = 0;
226            let value: BencodexValue = n.into();
227            assert_eq!(value, BencodexValue::Number(0.into()));
228
229            let n: u64 = 0;
230            let value: BencodexValue = n.into();
231            assert_eq!(value, BencodexValue::Number(0.into()));
232
233            let n: i8 = 0;
234            let value: BencodexValue = n.into();
235            assert_eq!(value, BencodexValue::Number(0.into()));
236
237            let n: i16 = 0;
238            let value: BencodexValue = n.into();
239            assert_eq!(value, BencodexValue::Number(0.into()));
240
241            let n: i32 = 0;
242            let value: BencodexValue = n.into();
243            assert_eq!(value, BencodexValue::Number(0.into()));
244
245            let n: i64 = 0;
246            let value: BencodexValue = n.into();
247            assert_eq!(value, BencodexValue::Number(0.into()));
248        }
249
250        #[test]
251        fn boolean() {
252            let value: BencodexValue = true.into();
253            assert_eq!(value, BencodexValue::Boolean(true));
254
255            let value: BencodexValue = false.into();
256            assert_eq!(value, BencodexValue::Boolean(false));
257        }
258
259        #[test]
260        fn null() {
261            let value: BencodexValue = BencodexValue::Null;
262            assert_eq!(value, BencodexValue::Null);
263        }
264
265        #[test]
266        fn list() {
267            let l = vec!["A", "B", "C", "D"];
268            let value: BencodexValue = l.into();
269            assert_eq!(
270                value,
271                BencodexValue::List(vec!["A".into(), "B".into(), "C".into(), "D".into()])
272            );
273
274            let l = vec![0, 1, 2, 3];
275            let value: BencodexValue = l.into();
276            assert_eq!(
277                value,
278                BencodexValue::List(vec![0.into(), 1.into(), 2.into(), 3.into()])
279            );
280
281            let l = vec![
282                BencodexValue::Null,
283                BencodexValue::Null,
284                BencodexValue::Null,
285            ];
286            let value: BencodexValue = l.into();
287            assert_eq!(
288                value,
289                BencodexValue::List(vec![
290                    BencodexValue::Null,
291                    BencodexValue::Null,
292                    BencodexValue::Null
293                ])
294            );
295
296            let l: Vec<Vec<u8>> = vec![vec![0, 1, 2, 3], vec![4, 5, 6, 7]];
297            let value: BencodexValue = l.into();
298            assert_eq!(
299                value,
300                BencodexValue::List(vec![vec![0u8, 1, 2, 3].into(), vec![4u8, 5, 6, 7].into(),])
301            );
302        }
303
304        #[test]
305        fn dictionary() {
306            let mut map = BTreeMap::<String, &[u8]>::new();
307            map.insert("foo".to_string(), b"bar");
308            let actual: BencodexValue = map.into();
309
310            let expected = BencodexValue::Dictionary(BTreeMap::from_iter(IntoIter::new([(
311                BencodexKey::Text("foo".to_string()),
312                BencodexValue::Binary(vec![b'b', b'a', b'r']),
313            )])));
314
315            assert_eq!(actual, expected);
316        }
317    }
318}