From b17e72e6f35978313a43b9d02a5c1db02475ddaf Mon Sep 17 00:00:00 2001 From: Jeremiah Russell Date: Thu, 16 Oct 2025 11:00:25 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(client=5Fconfig):=20add=20conf?= =?UTF-8?q?ig=20root=20parsing=20with=20regex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - introduce regex-based parsing for config root strings - support 'h', 'r', and 'c' prefixes for home, root, and crate paths - add tests for parsing different config root types --- src/client_config/config_root.rs | 93 ++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 9 deletions(-) diff --git a/src/client_config/config_root.rs b/src/client_config/config_root.rs index cb44274..3a25c4e 100644 --- a/src/client_config/config_root.rs +++ b/src/client_config/config_root.rs @@ -1,5 +1,9 @@ use std::{env, fmt::Display}; +use lazy_regex::{Lazy, Regex, lazy_regex}; + +static ROOT_CONFIG: Lazy = lazy_regex!(r"^(?P[hrc]):(?P.+)$"); + #[derive(Debug, Default)] pub enum ConfigRoot { #[default] @@ -28,16 +32,87 @@ impl Display for ConfigRoot { impl ConfigRoot { pub fn parse(s: &str) -> Self { - if !s.is_empty() { - match s.chars().nth(0) { - Some('h') => ConfigRoot::Home(s.to_string()), - Some('r') => ConfigRoot::Root(s.to_string()), - Some('c') => ConfigRoot::Crate(s.to_string()), - Some(_) => ConfigRoot::Crate(s.to_string()), - None => ConfigRoot::None, - } + log::debug!("parsing the string `{s}`"); + let Some(captures) = ROOT_CONFIG.captures(s) else { + return ConfigRoot::None; + }; + log::debug!("found captures `{captures:?}`"); + + let path = String::from(if let Some(p) = captures.name("path") { + p.as_str() } else { - ConfigRoot::None + "" + }); + log::debug!("set the path to `{path}`"); + + let Some(class) = captures.name("class") else { + return ConfigRoot::None; + }; + log::debug!("found the class `{class:?}`"); + + match class.as_str() { + "h" => ConfigRoot::Home(path), + "r" => ConfigRoot::Root(path), + "c" => ConfigRoot::Crate(path), + _ => unreachable!(), } } } + +enum ConfigRootError {} + +#[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(); + + assert_eq!(expected, ConfigRoot::parse(&input).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}"); + + assert_eq!(expected, ConfigRoot::parse(&input).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(); + + assert_eq!(expected, ConfigRoot::parse(&input).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(); + + assert_eq!(expected, ConfigRoot::parse(&input).to_string()); + } +}