1use super::types::*;
2use itertools::Itertools;
3use num_bigint::BigInt;
4use std::cmp::Ordering;
5use std::collections::BTreeMap;
6use std::io;
7use std::result::Result;
8
9pub trait Encode {
13 fn encode(self, writer: &mut dyn io::Write) -> Result<(), std::io::Error>;
30}
31
32impl Encode for Vec<u8> {
33 fn encode(self, writer: &mut dyn io::Write) -> Result<(), std::io::Error> {
41 write!(writer, "{}:", self.len())?;
42 writer.write_all(&self)?;
43
44 Ok(())
45 }
46}
47
48impl Encode for i64 {
49 fn encode(self, writer: &mut dyn io::Write) -> Result<(), std::io::Error> {
57 write!(writer, "i{}e", self)
58 }
59}
60
61impl Encode for String {
62 fn encode(self, writer: &mut dyn io::Write) -> Result<(), std::io::Error> {
70 let bytes = self.into_bytes();
71 write!(writer, "u{}:", bytes.len())?;
72 writer.write_all(&bytes)?;
73
74 Ok(())
75 }
76}
77
78impl Encode for bool {
79 fn encode(self, writer: &mut dyn io::Write) -> Result<(), std::io::Error> {
87 writer.write_all(match self {
88 true => &[b't'],
89 false => &[b'f'],
90 })?;
91
92 Ok(())
93 }
94}
95
96impl Encode for BigInt {
97 fn encode(self, writer: &mut dyn io::Write) -> Result<(), std::io::Error> {
106 writer.write_all(&[b'i'])?;
107 writer.write_all(&self.to_str_radix(10).into_bytes())?;
108 writer.write_all(&[b'e'])?;
109
110 Ok(())
111 }
112}
113
114impl Encode for Vec<BencodexValue> {
115 fn encode(self, writer: &mut dyn io::Write) -> Result<(), std::io::Error> {
125 writer.write_all(&[b'l'])?;
126 for el in self {
127 el.encode(writer)?;
128 }
129 writer.write_all(&[b'e'])?;
130
131 Ok(())
132 }
133}
134
135fn encode_null(writer: &mut dyn io::Write) -> Result<(), std::io::Error> {
136 writer.write_all(&[b'n'])?;
137
138 Ok(())
139}
140
141impl Encode for BencodexValue {
142 fn encode(self, writer: &mut dyn io::Write) -> Result<(), std::io::Error> {
143 match self {
145 BencodexValue::Binary(x) => x.encode(writer)?,
146 BencodexValue::Text(x) => x.encode(writer)?,
147 BencodexValue::Dictionary(x) => x.encode(writer)?,
148 BencodexValue::List(x) => x.encode(writer)?,
149 BencodexValue::Boolean(x) => x.encode(writer)?,
150 BencodexValue::Null => encode_null(writer)?,
151 BencodexValue::Number(x) => x.encode(writer)?,
152 }
153
154 Ok(())
155 }
156}
157
158fn compare_vector<T: Ord>(xs: &[T], ys: &[T]) -> Ordering {
159 for (x, y) in xs.iter().zip(ys) {
160 match x.cmp(y) {
161 Ordering::Equal => continue,
162 Ordering::Greater => return Ordering::Greater,
163 Ordering::Less => return Ordering::Less,
164 };
165 }
166
167 xs.len().cmp(&ys.len())
168}
169
170fn compare_key(x: &BencodexKey, y: &BencodexKey) -> Ordering {
171 match (x, y) {
172 (BencodexKey::Text(x), BencodexKey::Text(y)) => compare_vector(x.as_bytes(), y.as_bytes()),
173 (BencodexKey::Binary(x), BencodexKey::Binary(y)) => compare_vector(x, y),
174 (BencodexKey::Text(_), BencodexKey::Binary(_)) => Ordering::Greater,
175 (BencodexKey::Binary(_), BencodexKey::Text(_)) => Ordering::Less,
176 }
177}
178
179impl Encode for BTreeMap<BencodexKey, BencodexValue> {
180 fn encode(self, writer: &mut dyn io::Write) -> Result<(), std::io::Error> {
193 let pairs = self
194 .into_iter()
195 .sorted_by(|(x, _), (y, _)| compare_key(x, y));
196
197 writer.write_all(&[b'd'])?;
198 for (key, value) in pairs {
199 let key = match key {
200 BencodexKey::Binary(x) => BencodexValue::Binary(x),
201 BencodexKey::Text(x) => BencodexValue::Text(x),
202 };
203
204 key.encode(writer)?;
205 value.encode(writer)?;
206 }
207 writer.write_all(&[b'e'])?;
208
209 Ok(())
210 }
211}
212
213#[cfg(test)]
214mod tests {
215 mod compare_key {
216 use super::super::*;
217
218 #[test]
219 fn should_return_equal() {
220 assert_eq!(
221 Ordering::Equal,
222 compare_key(
223 &BencodexKey::Text("foo".to_string()),
224 &BencodexKey::Text("foo".to_string())
225 )
226 );
227 assert_eq!(
228 Ordering::Equal,
229 compare_key(
230 &BencodexKey::Binary(b"bar".to_vec()),
231 &BencodexKey::Binary(b"bar".to_vec())
232 )
233 );
234 }
235
236 #[test]
237 fn should_return_greater() {
238 assert_eq!(
239 Ordering::Greater,
240 compare_key(
241 &BencodexKey::Text("".to_string()),
242 &BencodexKey::Binary(b"".to_vec())
243 )
244 );
245 }
246
247 #[test]
248 fn should_return_less() {
249 assert_eq!(
250 Ordering::Less,
251 compare_key(
252 &BencodexKey::Binary(b"".to_vec()),
253 &BencodexKey::Text("".to_string())
254 )
255 );
256 }
257 }
258
259 mod compare_vector {
260 use super::super::*;
261
262 #[test]
263 fn should_return_equal() {
264 assert_eq!(
265 Ordering::Equal,
266 compare_vector(&Vec::<u8>::new(), &Vec::<u8>::new())
267 );
268 assert_eq!(
269 Ordering::Equal,
270 compare_vector(&vec![1, 2, 3], &vec![1, 2, 3])
271 );
272 }
273
274 #[test]
275 fn should_return_less() {
276 assert_eq!(Ordering::Less, compare_vector(&vec![], &vec![3]));
277 assert_eq!(Ordering::Less, compare_vector(&vec![0], &vec![1, 2, 3]));
278 assert_eq!(Ordering::Less, compare_vector(&vec![1], &vec![9, 1, 1]));
279 assert_eq!(Ordering::Less, compare_vector(&vec![1, 2], &vec![1, 2, 3]));
280 assert_eq!(
281 Ordering::Less,
282 compare_vector(&vec![1, 9, 9], &vec![9, 1, 1])
283 );
284 }
285
286 #[test]
287 fn should_return_greater() {
288 assert_eq!(Ordering::Greater, compare_vector(&vec![9], &vec![]));
289 assert_eq!(Ordering::Greater, compare_vector(&vec![9], &vec![1, 2, 3]));
290 assert_eq!(
291 Ordering::Greater,
292 compare_vector(&vec![1, 9, 2], &vec![1, 2, 2])
293 );
294 }
295 }
296
297 mod encode {
298 struct ConditionFailWriter {
299 throw_counts: Vec<u64>,
300 call_count: u64,
301 }
302
303 impl ConditionFailWriter {
304 fn new(throw_counts: Vec<u64>) -> ConditionFailWriter {
305 ConditionFailWriter {
306 throw_counts: throw_counts,
307 call_count: 0,
308 }
309 }
310 }
311
312 #[cfg(not(tarpaulin_include))]
313 impl std::io::Write for ConditionFailWriter {
314 fn write(&mut self, bytes: &[u8]) -> std::result::Result<usize, std::io::Error> {
315 self.call_count += 1;
316 if self.throw_counts.contains(&self.call_count) {
317 Err(std::io::Error::new(std::io::ErrorKind::Other, ""))
318 } else {
319 Ok(bytes.len())
320 }
321 }
322
323 fn write_all(&mut self, _: &[u8]) -> std::result::Result<(), std::io::Error> {
324 self.call_count += 1;
325 if self.throw_counts.contains(&self.call_count) {
326 Err(std::io::Error::new(std::io::ErrorKind::Other, ""))
327 } else {
328 Ok(())
329 }
330 }
331
332 fn flush(&mut self) -> std::result::Result<(), std::io::Error> {
333 Ok(())
334 }
335 }
336
337 mod vec_u8 {
338 use super::super::super::*;
339 use super::*;
340
341 #[test]
342 fn should_pass_error() {
343 let bvalue = Vec::<u8>::new();
344
345 let mut writer = ConditionFailWriter::new(vec![1]);
347 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
348 assert_eq!(std::io::ErrorKind::Other, err.kind());
349 assert_eq!("", err.to_string());
350
351 let mut writer = ConditionFailWriter::new(vec![2]);
353 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
354 assert_eq!(std::io::ErrorKind::Other, err.kind());
355 assert_eq!("", err.to_string());
356
357 let mut writer = ConditionFailWriter::new(vec![3]);
359 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
360 assert_eq!(std::io::ErrorKind::Other, err.kind());
361 assert_eq!("", err.to_string());
362 }
363 }
364
365 mod btree_map {
366 use super::super::super::*;
367 use super::*;
368
369 #[test]
370 fn should_order_keys() {
371 let mut bvalue: BTreeMap<BencodexKey, BencodexValue> = BTreeMap::new();
372 bvalue.insert(BencodexKey::Text("ua".to_string()), BencodexValue::Null);
373 bvalue.insert(BencodexKey::Binary(vec![b'a']), BencodexValue::Null);
374 bvalue.insert(BencodexKey::Text("ub".to_string()), BencodexValue::Null);
375 bvalue.insert(BencodexKey::Binary(vec![b'b']), BencodexValue::Null);
376
377 let mut writer = Vec::new();
378 assert!(bvalue.to_owned().encode(&mut writer).is_ok());
379 assert_eq!(b"d1:an1:bnu2:uanu2:ubne".to_vec(), writer);
380 }
381
382 #[test]
383 fn should_pass_error() {
384 let mut bvalue: BTreeMap<BencodexKey, BencodexValue> = BTreeMap::new();
385 bvalue.insert(BencodexKey::Text("".to_string()), BencodexValue::Null);
386
387 let mut writer = ConditionFailWriter::new(vec![1]);
389 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
390 assert_eq!(std::io::ErrorKind::Other, err.kind());
391 assert_eq!("", err.to_string());
392
393 let mut writer = ConditionFailWriter::new(vec![2]);
395 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
396 assert_eq!(std::io::ErrorKind::Other, err.kind());
397 assert_eq!("", err.to_string());
398
399 let mut writer = ConditionFailWriter::new(vec![3]);
401 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
402 assert_eq!(std::io::ErrorKind::Other, err.kind());
403 assert_eq!("", err.to_string());
404
405 let mut writer = ConditionFailWriter::new(vec![4]);
407 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
408 assert_eq!(std::io::ErrorKind::Other, err.kind());
409 assert_eq!("", err.to_string());
410
411 let mut writer = ConditionFailWriter::new(vec![5]);
413 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
414 assert_eq!(std::io::ErrorKind::Other, err.kind());
415 assert_eq!("", err.to_string());
416
417 let mut writer = ConditionFailWriter::new(vec![6]);
419 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
420 assert_eq!(std::io::ErrorKind::Other, err.kind());
421 assert_eq!("", err.to_string());
422
423 let mut writer = ConditionFailWriter::new(vec![7]);
425 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
426 assert_eq!(std::io::ErrorKind::Other, err.kind());
427 assert_eq!("", err.to_string());
428 }
429 }
430
431 mod vec_bvalue {
432 use super::super::super::*;
433 use super::*;
434
435 #[test]
436 fn should_pass_error() {
437 let bvalue: &mut Vec<BencodexValue> = &mut Vec::new();
438 bvalue.push(BencodexValue::Null);
439
440 let mut writer = ConditionFailWriter::new(vec![1]);
442 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
443 assert_eq!(std::io::ErrorKind::Other, err.kind());
444 assert_eq!("", err.to_string());
445
446 let mut writer = ConditionFailWriter::new(vec![2]);
448 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
449 assert_eq!(std::io::ErrorKind::Other, err.kind());
450 assert_eq!("", err.to_string());
451
452 let mut writer = ConditionFailWriter::new(vec![3]);
454 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
455 assert_eq!(std::io::ErrorKind::Other, err.kind());
456 assert_eq!("", err.to_string());
457 }
458 }
459
460 mod string {
461 use super::super::super::*;
462 use super::*;
463
464 #[test]
465 fn should_pass_error() {
466 let bvalue: String = String::new();
467
468 let mut writer = ConditionFailWriter::new(vec![1]);
470 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
471 assert_eq!(std::io::ErrorKind::Other, err.kind());
472 assert_eq!("", err.to_string());
473
474 let mut writer = ConditionFailWriter::new(vec![2]);
476 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
477 assert_eq!(std::io::ErrorKind::Other, err.kind());
478 assert_eq!("", err.to_string());
479
480 let mut writer = ConditionFailWriter::new(vec![3]);
482 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
483 assert_eq!(std::io::ErrorKind::Other, err.kind());
484 assert_eq!("", err.to_string());
485
486 let mut writer = ConditionFailWriter::new(vec![4]);
488 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
489 assert_eq!(std::io::ErrorKind::Other, err.kind());
490 assert_eq!("", err.to_string());
491 }
492 }
493
494 mod bool {
495 use super::super::super::*;
496 use super::*;
497
498 #[test]
499 fn should_pass_error() {
500 let bvalue = true;
501
502 let mut writer = ConditionFailWriter::new(vec![1]);
504 let err = bvalue.encode(&mut writer).unwrap_err();
505 assert_eq!(std::io::ErrorKind::Other, err.kind());
506 assert_eq!("", err.to_string());
507 }
508 }
509
510 mod big_int {
511 use super::super::super::*;
512 use super::*;
513
514 #[test]
515 fn should_pass_error() {
516 let bvalue = BigInt::from(0);
517
518 let mut writer = ConditionFailWriter::new(vec![1]);
520 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
521 assert_eq!(std::io::ErrorKind::Other, err.kind());
522 assert_eq!("", err.to_string());
523
524 let mut writer = ConditionFailWriter::new(vec![2]);
526 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
527 assert_eq!(std::io::ErrorKind::Other, err.kind());
528 assert_eq!("", err.to_string());
529
530 let mut writer = ConditionFailWriter::new(vec![3]);
532 let err = bvalue.to_owned().encode(&mut writer).unwrap_err();
533 assert_eq!(std::io::ErrorKind::Other, err.kind());
534 assert_eq!("", err.to_string());
535 }
536 }
537
538 mod i64 {
539 use super::super::super::*;
540 use super::*;
541
542 #[test]
543 fn should_pass_error() {
544 let bvalue: i64 = 0;
545 let mut writer = ConditionFailWriter::new(vec![1]);
547 let err = bvalue.encode(&mut writer).unwrap_err();
548 assert_eq!(std::io::ErrorKind::Other, err.kind());
549 assert_eq!("", err.to_string());
550
551 let mut writer = ConditionFailWriter::new(vec![2]);
553 let err = bvalue.encode(&mut writer).unwrap_err();
554 assert_eq!(std::io::ErrorKind::Other, err.kind());
555 assert_eq!("", err.to_string());
556
557 let mut writer = ConditionFailWriter::new(vec![3]);
559 let err = bvalue.encode(&mut writer).unwrap_err();
560 assert_eq!(std::io::ErrorKind::Other, err.kind());
561 assert_eq!("", err.to_string());
562 }
563 }
564 }
565}