uri_parsing_rs/parser/parsers/
hier_part_parsers.rs1use nom::bytes::complete::tag;
2use nom::combinator::opt;
3use nom::sequence::{preceded, tuple};
4
5use crate::ast::authority::Authority;
6use crate::ast::path::Path;
7use crate::parser::parsers::{authority_parsers, Elms, path_parsers, UResult};
8
9#[inline]
14pub fn hier_part(i: Elms) -> UResult<Elms, (Option<Authority>, Path)> {
15 if let (i, Some((authority, path))) = opt(preceded(
16 tag("//"),
17 tuple((authority_parsers::authority, path_parsers::path_abempty)),
18 ))(i.clone())?
19 {
20 Ok((i, (Some(authority), path)))
21 } else {
22 log::debug!("path_without_abempty = {}", i.clone());
23 let (i, path) = path_parsers::path_without_abempty(i)?;
24 Ok((i, (None, path)))
25 }
26}
27
28#[cfg(test)]
29pub mod gens {
30 use prop_check_rs::gen::{Gen, Gens};
31
32 use crate::parser::parsers::authority_parsers::gens::authority_gen;
33 use crate::parser::parsers::path_parsers::gens::*;
34
35 pub fn hier_part_gen() -> Gen<Pair<String, Option<bool>>> {
36 let gen1 = || {
37 authority_gen().bind(move |authority| {
38 path_abempty_str_gen().fmap(move |path_abempty| format!("//{}{}", authority, path_abempty))
39 })
40 };
41 let gen2 = || {
42 path_str_without_abempty_gen().fmap(|Pair(p1, p2)| {
43 println!("p1 = {}", p1);
44 Pair(p2, Some(p1 == "empty_path".to_string()))
45 })
46 };
47 Gens::one_bool().bind(move |b| {
48 if b {
49 gen1().fmap(|s| Pair(s, None))
50 } else {
51 gen2()
52 }
53 })
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use std::env;
60
61 use anyhow::Result;
62 use prop_check_rs::prop;
63 use prop_check_rs::prop::TestCases;
64 use prop_check_rs::rng::RNG;
65
66 use super::*;
67 use super::gens::*;
68 use crate::parser::parsers::path_parsers::gens::Pair;
69
70 const TEST_COUNT: TestCases = 100;
71
72 fn init() {
73 env::set_var("RUST_LOG", "debug");
74 let _ = env_logger::builder().is_test(true).try_init();
75 }
76
77 #[test]
78 fn test_hier_part() -> Result<()> {
79 init();
80 let mut counter = 0;
81 let prop = prop::for_all(
82 || hier_part_gen(),
83 move |Pair(s, _b)| {
84 counter += 1;
85 log::debug!("{:>03}, hier_part = {}", counter, s);
86 let (_, (authority, path)) = hier_part(Elms::new(s.as_bytes())).ok().unwrap();
87 let sa = authority
88 .map(|e| format!("//{}", e))
89 .unwrap_or("".to_string());
90 let sp = path.to_string();
91 let sap = format!("{}{}", sa, sp);
92 assert_eq!(sap, s);
93 true
94 },
95 );
96 prop::test_with_prop(prop, 5, TEST_COUNT, RNG::new())
97 }
98}