Skip to main content

css_variable_lsp/
flags.rs

1use std::collections::HashMap;
2
3pub fn get_arg_value(args: &[String], name: &str) -> Option<String> {
4    let flag = format!("--{name}");
5    if let Some(idx) = args.iter().position(|arg| arg == &flag) {
6        if let Some(candidate) = args.get(idx + 1) {
7            if !candidate.starts_with('-') {
8                return Some(candidate.to_string());
9            }
10        }
11        return None;
12    }
13
14    let prefix = format!("{}=", flag);
15    for arg in args {
16        if arg.starts_with(&prefix) {
17            return Some(arg[prefix.len()..].to_string());
18        }
19    }
20    None
21}
22
23pub fn parse_optional_int(value: Option<&str>) -> Option<i64> {
24    let raw = value?.trim();
25    if raw.is_empty() {
26        return None;
27    }
28    raw.parse::<i64>().ok()
29}
30
31pub fn split_list(value: &str) -> Vec<String> {
32    value
33        .split(',')
34        .map(|s| s.trim().to_string())
35        .filter(|s| !s.is_empty())
36        .collect()
37}
38
39pub fn flag_bool(
40    args: &[String],
41    env: &HashMap<String, String>,
42    _name: &str,
43    env_key: &str,
44    cli_disable: &str,
45    default: bool,
46) -> bool {
47    if args.iter().any(|arg| arg == cli_disable) {
48        return false;
49    }
50    if let Some(v) = env.get(env_key) {
51        return v != "0";
52    }
53    default
54}
55
56pub fn flag_bool_simple(
57    args: &[String],
58    env: &HashMap<String, String>,
59    env_key: &str,
60    cli_flag: &str,
61    default: bool,
62) -> bool {
63    if args.iter().any(|arg| arg == cli_flag) {
64        return true;
65    }
66    if let Some(v) = env.get(env_key) {
67        return v != "0";
68    }
69    default
70}
71
72pub fn flag_opt<T: From<Vec<String>>>(
73    args: &[String],
74    env: &HashMap<String, String>,
75    name: &str,
76    env_key: &str,
77    default: Option<T>,
78) -> Option<T> {
79    let mut values = Vec::new();
80
81    let mut i = 0;
82    while i < args.len() {
83        let arg = &args[i];
84        if arg == &format!("--{name}") {
85            if let Some(next) = args.get(i + 1) {
86                if !next.starts_with('-') {
87                    values.extend(split_list(next));
88                    i += 1;
89                }
90            }
91        } else if let Some(rest) = arg.strip_prefix(&format!("--{name}=")) {
92            values.extend(split_list(rest));
93        }
94        i += 1;
95    }
96
97    if !values.is_empty() {
98        return Some(T::from(values));
99    }
100
101    if let Some(v) = env.get(env_key) {
102        let env_values = split_list(v);
103        if !env_values.is_empty() {
104            return Some(T::from(env_values));
105        }
106    }
107
108    default
109}
110
111pub fn flag_enum<T: Clone + Default>(
112    args: &[String],
113    env: &HashMap<String, String>,
114    name: &str,
115    env_key: &str,
116    cli_name: Option<&str>,
117    normalizer: fn(Option<&str>) -> Option<T>,
118    default: T,
119) -> T {
120    let cli_name = cli_name.unwrap_or(name);
121
122    if let Some(cli_val) = get_arg_value(args, cli_name) {
123        if let Some(normalized) = normalizer(Some(&cli_val)) {
124            return normalized;
125        }
126    }
127
128    if let Some(v) = env.get(env_key) {
129        if let Some(normalized) = normalizer(Some(v.as_str())) {
130            return normalized;
131        }
132    }
133
134    default
135}
136
137pub fn flag_usize(
138    args: &[String],
139    env: &HashMap<String, String>,
140    name: &str,
141    env_key: &str,
142    default: usize,
143) -> usize {
144    let arg_value = get_arg_value(args, name);
145    if let Some(v) = parse_optional_int(arg_value.as_deref()) {
146        return v.max(0) as usize;
147    }
148
149    if let Some(v) = env.get(env_key) {
150        if let Some(n) = parse_optional_int(Some(v)) {
151            return n.max(0) as usize;
152        }
153    }
154
155    default
156}