web_url/parse/path_plus/
fragment.rs

1use crate::parse::Error;
2use crate::parse::Error::InvalidFragment;
3use crate::Fragment;
4
5/// Parses the optional `fragment`.
6///
7/// The `fragment` must start with a `#` or be empty.
8///
9/// Returns `Ok(Some(fragment))`.
10/// Returns `Ok(None)` if the `fragment` is empty.
11/// Returns `Err(InvalidFragment)` if the fragment is invalid.
12pub fn parse_fragment(fragment: &str) -> Result<Option<&str>, Error> {
13    if fragment.is_empty() {
14        Ok(None)
15    } else if Fragment::is_valid(fragment) {
16        Ok(Some(fragment))
17    } else {
18        Err(InvalidFragment)
19    }
20}
21
22#[cfg(test)]
23mod tests {
24    use crate::parse::path_plus::parse_fragment;
25    use crate::parse::Error;
26    use crate::parse::Error::InvalidFragment;
27
28    #[test]
29    fn fn_parse_fragment() {
30        let test_cases: &[(&str, Result<Option<&str>, Error>)] = &[
31            ("", Ok(None)),
32            ("fragment", Err(InvalidFragment)),
33            ("#", Ok(Some("#"))),
34            ("#fragment", Ok(Some("#fragment"))),
35            ("#\x00", Err(InvalidFragment)),
36            ("#你好", Err(InvalidFragment)),
37            ("#fragment ", Err(InvalidFragment)),
38        ];
39        for (fragment, expected) in test_cases {
40            let result: Result<Option<&str>, Error> = parse_fragment(fragment);
41            assert_eq!(result, *expected);
42        }
43    }
44}