iocore 3.1.0

IOCore is a safe library for unix CLI tools and Systems programming. IOCore provides the [`iocore::Path`] abstraction of file-system paths designed to replace most [`std::path`] and [`std::fs`] operations with practical methods, other abstractions include: - handling file-system permissions via [`iocore::PathPermissions`] powered by the crate [`trilobyte`]. - handling file-system timestamps via [`iocore::PathTimestamps`] granularly via [`iocore::PathDateTime`]. IOCore provides the [`iocore::walk_dir`] function and its companion trait [`iocore::WalkProgressHandler`] which traverses file-systems quickly via threads. IOcore provides [`iocore::User`] which provides unix user information such as uid, path to home etc. The module [`iocore::env`] provides [`iocore::env:args`] returns a [`Vec<String>`] from [`std::env:args`], and [`iocore::env:var`] that returns environment variables as string.
Documentation
use std::path::MAIN_SEPARATOR_STR;

use crate::Path;
use crate::errors::{Error, Result};

pub struct FileName {
    value: String,
}

impl FileName {
    pub fn new(name: impl Into<String>) -> Result<FileName> {
        let value: String = value.into();
        if value.contains(MAIN_SEPARATOR_STR) {
            Err(Error::MalformedFileName(format!(
                "FileName contains path separator {:#?}: {:#?}",
                MAIN_SEPARATOR_STR, &value
            )))
        } else {
            FileName { value }
        }
    }

    pub fn validate(&self) -> Result<()> {
        if self.value.contains(MAIN_SEPARATOR_STR) {
            Err(Error::MalformedFileName(format!(
                "FileName contains path separator {:#?}: {:#?}",
                MAIN_SEPARATOR_STR, &self.value
            )))
        } else {
            Ok(())
        }
    }

    pub fn at_path(&self, path: &Path) -> Result<Path> {
        self.validate()?;
        if !path.exists() || path.is_dir() {
            Ok(path.join(&self.value))
        } else {
            Err(Error::PathConversionError(format!(
                "in joining {:#?}: {:#?} exists and is not a diretory",
                &self, path
            )))
        }
    }
}

impl std::fmt::Display for FileName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.validate()?;
        write!(f, "{}", &self.value)
    }
}

impl std::fmt::Debug for FileName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{}::FileName({:#?})", module_path!(), &self.value)
    }
}