use super::Path;
use crate::Char16;
use crate::fs::CHARACTER_DENY_LIST;
use core::fmt::{self, Display, Formatter};
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum PathError {
Empty,
EmptyComponent,
IllegalChar(Char16),
}
impl Display for PathError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Empty => write!(f, "path is empty"),
Self::EmptyComponent => write!(f, "path contains an empty component"),
Self::IllegalChar(c) => {
write!(
f,
"path contains an illegal character (value {})",
u16::from(*c)
)
}
}
}
}
impl core::error::Error for PathError {}
pub fn validate_path<P: AsRef<Path>>(path: P) -> Result<(), PathError> {
let path = path.as_ref();
if path.is_empty() {
return Err(PathError::Empty);
}
for component in path.components() {
if component.is_empty() {
return Err(PathError::EmptyComponent);
} else if let Some(char) = component
.as_slice()
.iter()
.find(|c| CHARACTER_DENY_LIST.contains(c))
{
return Err(PathError::IllegalChar(*char));
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::fs::PathBuf;
use crate::{CString16, cstr16};
#[test]
fn test_validate_path() {
validate_path(cstr16!("hello\\foo\\bar")).unwrap();
let err = validate_path(cstr16!("hello\\f>oo\\bar")).unwrap_err();
assert_eq!(err, PathError::IllegalChar(CHARACTER_DENY_LIST[6]));
let err = validate_path(cstr16!("hello\\\\bar")).unwrap_err();
assert_eq!(err, PathError::EmptyComponent);
let empty_cstring16 = CString16::try_from("").unwrap();
let path = PathBuf::from(empty_cstring16);
let err = validate_path(path).unwrap_err();
assert_eq!(err, PathError::Empty)
}
}