//! Parsers for path. use crate::parser::char; use crate::parser::str::{find_split2_hole, satisfy_chars_with_pct_encoded}; use crate::spec::Spec; use crate::validate::Error; /// Returns `Ok(_)` if the string matches `path-abempty` or `ipath-abempty`. pub(super) fn validate_path_abempty(i: &str) -> Result<(), Error> { if i.is_empty() { return Ok(()); } let i = match i.strip_prefix('/') { Some(rest) => rest, None => return Err(Error::new()), }; let is_valid = satisfy_chars_with_pct_encoded( i, char::is_ascii_pchar_slash, S::is_nonascii_char_unreserved, ); if is_valid { Ok(()) } else { Err(Error::new()) } } /// Returns `Ok(_)` if the string matches `hier-part` or `ihier-part` modulo /// `"//" authority path-abempty`. pub(super) fn validate_path_absolute_authority_absent(i: &str) -> Result<(), Error> { if i.is_empty() { // `path-empty`. return Ok(()); } if i.starts_with("//") { unreachable!("this case should be handled by the caller"); } let is_valid = satisfy_chars_with_pct_encoded( i, char::is_ascii_pchar_slash, S::is_nonascii_char_unreserved, ); if is_valid { Ok(()) } else { Err(Error::new()) } } /// Returns `Ok(_)` if the string matches `relative-part` or `irelative-part` modulo /// `"//" authority path-abempty`. pub(super) fn validate_path_relative_authority_absent(i: &str) -> Result<(), Error> { if i.starts_with("//") { unreachable!("this case should be handled by the caller"); } let is_valid = match find_split2_hole(i, b'/', b':') { Some((_, b'/', _)) | None => satisfy_chars_with_pct_encoded( i, char::is_ascii_pchar_slash, S::is_nonascii_char_unreserved, ), Some((_, c, _)) => { debug_assert_eq!(c, b':'); // `foo:bar`-style. This does not match `path-noscheme`. return Err(Error::new()); } }; if is_valid { Ok(()) } else { Err(Error::new()) } } /// Returns `Ok(_)` if the string matches `path`/`ipath` rules. pub(crate) fn validate_path(i: &str) -> Result<(), Error> { if i.starts_with("//") { return Err(Error::new()); } let is_valid = satisfy_chars_with_pct_encoded( i, char::is_ascii_pchar_slash, S::is_nonascii_char_unreserved, ); if is_valid { Ok(()) } else { Err(Error::new()) } }