use crate::error::FsError;
use crate::error::FsOperation;
use crate::error::FsResult;
use crate::path::Path;
use crate::path::PathForm;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PathConstraints {
form: PathForm,
}
impl PathConstraints {
#[inline]
#[must_use]
pub const fn absolute() -> Self {
Self {
form: PathForm::Absolute,
}
}
#[inline]
#[must_use]
pub const fn relative() -> Self {
Self {
form: PathForm::Relative,
}
}
#[inline]
#[must_use]
pub const fn either() -> Self {
Self { form: PathForm::Either }
}
#[inline]
#[must_use]
pub const fn form(&self) -> PathForm {
self.form
}
#[inline]
pub fn validate(&self, path: &Path) -> FsResult<()> {
let allowed = matches!(self.form, PathForm::Either)
|| matches!(
(self.form, path.is_absolute()),
(PathForm::Absolute, true) | (PathForm::Relative, false)
);
if allowed {
Ok(())
} else {
Err(FsError::invalid_path(
FsOperation::ParsePath,
"path form is not accepted by this filesystem",
))
}
}
}
#[cfg(test)]
mod tests {
use std::hint::black_box;
use super::PathConstraints;
use crate::path::PathForm;
#[test]
fn relative_constructor_is_executed_at_runtime() {
let constructor: fn() -> PathConstraints = black_box(PathConstraints::relative);
let either_constructor: fn() -> PathConstraints = black_box(PathConstraints::either);
assert_eq!(PathForm::Relative, constructor().form());
assert_eq!(PathForm::Either, either_constructor().form());
}
}