oni_comb_uri_rs/parsers/
hier_part_parsers.rs

1use crate::models::hier_part::HierPart;
2use crate::parsers::authority_parsers::authority;
3use crate::parsers::path_parsers::{path_abempty, path_rootless};
4use oni_comb_parser_rs::prelude::*;
5
6//  hier-part     = "//" authority path-abempty
7//                / path-absolute
8//                / path-rootless
9//                / path-empty
10pub fn hier_part<'a>() -> Parser<'a, u8, Option<HierPart>> {
11  let p1 = (seq(b"//") * authority() + path_abempty(false)).map(|(a, b)| HierPart::new(Some(a), b));
12  let p2 = (path_abempty(true).attempt() | path_rootless()).map(|e| HierPart::of_path(e));
13  (p1.attempt() | p2).opt()
14}
15
16#[cfg(test)]
17pub mod gens {
18  use crate::parsers::authority_parsers::gens::authority_gen;
19  use prop_check_rs::gen::{Gen, Gens};
20
21  use crate::parsers::path_parsers::gens::{path_abempty_gen, path_str_without_abempty_gen, Pair};
22
23  pub fn hier_part_gen() -> Gen<Pair<String, Option<bool>>> {
24    let gen1 = {
25      authority_gen().flat_map(move |authority| {
26        path_abempty_gen().map(move |path_abempty| format!("//{}{}", authority, path_abempty))
27      })
28    };
29    let gen2 = { path_str_without_abempty_gen().map(|Pair(p1, p2)| Pair(p2, Some(p1 == "empty_path".to_string()))) };
30    Gens::one_bool().flat_map(move |b| {
31      if b {
32        gen1.clone().map(|s| Pair(s, None))
33      } else {
34        gen2.clone()
35      }
36    })
37  }
38}
39
40#[cfg(test)]
41mod tests {
42  use std::env;
43
44  use crate::parsers::path_parsers::gens::Pair;
45  use anyhow::Result;
46  use prop_check_rs::prop;
47  use prop_check_rs::prop::TestCases;
48  use prop_check_rs::rng::RNG;
49
50  use super::gens::*;
51  use super::*;
52
53  const TEST_COUNT: TestCases = 100;
54
55  #[ctor::ctor]
56  fn init_logger() {
57    env::set_var("RUST_LOG", "debug");
58    let _ = env_logger::builder().is_test(true).try_init();
59  }
60
61  #[test]
62  fn test_hier_part() -> Result<()> {
63    let mut counter = 0;
64    let prop = prop::for_all_gen(hier_part_gen(), move |Pair(s, _b)| {
65      counter += 1;
66      log::debug!("{:>03}, hier_part:string = {}", counter, s);
67      let input = s.as_bytes();
68      let result = (hier_part() - end()).parse(input).to_result();
69      let hier_port = result.unwrap();
70      log::debug!("{:>03}, hier_part:object = {:?}", counter, hier_port);
71      assert_eq!(hier_port.map(|e| e.to_string()).unwrap_or("".to_string()), s);
72      true
73    });
74    prop::test_with_prop(prop, 5, TEST_COUNT, RNG::new())
75  }
76}