cull-gmail 0.1.8

Cull emails from a gmail account using the gmail API
Documentation
use std::{env, fmt::Display, path::PathBuf};

use lazy_regex::{Lazy, Regex, lazy_regex};

static ROOT_CONFIG: Lazy<Regex> = lazy_regex!(r"^(?P<class>[hrc]):(?P<path>.+)$");

#[derive(Debug, Default, Clone)]
pub enum RootBase {
    #[default]
    None,
    Crate,
    Home,
    Root,
}

impl Display for RootBase {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            RootBase::None => write!(f, ""),
            RootBase::Crate => write!(f, "c:"),
            RootBase::Home => write!(f, "h:"),
            RootBase::Root => write!(f, "r:"),
        }
    }
}

impl RootBase {
    fn path(&self) -> PathBuf {
        match self {
            RootBase::None => PathBuf::new(),
            RootBase::Crate => PathBuf::new(),
            RootBase::Home => env::home_dir().unwrap_or_default(),
            RootBase::Root => PathBuf::from("/"),
        }
    }
}

#[derive(Debug, Default, Clone)]
pub struct ConfigRoot {
    root: RootBase,
    path: String,
}

impl Display for ConfigRoot {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}{}", self.root, self.path)
    }
}

impl ConfigRoot {
    pub fn parse(s: &str) -> Self {
        log::debug!("parsing the string `{s}`");
        let Some(captures) = ROOT_CONFIG.captures(s) else {
            return ConfigRoot {
                root: RootBase::None,
                path: "".to_string(),
            };
        };
        log::debug!("found captures `{captures:?}`");

        let path = String::from(if let Some(p) = captures.name("path") {
            p.as_str()
        } else {
            ""
        });
        log::debug!("set the path to `{path}`");

        let class = if let Some(c) = captures.name("class") {
            c.as_str()
        } else {
            ""
        };
        log::debug!("found the class `{class:?}`");

        let root = match class {
            "c" => RootBase::Crate,
            "h" => RootBase::Home,
            "r" => RootBase::Root,
            "" => RootBase::None,
            _ => unreachable!(),
        };

        ConfigRoot { root, path }
    }

    pub fn set_root_base(&mut self, root: &RootBase) {
        self.root = root.to_owned();
    }

    pub fn set_path(&mut self, path: &str) {
        self.path = path.to_string();
    }

    pub fn full_path(&self) -> PathBuf {
        self.root.path().join(&self.path)
    }
}

#[cfg(test)]
mod tests {
    use std::env;

    use super::*;

    use crate::test_utils::get_test_logger;

    #[test]
    fn test_parse_to_home() {
        get_test_logger();
        let input = "h:.cull-gmail".to_string();
        log::debug!("Input set to: `{input}`");
        let dir_part = input[2..].to_string();

        let user_home = env::home_dir().unwrap();

        let expected = user_home.join(dir_part).display().to_string();

        let output = ConfigRoot::parse(&input);
        log::debug!("Output set to: `{output:?}`");

        assert_eq!(expected, output.full_path().to_string_lossy().to_string());
    }

    #[test]
    fn test_parse_to_root() {
        get_test_logger();
        let input = "r:.cull-gmail".to_string();
        log::debug!("Input set to: `{input}`");
        let dir_part = input[2..].to_string();

        let expected = format!("/{dir_part}");

        let output = ConfigRoot::parse(&input);
        log::debug!("Output set to: `{output:?}`");

        assert_eq!(expected, output.full_path().to_string_lossy().to_string());
    }

    #[test]
    fn test_parse_to_crate() {
        get_test_logger();
        let input = "c:.cull-gmail".to_string();
        log::debug!("Input set to: `{input}`");
        let expected = input[2..].to_string();

        let output = ConfigRoot::parse(&input);
        log::debug!("Output set to: `{output:?}`");

        assert_eq!(expected, output.full_path().to_string_lossy().to_string());
    }

    #[test]
    fn test_parse_to_none() {
        get_test_logger();
        let input = ".cull-gmail".to_string();
        log::debug!("Input set to: `{input}`");

        let expected = "".to_string();

        let output = ConfigRoot::parse(&input);
        log::debug!("Output set to: `{output:?}`");

        assert_eq!(expected, output.full_path().to_string_lossy().to_string());
    }
}