uri_parsing_rs/parser/parsers/
fragment_parsers.rs

1use nom::branch::alt;
2use nom::character::complete::one_of;
3use nom::combinator::map;
4use nom::error::context;
5use nom::multi::many1;
6
7use crate::parser::parsers::{Elms, UResult};
8use crate::parser::parsers::basic_parsers::*;
9
10#[inline]
11pub(crate) fn fragment(i: Elms) -> UResult<Elms, String> {
12  context(
13    "fragment",
14    map(many1(alt((pchar, map(one_of("/?"), |c| c.into())))), |sl| {
15      sl.into_iter().collect()
16    }),
17  )(i)
18}
19
20#[cfg(test)]
21pub mod gens {
22  use prop_check_rs::gen::{Gen, Gens};
23  use crate::parser::parsers::basic_parsers::gens::*;
24
25  pub fn fragment_str_gen() -> Gen<String> {
26    rep_str_gen(1, u8::MAX - 1, || {
27      Gens::choose_u8(1, 2).bind(|n| match n {
28        1 => pchar_str_gen(1, 1),
29        2 => Gens::one_of_vec(vec!['/', '?']).fmap(|c| c.into()),
30        x => panic!("x = {}", x),
31      })
32    })
33  }
34}
35
36#[cfg(test)]
37mod tests {
38  use std::env;
39
40  use anyhow::Result;
41  use prop_check_rs::prop;
42  use prop_check_rs::prop::TestCases;
43  use prop_check_rs::rng::RNG;
44
45  use super::*;
46  use super::gens::*;
47
48  const TEST_COUNT: TestCases = 100;
49
50  fn init() {
51    env::set_var("RUST_LOG", "debug");
52    let _ = env_logger::builder().is_test(true).try_init();
53  }
54
55  #[test]
56  fn test_fragment() -> Result<()> {
57    init();
58    let mut counter = 0;
59    let prop = prop::for_all(
60      || fragment_str_gen(),
61      move |s| {
62        counter += 1;
63        log::debug!("{:>03}, fragment = {}", counter, s);
64        let (_, fragment) = fragment(Elms::new(s.as_bytes())).ok().unwrap();
65        assert_eq!(fragment, s);
66        true
67      },
68    );
69    prop::test_with_prop(prop, 5, TEST_COUNT, RNG::new())
70  }
71}