1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
#![crate_name = "fileman_rs"]
//! A high-performance file management system for working with large quantities of files written in Rust.
// declare cargo crates
use std::io;
// declare local modules
mod organize;
mod tools;
pub trait RunTask {
/// task definition that allows Config to run a task outlined in a task module
///
/// # Arguments
///
/// `&self` - a reference to Config enum
fn run_task(&self) -> Result<(), io::Error>;
}
#[derive(Debug, PartialEq, Eq)]
pub enum Config {
/// configuration enum, all tasks are given their own variant
// variant to run the organize task
Organize(organize::OrganizeTask),
}
impl Config {
/// Config enum constructor
///
/// # Arguments
///
/// `args` - an iterator containing Strings to be used as arguments
///
/// # Errors
///
/// - no task specified
/// - provided task does not match any defined task
/// - error propagated upward from subsequent function calls
pub fn new(mut args: impl Iterator<Item = String>) -> Result<Config, &'static str> {
//skips the path to the compiled file (first argument passed in)
args.next();
// errors if there is no task specified
let task = match args.next() {
Some(arg) => arg,
None => return Err("no task specified"),
};
// match an all lowercase task to a set of predefined tasks
match task.to_lowercase().as_str() {
"organize" => {
// ensures OrganizeTask created successfully, otherwise propagates error
let organize_task = organize::OrganizeTask::new(args)?;
Ok(Self::Organize(organize_task))
}
// errors if desired task is not defined
_ => return Err("provided task did not match any defined tasks"),
}
}
}
/// RunTask trait allows for all tasks to be run from main.rs
impl RunTask for Config {
/// run_task() matches against Config and runs the corresponding method Variant(task) => task.run_task()
///
/// # Arguments
///
/// `&self` reference to Config enum
///
/// # Errors
///
/// - if Variant(task) => task.run_task() errors
fn run_task(&self) -> Result<(), io::Error> {
match self {
Config::Organize(task) => task.run_task(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
/// verifies Config::new() works correctly with valid arguments passed in
///
/// # Arguments
///
/// None
///
/// # Errors
///
/// - Config::new() doesnt error if args does not contain a task
#[test]
fn config_new_organize_with_valid_args() {
// args iterator
let args_1 = [String::from("./src"), String::from("./src/organize")].into_iter();
let organize_task = organize::OrganizeTask::new(args_1).unwrap();
// args iterator
let args_2 = [
String::from("foo"),
String::from("organize"),
String::from("./src"),
String::from("./src/organize"),
]
.into_iter();
assert_eq!(Config::new(args_2), Ok(Config::Organize(organize_task)))
}
/// verifies Config::new() errors if args does contain a task
///
/// # Arguments
///
/// None
///
/// # Errors
///
/// - Config::new() doesnt error if args does not contain a task
#[test]
fn config_new_no_task() {
// args iterator
let args = [String::from("foo")].into_iter();
assert!(Config::new(args).is_err());
}
/// verifies Config::new() errors if an invalid task is requested
///
/// # Arguments
///
/// None
///
/// # Errors
///
/// - Config::new() doesnt error if an undefined task is requested
#[test]
fn config_new_invalid_task() {
// args iterator
let args = [String::from("foo"), String::from("bar")].into_iter();
assert!(Config::new(args).is_err());
}
}