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::fmt::Display;
use std::os::unix::fs::OpenOptionsExt;

use crate::{traceback, Error};

#[derive(Debug)]
pub struct OpenOptions {
    f_read: bool,
    f_write: bool,
    f_create: bool,
    f_append: bool,
    f_mode: u32,
}
impl Display for OpenOptions {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        let mut opts = Vec::<String>::new();
        if self.f_read {
            opts.push(String::from("read"));
        }
        if self.f_write {
            opts.push(String::from("write"));
        }
        if self.f_create {
            opts.push(String::from("create"));
        }
        if self.f_append {
            opts.push(String::from("append"));
        }
        if self.f_mode > 0o0000 {
            opts.push(format!("mode:{:40o}", self.f_mode));
        }
        write!(f, "[{}]", opts.join(","))
    }
}
impl OpenOptions {
    pub fn new() -> OpenOptions {
        OpenOptions {
            f_read: bool::default(),
            f_create: bool::default(),
            f_append: bool::default(),
            f_write: bool::default(),
            f_mode: 0o0600,
        }
    }

    pub fn read(&mut self, read: bool) -> &mut OpenOptions {
        self.f_read = read;
        self
    }

    pub fn create(&mut self, create: bool) -> &mut OpenOptions {
        self.f_create = create;
        self
    }

    pub fn append(&mut self, append: bool) -> &mut OpenOptions {
        self.f_append = append;
        self
    }

    pub fn write(&mut self, write: bool) -> &mut OpenOptions {
        self.f_write = write;
        self
    }

    pub fn mode(&mut self, mode: u32) -> &mut OpenOptions {
        self.f_mode = mode;
        self
    }

    pub fn open<T: Into<crate::fs::Path>>(&self, path: T) -> Result<std::fs::File, Error> {
        let path = path.into();
        Ok(if path.exists() && self.f_mode > 0o0000 {
            std::fs::OpenOptions::new()
                .create(self.f_create)
                .read(self.f_read)
                .write(self.f_write)
                .append(self.f_append)
                .mode(self.f_mode)
                .open(&path)
        } else {
            std::fs::OpenOptions::new()
                .create(self.f_create)
                .read(self.f_read)
                .write(self.f_write)
                .append(self.f_append)
                .open(&path)
        }
        .map_err(|e| {
            traceback!(
                FileSystemError,
                "{:#?}: {}",
                Into::<crate::Path>::into(path).to_string(),
                e.to_string()
            )
        })?)
    }
}