1#![allow(
2 clippy::cast_possible_wrap,
3 reason = "M175: bencode `u64 → i64` for serializer compat — bencode integers are i64 by spec; user values > i64::MAX would round-trip incorrectly but are vanishingly rare in real torrents"
4)]
5
6use serde::ser::{self, Serialize};
7use std::io::Write;
8
9use crate::error::{Error, Result};
10
11pub struct Serializer<W> {
15 writer: W,
16}
17
18impl<W: Write> Serializer<W> {
19 pub fn new(writer: W) -> Self {
21 Self { writer }
22 }
23
24 fn write_byte_string(&mut self, v: &[u8]) -> Result<()> {
25 write!(self.writer, "{}:", v.len()).map_err(|e| Error::Custom(e.to_string()))?;
26 self.writer
27 .write_all(v)
28 .map_err(|e| Error::Custom(e.to_string()))
29 }
30
31 fn write_integer(&mut self, v: i64) -> Result<()> {
32 write!(self.writer, "i{v}e").map_err(|e| Error::Custom(e.to_string()))
33 }
34}
35
36impl<'a, W: Write> ser::Serializer for &'a mut Serializer<W> {
37 type Ok = ();
38 type Error = Error;
39 type SerializeSeq = &'a mut Serializer<W>;
40 type SerializeTuple = &'a mut Serializer<W>;
41 type SerializeTupleStruct = &'a mut Serializer<W>;
42 type SerializeTupleVariant = &'a mut Serializer<W>;
43 type SerializeMap = SortedMapSerializer<'a, W>;
44 type SerializeStruct = SortedMapSerializer<'a, W>;
45 type SerializeStructVariant = SortedMapSerializer<'a, W>;
46
47 fn serialize_bool(self, v: bool) -> Result<()> {
48 self.write_integer(i64::from(v))
49 }
50
51 fn serialize_i8(self, v: i8) -> Result<()> {
52 self.write_integer(i64::from(v))
53 }
54
55 fn serialize_i16(self, v: i16) -> Result<()> {
56 self.write_integer(i64::from(v))
57 }
58
59 fn serialize_i32(self, v: i32) -> Result<()> {
60 self.write_integer(i64::from(v))
61 }
62
63 fn serialize_i64(self, v: i64) -> Result<()> {
64 self.write_integer(v)
65 }
66
67 fn serialize_u8(self, v: u8) -> Result<()> {
68 self.write_integer(i64::from(v))
69 }
70
71 fn serialize_u16(self, v: u16) -> Result<()> {
72 self.write_integer(i64::from(v))
73 }
74
75 fn serialize_u32(self, v: u32) -> Result<()> {
76 self.write_integer(i64::from(v))
77 }
78
79 fn serialize_u64(self, v: u64) -> Result<()> {
80 self.write_integer(v as i64)
81 }
82
83 fn serialize_f32(self, _v: f32) -> Result<()> {
84 Err(Error::Custom("bencode does not support floats".into()))
85 }
86
87 fn serialize_f64(self, _v: f64) -> Result<()> {
88 Err(Error::Custom("bencode does not support floats".into()))
89 }
90
91 fn serialize_char(self, v: char) -> Result<()> {
92 let mut buf = [0u8; 4];
93 let s = v.encode_utf8(&mut buf);
94 self.write_byte_string(s.as_bytes())
95 }
96
97 fn serialize_str(self, v: &str) -> Result<()> {
98 self.write_byte_string(v.as_bytes())
99 }
100
101 fn serialize_bytes(self, v: &[u8]) -> Result<()> {
102 self.write_byte_string(v)
103 }
104
105 fn serialize_none(self) -> Result<()> {
106 Err(Error::Custom("bencode does not support None/null".into()))
107 }
108
109 fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<()> {
110 value.serialize(self)
111 }
112
113 fn serialize_unit(self) -> Result<()> {
114 Err(Error::Custom("bencode does not support unit".into()))
115 }
116
117 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
118 Err(Error::Custom(
119 "bencode does not support unit structs".into(),
120 ))
121 }
122
123 fn serialize_unit_variant(
124 self,
125 _name: &'static str,
126 _variant_index: u32,
127 variant: &'static str,
128 ) -> Result<()> {
129 self.write_byte_string(variant.as_bytes())
130 }
131
132 fn serialize_newtype_struct<T: ?Sized + Serialize>(
133 self,
134 _name: &'static str,
135 value: &T,
136 ) -> Result<()> {
137 value.serialize(self)
138 }
139
140 fn serialize_newtype_variant<T: ?Sized + Serialize>(
141 self,
142 _name: &'static str,
143 _variant_index: u32,
144 variant: &'static str,
145 value: &T,
146 ) -> Result<()> {
147 self.writer
148 .write_all(b"d")
149 .map_err(|e| Error::Custom(e.to_string()))?;
150 self.write_byte_string(variant.as_bytes())?;
151 value.serialize(&mut *self)?;
152 self.writer
153 .write_all(b"e")
154 .map_err(|e| Error::Custom(e.to_string()))
155 }
156
157 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
158 self.writer
159 .write_all(b"l")
160 .map_err(|e| Error::Custom(e.to_string()))?;
161 Ok(self)
162 }
163
164 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
165 self.serialize_seq(Some(len))
166 }
167
168 fn serialize_tuple_struct(
169 self,
170 _name: &'static str,
171 len: usize,
172 ) -> Result<Self::SerializeTupleStruct> {
173 self.serialize_seq(Some(len))
174 }
175
176 fn serialize_tuple_variant(
177 self,
178 _name: &'static str,
179 _variant_index: u32,
180 variant: &'static str,
181 _len: usize,
182 ) -> Result<Self::SerializeTupleVariant> {
183 self.writer
184 .write_all(b"d")
185 .map_err(|e| Error::Custom(e.to_string()))?;
186 self.write_byte_string(variant.as_bytes())?;
187 self.writer
188 .write_all(b"l")
189 .map_err(|e| Error::Custom(e.to_string()))?;
190 Ok(self)
191 }
192
193 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
194 Ok(SortedMapSerializer::new(self))
195 }
196
197 fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
198 Ok(SortedMapSerializer::new(self))
199 }
200
201 fn serialize_struct_variant(
202 self,
203 _name: &'static str,
204 _variant_index: u32,
205 variant: &'static str,
206 _len: usize,
207 ) -> Result<Self::SerializeStructVariant> {
208 self.writer
212 .write_all(b"d")
213 .map_err(|e| Error::Custom(e.to_string()))?;
214 self.write_byte_string(variant.as_bytes())?;
215 Ok(SortedMapSerializer::new_nested(self))
216 }
217}
218
219impl<W: Write> ser::SerializeSeq for &mut Serializer<W> {
221 type Ok = ();
222 type Error = Error;
223
224 fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
225 value.serialize(&mut **self)
226 }
227
228 fn end(self) -> Result<()> {
229 self.writer
230 .write_all(b"e")
231 .map_err(|e| Error::Custom(e.to_string()))
232 }
233}
234
235impl<W: Write> ser::SerializeTuple for &mut Serializer<W> {
236 type Ok = ();
237 type Error = Error;
238
239 fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
240 ser::SerializeSeq::serialize_element(self, value)
241 }
242
243 fn end(self) -> Result<()> {
244 ser::SerializeSeq::end(self)
245 }
246}
247
248impl<W: Write> ser::SerializeTupleStruct for &mut Serializer<W> {
249 type Ok = ();
250 type Error = Error;
251
252 fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
253 ser::SerializeSeq::serialize_element(self, value)
254 }
255
256 fn end(self) -> Result<()> {
257 ser::SerializeSeq::end(self)
258 }
259}
260
261impl<W: Write> ser::SerializeTupleVariant for &mut Serializer<W> {
262 type Ok = ();
263 type Error = Error;
264
265 fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
266 ser::SerializeSeq::serialize_element(self, value)
267 }
268
269 fn end(self) -> Result<()> {
270 self.writer
272 .write_all(b"e")
273 .map_err(|e| Error::Custom(e.to_string()))?;
274 self.writer
275 .write_all(b"e")
276 .map_err(|e| Error::Custom(e.to_string()))
277 }
278}
279
280pub struct SortedMapSerializer<'a, W> {
285 ser: &'a mut Serializer<W>,
286 entries: Vec<(Vec<u8>, Vec<u8>)>,
287 current_key: Option<Vec<u8>>,
288 nested: bool,
290}
291
292impl<'a, W: Write> SortedMapSerializer<'a, W> {
293 fn new(ser: &'a mut Serializer<W>) -> Self {
294 SortedMapSerializer {
295 ser,
296 entries: Vec::new(),
297 current_key: None,
298 nested: false,
299 }
300 }
301
302 fn new_nested(ser: &'a mut Serializer<W>) -> Self {
303 SortedMapSerializer {
304 ser,
305 entries: Vec::new(),
306 current_key: None,
307 nested: true,
308 }
309 }
310
311 fn flush_sorted(&mut self) -> Result<()> {
312 self.entries.sort_by(|a, b| a.0.cmp(&b.0));
313 self.ser
314 .writer
315 .write_all(b"d")
316 .map_err(|e| Error::Custom(e.to_string()))?;
317 for (key, value) in &self.entries {
318 self.ser.write_byte_string(key)?;
319 self.ser
320 .writer
321 .write_all(value)
322 .map_err(|e| Error::Custom(e.to_string()))?;
323 }
324 self.ser
325 .writer
326 .write_all(b"e")
327 .map_err(|e| Error::Custom(e.to_string()))
328 }
329}
330
331impl<W: Write> ser::SerializeMap for SortedMapSerializer<'_, W> {
332 type Ok = ();
333 type Error = Error;
334
335 fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<()> {
336 let mut buf = Vec::new();
337 let mut key_ser = Serializer::new(&mut buf);
338 key.serialize(&mut key_ser)?;
339 self.current_key = Some(extract_string_content(&buf)?);
342 Ok(())
343 }
344
345 fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
346 let key = self
347 .current_key
348 .take()
349 .ok_or_else(|| Error::Custom("serialize_value called before serialize_key".into()))?;
350 let mut buf = Vec::new();
351 let mut val_ser = Serializer::new(&mut buf);
352 value.serialize(&mut val_ser)?;
353 self.entries.push((key, buf));
354 Ok(())
355 }
356
357 fn end(mut self) -> Result<()> {
358 self.flush_sorted()?;
359 if self.nested {
360 self.ser
361 .writer
362 .write_all(b"e")
363 .map_err(|e| Error::Custom(e.to_string()))?;
364 }
365 Ok(())
366 }
367}
368
369impl<W: Write> ser::SerializeStruct for SortedMapSerializer<'_, W> {
370 type Ok = ();
371 type Error = Error;
372
373 fn serialize_field<T: ?Sized + Serialize>(
374 &mut self,
375 key: &'static str,
376 value: &T,
377 ) -> Result<()> {
378 let mut buf = Vec::new();
379 let mut val_ser = Serializer::new(&mut buf);
380 value.serialize(&mut val_ser)?;
381 self.entries.push((key.as_bytes().to_vec(), buf));
382 Ok(())
383 }
384
385 fn end(mut self) -> Result<()> {
386 self.flush_sorted()?;
387 if self.nested {
388 self.ser
389 .writer
390 .write_all(b"e")
391 .map_err(|e| Error::Custom(e.to_string()))?;
392 }
393 Ok(())
394 }
395
396 fn skip_field(&mut self, _key: &'static str) -> Result<()> {
397 Ok(())
398 }
399}
400
401impl<W: Write> ser::SerializeStructVariant for SortedMapSerializer<'_, W> {
402 type Ok = ();
403 type Error = Error;
404
405 fn serialize_field<T: ?Sized + Serialize>(
406 &mut self,
407 key: &'static str,
408 value: &T,
409 ) -> Result<()> {
410 ser::SerializeStruct::serialize_field(self, key, value)
411 }
412
413 fn end(self) -> Result<()> {
414 ser::SerializeStruct::end(self)
415 }
416}
417
418fn extract_string_content(encoded: &[u8]) -> Result<Vec<u8>> {
420 let colon_pos = encoded
421 .iter()
422 .position(|&b| b == b':')
423 .ok_or_else(|| Error::Custom("map key must be a string".into()))?;
424 Ok(encoded[colon_pos + 1..].to_vec())
425}
426
427#[cfg(test)]
428mod tests {
429 use serde::Serialize;
430
431 #[test]
432 fn serialize_integer() {
433 assert_eq!(to_bytes(&42i64), b"i42e");
434 assert_eq!(to_bytes(&0i64), b"i0e");
435 assert_eq!(to_bytes(&-1i64), b"i-1e");
436 }
437
438 #[test]
439 fn serialize_string() {
440 assert_eq!(to_bytes("spam"), b"4:spam");
441 assert_eq!(to_bytes(""), b"0:");
442 }
443
444 #[test]
445 fn serialize_list() {
446 let list = vec!["spam", "eggs"];
447 assert_eq!(to_bytes(&list), b"l4:spam4:eggse");
448 }
449
450 #[test]
451 fn serialize_struct_sorted_keys() {
452 #[derive(Serialize)]
453 struct Test {
454 zebra: i64,
455 alpha: i64,
456 }
457 let val = Test { zebra: 2, alpha: 1 };
458 assert_eq!(to_bytes(&val), b"d5:alphai1e5:zebrai2ee");
460 }
461
462 fn to_bytes<T: Serialize + ?Sized>(value: &T) -> Vec<u8> {
463 crate::to_bytes(value).unwrap()
464 }
465}