uri_parsing_rs/parser/parsers/
fragment_parsers.rs1use 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}