1use gitkraft_core::{is_system_name, SYSTEM_THEME_NAME, THEME_NAMES};
4
5pub fn theme_names() -> Vec<&'static str> {
7 std::iter::once(SYSTEM_THEME_NAME)
8 .chain(THEME_NAMES.iter().copied())
9 .collect()
10}
11
12pub fn resolve_theme(name: &str) -> Option<&'static str> {
15 if is_system_name(name) {
16 return Some(SYSTEM_THEME_NAME);
17 }
18 THEME_NAMES
19 .iter()
20 .copied()
21 .find(|n| n.eq_ignore_ascii_case(name.trim()))
22}
23
24#[derive(Debug, Default, PartialEq, Eq)]
26pub struct Cli {
27 pub repo_path: Option<String>,
28 pub theme: Option<String>,
29 pub list_themes: bool,
30}
31
32pub fn parse_args<I: IntoIterator<Item = String>>(args: I) -> Result<Cli, String> {
34 let mut cli = Cli::default();
35 let mut it = args.into_iter();
36 while let Some(a) = it.next() {
37 if a == "--list-themes" {
38 cli.list_themes = true;
39 } else if a == "--theme" {
40 cli.theme = Some(it.next().ok_or("--theme requires a value")?);
41 } else if let Some(v) = a.strip_prefix("--theme=") {
42 cli.theme = Some(v.to_string());
43 } else if a.starts_with("--") {
44 return Err(format!("unknown option '{a}'"));
45 } else if cli.repo_path.is_none() {
46 cli.repo_path = Some(a);
47 }
48 }
49 Ok(cli)
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 fn p(a: &[&str]) -> Result<Cli, String> {
57 parse_args(a.iter().map(|s| s.to_string()))
58 }
59
60 #[test]
61 fn names_start_with_system_and_cover_all_presets() {
62 let n = theme_names();
63 assert_eq!(n[0], "System");
64 assert_eq!(n.len(), gitkraft_core::THEME_COUNT + 1);
65 }
66
67 #[test]
68 fn resolve_is_case_insensitive() {
69 assert_eq!(resolve_theme("system"), Some("System"));
70 assert_eq!(resolve_theme("dracula"), Some("Dracula"));
71 assert_eq!(resolve_theme("nope"), None);
72 }
73
74 #[test]
75 fn parses_flags_and_repo() {
76 assert_eq!(p(&[]).unwrap(), Cli::default());
77 let c = p(&["/tmp/r", "--theme", "Nord"]).unwrap();
78 assert_eq!(c.repo_path.as_deref(), Some("/tmp/r"));
79 assert_eq!(c.theme.as_deref(), Some("Nord"));
80 assert_eq!(
81 p(&["--theme=System"]).unwrap().theme.as_deref(),
82 Some("System")
83 );
84 assert!(p(&["--list-themes"]).unwrap().list_themes);
85 assert!(p(&["--theme"]).is_err());
86 assert!(p(&["--bogus"]).is_err());
87 }
88}