You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dirstat/src/config.rs

125 lines
2.4 KiB

use std::path::PathBuf;
use std::num::NonZeroUsize;
use std::{fmt,error};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Recursion
{
None,
Limited(NonZeroUsize),
Unlimited,
}
impl Default for Recursion
{
#[inline]
fn default() -> Self
{
Self::None
}
}
impl Recursion
{
/// Can we run at this depth?
pub fn can_run(&self, depth: usize) -> bool
{
debug_assert!(depth > 0, "Depth of 0 is invalid");
match self {
Self::None => depth == 1,
Self::Limited(limit) => depth <= limit.get(),
Self::Unlimited => true
}
}
}
impl From<usize> for Recursion
{
fn from(from: usize) -> Self
{
match from {
0 => Self::Unlimited,
1 => Self::None,
x => Self::Limited(unsafe {NonZeroUsize::new_unchecked(x)}),
}
}
}
/// Configuration for this run
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Config
{
pub paths: Vec<PathBuf>,
pub recursive: Recursion,
pub max_tasks: Option<NonZeroUsize>,
}
/// The default `max_tasks`
#[inline(always)] pub fn max_tasks_cpus() -> Option<NonZeroUsize>
{
lazy_static! {
static ref CPUS: usize = num_cpus::get();
}
NonZeroUsize::new(*CPUS)
}
impl Default for Config
{
#[inline]
fn default() -> Self
{
Self {
paths: Vec::new(),
recursive: Default::default(),
max_tasks: max_tasks_cpus(),
}
}
}
impl Config
{
/// Validate this configuration instance.
pub fn validate(self) -> Result<Self, InvalidConfigError>
{
if self.paths.len() < 1 {
return Err(InvalidConfigError::NoPaths);
}
let paths: Result<Vec<_>, _> = self.paths.into_iter()
.map(|path| if !path.exists() { Err(InvalidConfigError::PathNotFound(path)) } else { Ok(path) })
.collect();
Ok(Self{
paths: paths?,
..self
})
}
}
/// Error type for an invalid instance of `Config`.
#[derive(Debug)]
#[non_exhaustive]
pub enum InvalidConfigError
{
/// No paths were given.
NoPaths,
/// Non-existant path was given.
PathNotFound(PathBuf),
/// Unknown error
Other,
}
impl error::Error for InvalidConfigError{}
impl fmt::Display for InvalidConfigError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
match self {
Self::NoPaths => write!(f, "No input paths were given. Cannot do anything"),
Self::PathNotFound(path) => write!(f, "Root path {:?} not found", path),
#[cold] _ => write!(f, "Unknown error"),
}
}
}