|
25 | 25 | //! }
|
26 | 26 | //! ```
|
27 | 27 |
|
28 |
| -/* |
29 | 28 | #![forbid(unsafe_code)]
|
30 | 29 | #![deny(missing_docs)]
|
31 | 30 | #![deny(warnings)]
|
32 | 31 | #![deny(clippy::nursery)]
|
33 | 32 | #![deny(clippy::pedantic)]
|
34 | 33 | #![deny(clippy::all)]
|
35 |
| - */ |
36 | 34 |
|
37 |
| -use error::BencodeError; |
| 35 | +pub use errors::BencodeError; |
38 | 36 | use nom::{
|
39 | 37 | branch::alt,
|
40 | 38 | bytes::complete::take,
|
41 | 39 | character::complete::{char, digit1},
|
42 | 40 | combinator::{eof, recognize},
|
43 | 41 | multi::{many0, many_till},
|
44 | 42 | sequence::{delimited, pair, preceded},
|
45 |
| - Err, IResult, |
| 43 | + IResult, |
46 | 44 | };
|
47 | 45 | use std::{collections::HashMap, fmt::Debug};
|
48 | 46 |
|
49 |
| -pub mod error; |
| 47 | +pub mod errors; |
| 48 | +pub use nom::Err; |
50 | 49 |
|
51 | 50 | type BenResult<'a> = IResult<&'a [u8], Value<'a>, BencodeError<&'a [u8]>>;
|
52 | 51 |
|
@@ -179,7 +178,7 @@ pub fn parse(source: &[u8]) -> Result<Vec<Value>, Err<BencodeError<&[u8]>>> {
|
179 | 178 | mod tests {
|
180 | 179 | use crate::{parse, BencodeError, Value};
|
181 | 180 | use assert_matches::assert_matches;
|
182 |
| - use proptest::prelude::*; |
| 181 | + use proptest::{collection::vec, prelude::*}; |
183 | 182 |
|
184 | 183 | #[test]
|
185 | 184 | fn test_integer() {
|
@@ -379,10 +378,85 @@ mod tests {
|
379 | 378 | let _ = parse(include_bytes!("../test-assets/multi-file.torrent")).unwrap();
|
380 | 379 | }
|
381 | 380 |
|
| 381 | + prop_compose! { |
| 382 | + fn bencode_bytes()(s in vec(any::<u8>(), 1..100)) -> Vec<u8> { |
| 383 | + let mut data: Vec<u8> = Vec::with_capacity(s.len() + 5); |
| 384 | + data.extend(format!("{}:", s.len()).as_bytes()); |
| 385 | + data.extend(s); |
| 386 | + data |
| 387 | + } |
| 388 | + } |
| 389 | + |
| 390 | + prop_compose! { |
| 391 | + fn bencode_integer()(s in any::<i64>()) -> Vec<u8> { |
| 392 | + format!("i{s}e").as_bytes().to_vec() |
| 393 | + } |
| 394 | + } |
| 395 | + |
| 396 | + prop_compose! { |
| 397 | + fn bencode_list()(s in vec((bencode_integer(), bencode_bytes()), 1..100)) -> Vec<u8> { |
| 398 | + let mut data: Vec<u8> = Vec::with_capacity(s.len() + 2); |
| 399 | + data.extend(b"l"); |
| 400 | + for (i, (a, b)) in s.iter().enumerate() { |
| 401 | + if i % 2 == 0 { |
| 402 | + data.extend(a); |
| 403 | + data.extend(b); |
| 404 | + } else { |
| 405 | + data.extend(b); |
| 406 | + data.extend(a); |
| 407 | + } |
| 408 | + |
| 409 | + } |
| 410 | + data.extend(b"e"); |
| 411 | + data |
| 412 | + } |
| 413 | + } |
| 414 | + |
| 415 | + prop_compose! { |
| 416 | + fn bencode_dict()(s in vec((bencode_bytes(), bencode_bytes()), 1..100)) -> Vec<u8> { |
| 417 | + let mut data: Vec<u8> = Vec::with_capacity(s.len() + 2); |
| 418 | + data.extend(b"d"); |
| 419 | + for (i, (a, b)) in s.iter().enumerate() { |
| 420 | + if i % 2 == 0 { |
| 421 | + data.extend(a); |
| 422 | + data.extend(b); |
| 423 | + } else { |
| 424 | + data.extend(b); |
| 425 | + data.extend(a); |
| 426 | + } |
| 427 | + } |
| 428 | + data.extend(b"e"); |
| 429 | + data |
| 430 | + } |
| 431 | + } |
| 432 | + |
382 | 433 | proptest! {
|
383 | 434 | #[test]
|
384 |
| - fn doesnt_panic(s in any::<Vec<u8>>()) { |
| 435 | + fn proptest_doesnt_panic_or_overflow(s in any::<Vec<u8>>()) { |
385 | 436 | parse(&s).ok();
|
386 | 437 | }
|
| 438 | + |
| 439 | + #[test] |
| 440 | + fn proptest_parse_integer(s in bencode_integer()) { |
| 441 | + prop_assert!(Value::parse_integer(&s).is_ok()); |
| 442 | + } |
| 443 | + |
| 444 | + #[test] |
| 445 | + fn proptest_parse_bytes(s in bencode_bytes()) { |
| 446 | + let mut data: Vec<u8> = Vec::with_capacity(s.len() + 5); |
| 447 | + data.extend(format!("{}:", s.len()).as_bytes()); |
| 448 | + data.extend(s); |
| 449 | + prop_assert!(Value::parse_bytes(&data).is_ok()); |
| 450 | + } |
| 451 | + |
| 452 | + #[test] |
| 453 | + fn proptest_parse_list(s in bencode_list()) { |
| 454 | + prop_assert!(Value::parse_list(&s).is_ok()); |
| 455 | + } |
| 456 | + |
| 457 | + #[test] |
| 458 | + fn proptest_parse_dict(s in bencode_dict()) { |
| 459 | + prop_assert!(Value::parse_dict(&s).is_ok()); |
| 460 | + } |
387 | 461 | }
|
388 | 462 | }
|
0 commit comments