1use std::borrow::Cow;
2use std::collections::HashMap;
3use std::marker::PhantomData;
4
5use serde::{Deserialize, Deserializer, Serialize};
6
7#[derive(Debug, Deserialize, PartialEq, Eq, Hash)]
8pub struct Bytes<'a>(Cow<'a, [u8]>);
9
10impl<'a> Serialize for Bytes<'a> {
11 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
12 where
13 S: serde::Serializer,
14 {
15 serializer.serialize_bytes(&self.0)
16 }
17}
18
19#[derive(Debug, Serialize, PartialEq, Eq)]
20#[serde(untagged)]
21pub enum BencodeValue<'a> {
22 Int(i64),
23 Bytes(Bytes<'a>),
24 List(Vec<BencodeValue<'a>>),
25 Dict(HashMap<Bytes<'a>, BencodeValue<'a>>),
26}
27
28impl<'a, 'de: 'a> serde::de::Deserialize<'de> for BencodeValue<'a> {
29 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30 where
31 D: Deserializer<'de>,
32 {
33 struct Visitor<'a> {
34 lifetime: PhantomData<BencodeValue<'a>>,
35 }
36
37 impl<'a, 'de: 'a> serde::de::Visitor<'de> for Visitor<'a> {
38 type Value = BencodeValue<'a>;
39
40 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
41 write!(formatter, "a valid bencode value")
42 }
43
44 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
45 where
46 E: serde::de::Error,
47 {
48 Ok(v.into())
49 }
50
51 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
52 where
53 A: serde::de::SeqAccess<'de>,
54 {
55 let mut v: Vec<BencodeValue<'a>> = Vec::new();
56 while let Some(value) = seq.next_element()? {
57 v.push(value);
58 }
59 Ok(v.into())
60 }
61
62 fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
63 where
64 E: serde::de::Error,
65 {
66 Ok(v.into())
67 }
68
69 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
70 where
71 A: serde::de::MapAccess<'de>,
72 {
73 let mut hashmap = HashMap::new();
74 while let Some(key) = map.next_key::<&'de [u8]>()? {
75 let value = map.next_value()?;
76 hashmap.insert(Bytes(Cow::Borrowed(key)), value);
77 }
78 Ok(hashmap.into())
79 }
80 }
81
82 deserializer.deserialize_any(Visitor { lifetime: PhantomData })
83 }
84}
85
86impl From<i64> for BencodeValue<'_> {
87 fn from(value: i64) -> Self {
88 BencodeValue::Int(value)
89 }
90}
91
92impl<'a> From<&'a [u8]> for BencodeValue<'a> {
93 fn from(value: &'a [u8]) -> Self {
94 BencodeValue::Bytes(Bytes(Cow::Borrowed(value)))
95 }
96}
97
98impl From<String> for BencodeValue<'_> {
99 fn from(s: String) -> Self {
100 BencodeValue::Bytes(Bytes(Cow::Owned(s.into_bytes())))
101 }
102}
103
104impl<'a> From<&'a str> for BencodeValue<'a> {
105 fn from(v: &'a str) -> Self {
106 BencodeValue::Bytes(Bytes(Cow::Borrowed(v.as_bytes())))
107 }
108}
109
110impl From<Vec<u8>> for BencodeValue<'_> {
111 fn from(value: Vec<u8>) -> Self {
112 BencodeValue::Bytes(Bytes(Cow::Owned(value)))
113 }
114}
115
116impl<'a> From<Vec<BencodeValue<'a>>> for BencodeValue<'a> {
117 fn from(value: Vec<BencodeValue<'a>>) -> Self {
118 BencodeValue::List(value)
119 }
120}
121
122impl<'a> From<HashMap<Bytes<'a>, BencodeValue<'a>>> for BencodeValue<'a> {
123 fn from(value: HashMap<Bytes<'a>, BencodeValue<'a>>) -> Self {
124 BencodeValue::Dict(value)
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131 use crate::{from_str, to_string};
132
133 mod basic_types {
134 use super::*;
135
136 #[test]
137 fn can_roundtrip_int() {
138 let value: BencodeValue = 888i64.into();
139 let serialized = to_string(&value).expect("failed to serialize an integer");
140 assert_eq!(serialized, "i888e");
141 let deserialized = from_str::<BencodeValue>(&serialized).expect("failed to deserialize an integer");
142 assert_eq!(deserialized, value)
143 }
144
145 #[test]
146 fn can_roundtrip_negative_int() {
147 let value: BencodeValue = (-888i64).into();
148 let serialized = to_string(&value).expect("failed to serialize a neg integer");
149 assert_eq!(serialized, "i-888e");
150 let deserialized = from_str::<BencodeValue>(&serialized).expect("failed to deserialize a neg integer");
151 assert_eq!(deserialized, value)
152 }
153
154 #[test]
155 fn can_roundtrip_bytes() {
156 let value: BencodeValue = "a nice value".into();
157 let serialized = to_string(&value).expect("failed to serialize a string");
158 assert_eq!(serialized, "12:a nice value");
159 let deserialized = from_str::<BencodeValue>(&serialized).expect("failed to deserialize a string");
160 assert_eq!(deserialized, value)
161 }
162
163 #[test]
164 fn can_roundtrip_list_of_bytes() {
165 let list: Vec<BencodeValue> = vec!["a nice value".into(), "another".into()];
166 let value: BencodeValue = list.into();
167 let serialized = to_string(&value).expect("failed to serialize a list of bytes");
168 assert_eq!(serialized, "l12:a nice value7:anothere");
169 let deserialized = from_str::<BencodeValue>(&serialized).expect("failed to deserialize a list of bytes");
170 assert_eq!(deserialized, value)
171 }
172
173 #[test]
174 fn can_roundtrip_list_of_ints() {
175 let list: Vec<BencodeValue> = vec![10i64.into(), 11i64.into()];
176 let value: BencodeValue = list.into();
177 let serialized = to_string(&value).expect("failed to serialize a list of ints");
178 assert_eq!(serialized, "li10ei11ee");
179 let deserialized = from_str::<BencodeValue>(&serialized).expect("failed to deserialize a list of ints");
180 assert_eq!(deserialized, value)
181 }
182
183 #[test]
184 fn can_roundtrip_list_of_lists() {
185 let list: Vec<BencodeValue> = vec![
186 BencodeValue::List(vec!["bytes".into()]),
187 BencodeValue::List(vec![20i64.into()]),
188 ];
189 let value: BencodeValue = list.into();
190 let serialized = to_string(&value).expect("failed to serialize a list of lists");
191 assert_eq!(serialized, "ll5:byteseli20eee");
192 let deserialized = from_str::<BencodeValue>(&serialized).expect("failed to deserialize a list of lists");
193 assert_eq!(deserialized, value)
194 }
195
196 #[test]
197 fn can_roundtrip_list_of_dicts() {
198 let dict_1 = HashMap::from([(Bytes(b"test".into()), BencodeValue::List(vec![21i64.into()]))]);
199 let dict_2 = HashMap::from([(Bytes(b"another".into()), BencodeValue::Dict(HashMap::new()))]);
200
201 let list: Vec<BencodeValue> = vec![dict_1.into(), dict_2.into()];
202 let value: BencodeValue = list.into();
203 let serialized = to_string(&value).expect("failed to serialize a list of dicts");
204 assert_eq!(serialized, "ld4:testli21eeed7:anotherdeee");
205 let deserialized = from_str::<BencodeValue>(&serialized).expect("failed to deserialize a list of dicts");
206 assert_eq!(deserialized, value)
207 }
208
209 #[test]
210 fn can_roundtrip_dict_of_ints() {
211 let dict: HashMap<Bytes, BencodeValue> = HashMap::from([(Bytes(b"key1".into()), 4i64.into())]);
212 let value: BencodeValue = dict.into();
213 let serialized = to_string(&value).expect("failed to serialize a dict of ints");
214 assert_eq!(serialized, "d4:key1i4ee");
215 let deserialized = from_str::<BencodeValue>(&serialized).expect("failed to deserialize a dict of ints");
216 assert_eq!(deserialized, value)
217 }
218
219 #[test]
220 fn can_roundtrip_dict_of_bytes() {
221 let dict: HashMap<Bytes, BencodeValue> = HashMap::from([(Bytes(b"key1".into()), "my value".into())]);
222 let value: BencodeValue = dict.into();
223 let serialized = to_string(&value).expect("failed to serialize a dict of bytes");
224 assert_eq!(serialized, "d4:key18:my valuee");
225 let deserialized = from_str::<BencodeValue>(&serialized).expect("failed to deserialize a dict of bytes");
226 assert_eq!(deserialized, value)
227 }
228
229 #[test]
230 fn can_roundtrip_dict_of_lists() {
231 let dict: HashMap<Bytes, BencodeValue> =
232 HashMap::from([(Bytes(b"key1".into()), vec![BencodeValue::Dict(HashMap::new())].into())]);
233 let value: BencodeValue = dict.into();
234 let serialized = to_string(&value).expect("failed to serialize a dict of lists");
235 assert_eq!(serialized, "d4:key1ldeee");
236 let deserialized = from_str::<BencodeValue>(&serialized).expect("failed to deserialize a dict of lists");
237 assert_eq!(deserialized, value)
238 }
239
240 #[test]
241 fn can_roundtrip_dict_of_dicts() {
242 let dict: HashMap<Bytes, BencodeValue> = HashMap::from([(
243 Bytes(b"key1".into()),
244 HashMap::from([(Bytes(b"inner".into()), BencodeValue::Dict(HashMap::new()))]).into(),
245 )]);
246 let value: BencodeValue = dict.into();
247 let serialized = to_string(&value).expect("failed to serialize a dict of dicts");
248 assert_eq!(serialized, "d4:key1d5:innerdeee");
249 let deserialized = from_str::<BencodeValue>(&serialized).expect("failed to deserialize a dict of dicts");
250 assert_eq!(deserialized, value)
251 }
252 }
253
254 mod option {
255 use super::*;
256
257 #[test]
258 fn can_roundtrip_some() {
259 let value: Option<i64> = Some(10);
260 let serialized = to_string(&value).expect("failed to serialize an Option::Some");
261 assert_eq!(serialized, "i10e");
262 let deserialized = from_str::<Option<i64>>(&serialized).expect("failed to deserialize an Option::Some");
263 assert_eq!(deserialized, value)
264 }
265
266 #[test]
267 fn can_roundtrip_none() {
268 let value: Option<i64> = None;
269 let serialized = to_string(&value).expect("failed to serialize an Option::None");
270 assert_eq!(serialized, "0:");
271 let deserialized = from_str::<Option<i64>>(&serialized).expect("failed to deserialize an Option::None");
272 assert_eq!(deserialized, value)
273 }
274 }
275
276 mod unit {
277 use super::*;
278
279 #[test]
280 fn can_roundtrip_unit() {
281 let value = ();
282 let serialized = to_string(&value).expect("failed to serialize the unit type");
283 assert_eq!(serialized, "0:");
284 let deserialized = from_str::<()>(&serialized).expect("failed to deserialize the unit type");
285 assert_eq!(deserialized, value)
286 }
287 }
288
289 mod _struct {
290 use super::*;
291
292 #[test]
293 fn can_roundtrip_unit_struct() {
294 #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
295 struct Test;
296
297 let value = Test;
298 let serialized = to_string(&value).expect("failed to serialize a unit struct");
299 assert_eq!(serialized, "0:");
300 let deserialized = from_str::<Test>(&serialized).expect("failed to deserialize a unit struct");
301 assert_eq!(deserialized, value)
302 }
303
304 #[test]
305 fn can_roundtrip_newtype_struct() {
306 #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
307 struct Test(i64);
308
309 let value = Test(11);
310 let serialized = to_string(&value).expect("failed to serialize a newtype struct");
311 assert_eq!(serialized, "i11e");
312 let deserialized = from_str::<Test>(&serialized).expect("failed to deserialize a newtype struct");
313 assert_eq!(deserialized, value)
314 }
315
316 #[test]
317 fn can_roundtrip_tuple_struct() {
318 #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
319 struct Test<'a>(i64, i64, &'a str);
320
321 let value = Test(10, 11, "hey!");
322 let serialized = to_string(&value).expect("failed to serialize a tuple struct");
323 assert_eq!(serialized, "li10ei11e4:hey!e");
324 let deserialized = from_str::<Test>(&serialized).expect("failed to deserialize a tuple struct");
325 assert_eq!(deserialized, value)
326 }
327
328 #[test]
329 fn can_roundtrip_struct() {
330 #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
331 struct Test<'a> {
332 field_1: &'a str,
333 field_2: i64,
334 }
335
336 let value = Test {
337 field_1: "test",
338 field_2: 555,
339 };
340 let serialized = to_string(&value).expect("failed to serialize a struct");
341 assert_eq!(serialized, "d7:field_14:test7:field_2i555ee");
342 let deserialized = from_str::<Test>(&serialized).expect("failed to deserialize a struct");
343 assert_eq!(deserialized, value)
344 }
345 }
346
347 mod _enum {
348 use super::*;
349
350 #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
351 enum Enumeration<'a> {
352 Unit,
353 NewType(i64),
354 Tuple(i64, i64, &'a str),
355 Struct { field: &'a str, integer: i64 },
356 }
357
358 #[test]
359 fn can_roundtrip_unit_variant() {
360 let value = Enumeration::Unit;
361 let serialized = to_string(&value).expect("failed to serialize a unit variant");
362 assert_eq!(serialized, "d4:Unit0:e");
363 let deserialized = from_str::<Enumeration>(&serialized).expect("failed to deserialize a unit variant");
364 assert_eq!(deserialized, value)
365 }
366
367 #[test]
368 fn can_roundtrip_newtype_variant() {
369 let value = Enumeration::NewType(15);
370 let serialized = to_string(&value).expect("failed to serialize a newtype variant");
371 assert_eq!(serialized, "d7:NewTypei15ee");
372 let deserialized = from_str::<Enumeration>(&serialized).expect("failed to deserialize a newtype variant");
373 assert_eq!(deserialized, value)
374 }
375
376 #[test]
377 fn can_roundtrip_tuple_variant() {
378 let value = Enumeration::Tuple(10, 12, "hi from enum");
379 let serialized = to_string(&value).expect("failed to serialize a tuple variant");
380 assert_eq!(serialized, "d5:Tupleli10ei12e12:hi from enumee");
381 let deserialized = from_str::<Enumeration>(&serialized).expect("failed to deserialize a tuple variant");
382 assert_eq!(deserialized, value)
383 }
384
385 #[test]
386 fn can_roundtrip_struct_variant() {
387 let value = Enumeration::Struct {
388 field: "hi from enum",
389 integer: 22,
390 };
391 let serialized = to_string(&value).expect("failed to serialize a struct variant");
392 assert_eq!(serialized, "d6:Structd5:field12:hi from enum7:integeri22eee");
393 let deserialized = from_str::<Enumeration>(&serialized).expect("failed to deserialize a struct variant");
394 assert_eq!(deserialized, value)
395 }
396 }
397}