iri_string/parser/validate/
path.rs

1//! Parsers for path.
2
3use crate::parser::char;
4use crate::parser::str::{find_split2_hole, satisfy_chars_with_pct_encoded};
5use crate::spec::Spec;
6use crate::validate::Error;
7
8/// Returns `Ok(_)` if the string matches `path-abempty` or `ipath-abempty`.
9pub(super) fn validate_path_abempty<S: Spec>(i: &str) -> Result<(), Error> {
10    if i.is_empty() {
11        return Ok(());
12    }
13    let i = match i.strip_prefix('/') {
14        Some(rest) => rest,
15        None => return Err(Error::new()),
16    };
17    let is_valid = satisfy_chars_with_pct_encoded(
18        i,
19        char::is_ascii_pchar_slash,
20        S::is_nonascii_char_unreserved,
21    );
22    if is_valid {
23        Ok(())
24    } else {
25        Err(Error::new())
26    }
27}
28
29/// Returns `Ok(_)` if the string matches `hier-part` or `ihier-part` modulo
30/// `"//" authority path-abempty`.
31pub(super) fn validate_path_absolute_authority_absent<S: Spec>(i: &str) -> Result<(), Error> {
32    if i.is_empty() {
33        // `path-empty`.
34        return Ok(());
35    }
36    if i.starts_with("//") {
37        unreachable!("this case should be handled by the caller");
38    }
39    let is_valid = satisfy_chars_with_pct_encoded(
40        i,
41        char::is_ascii_pchar_slash,
42        S::is_nonascii_char_unreserved,
43    );
44    if is_valid {
45        Ok(())
46    } else {
47        Err(Error::new())
48    }
49}
50
51/// Returns `Ok(_)` if the string matches `relative-part` or `irelative-part` modulo
52/// `"//" authority path-abempty`.
53pub(super) fn validate_path_relative_authority_absent<S: Spec>(i: &str) -> Result<(), Error> {
54    if i.starts_with("//") {
55        unreachable!("this case should be handled by the caller");
56    }
57    let is_valid = match find_split2_hole(i, b'/', b':') {
58        Some((_, b'/', _)) | None => satisfy_chars_with_pct_encoded(
59            i,
60            char::is_ascii_pchar_slash,
61            S::is_nonascii_char_unreserved,
62        ),
63        Some((_, c, _)) => {
64            debug_assert_eq!(c, b':');
65            // `foo:bar`-style. This does not match `path-noscheme`.
66            return Err(Error::new());
67        }
68    };
69    if is_valid {
70        Ok(())
71    } else {
72        Err(Error::new())
73    }
74}
75
76/// Returns `Ok(_)` if the string matches `path`/`ipath` rules.
77pub(crate) fn validate_path<S: Spec>(i: &str) -> Result<(), Error> {
78    if i.starts_with("//") {
79        return Err(Error::new());
80    }
81    let is_valid = satisfy_chars_with_pct_encoded(
82        i,
83        char::is_ascii_pchar_slash,
84        S::is_nonascii_char_unreserved,
85    );
86    if is_valid {
87        Ok(())
88    } else {
89        Err(Error::new())
90    }
91}