use crate::error::{PathError, StorageError};
pub fn bucket(id: &str) -> Result<&str, StorageError> {
check(id, core::iter::once(id))?;
Ok(id)
}
pub fn object(path: &str) -> Result<core::str::Split<'_, char>, StorageError> {
check(path, path.split('/'))?;
Ok(path.split('/'))
}
fn check<'a>(input: &str, mut segments: impl Iterator<Item = &'a str>) -> Result<(), StorageError> {
let reason = if input.is_empty() {
Some(PathError::Empty)
} else if input.contains(['\t', '\r', '\n']) {
Some(PathError::ControlCharacter)
} else {
segments.find_map(|segment| match segment {
"" => Some(PathError::EmptySegment),
"." | ".." => Some(PathError::DotSegment),
_ => None,
})
};
reason.map_or(Ok(()), |reason| {
Err(StorageError::InvalidPath {
path: input.to_owned(),
reason,
})
})
}