web_url/parse/path_plus/
path.rs

1use crate::parse::Error;
2use crate::Path;
3
4/// Parses the path from the prefix of `s`.
5///
6/// Returns `Ok(path, rest_of_s)`.
7/// Returns `Err(InvalidPath)` if the path is invalid.
8pub fn parse_path(s: &str) -> Result<(Path<'_>, &str), Error> {
9    if let Some(qh) = s.as_bytes().iter().position(|c| *c == b'?' || *c == b'#') {
10        let path: Path = Path::try_from(&s[..qh])?;
11        let s: &str = &s[qh..];
12        Ok((path, s))
13    } else {
14        let path: Path = Path::try_from(s)?;
15        Ok((path, ""))
16    }
17}
18
19#[cfg(test)]
20mod tests {
21    use crate::parse::path_plus::parse_path;
22    use crate::Path;
23
24    #[test]
25    fn fn_parse_path() {
26        let test_cases: &[(&str, Option<(&str, &str)>)] = &[
27            ("", None),
28            ("no/starting/slash", None),
29            ("/", Some(("/", ""))),
30            ("/the/path", Some(("/the/path", ""))),
31            ("/the/path?query", Some(("/the/path", "?query"))),
32            ("/the/path#fragment", Some(("/the/path", "#fragment"))),
33        ];
34        for (s, expected) in test_cases {
35            let expected: Option<(Path, &str)> =
36                expected.map(|(p, s)| (unsafe { Path::new(p) }, s));
37            let result: Option<(Path, &str)> = parse_path(s).ok();
38            assert_eq!(result, expected, "s={}", s);
39        }
40    }
41}