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 singular_names = ["lookup-files", "ignore-globs"];
80    let use_singular = singular_names.contains(&name);
81
82    let mut names: Vec<String> = vec![name.to_string()];
83    if use_singular {
84        if let Some(singular) = name.strip_suffix('s') {
85            names.push(singular.to_string());
86        }
87    }
88
89    let mut values = Vec::new();
90
91    let mut i = 0;
92    while i < args.len() {
93        let arg = &args[i];
94        for n in &names {
95            if arg == &format!("--{n}") {
96                if let Some(next) = args.get(i + 1) {
97                    if !next.starts_with('-') {
98                        values.extend(split_list(next));
99                        i += 1;
100                    }
101                }
102            } else if let Some(rest) = arg.strip_prefix(&format!("--{n}=")) {
103                values.extend(split_list(rest));
104            }
105        }
106        i += 1;
107    }
108
109    if !values.is_empty() {
110        return Some(T::from(values));
111    }
112
113    if let Some(v) = env.get(env_key) {
114        let env_values = split_list(v);
115        if !env_values.is_empty() {
116            return Some(T::from(env_values));
117        }
118    }
119
120    default
121}
122
123pub fn flag_enum<T: Clone + Default>(
124    args: &[String],
125    env: &HashMap<String, String>,
126    name: &str,
127    env_key: &str,
128    cli_name: Option<&str>,
129    normalizer: fn(Option<&str>) -> Option<T>,
130    default: T,
131) -> T {
132    let cli_name = cli_name.unwrap_or(name);
133
134    if let Some(cli_val) = get_arg_value(args, cli_name) {
135        if let Some(normalized) = normalizer(Some(&cli_val)) {
136            return normalized;
137        }
138    }
139
140    if let Some(v) = env.get(env_key) {
141        if let Some(normalized) = normalizer(Some(v.as_str())) {
142            return normalized;
143        }
144    }
145
146    default
147}
148
149pub fn flag_usize(
150    args: &[String],
151    env: &HashMap<String, String>,
152    name: &str,
153    env_key: &str,
154    default: usize,
155) -> usize {
156    let arg_value = get_arg_value(args, name);
157    if let Some(v) = parse_optional_int(arg_value.as_deref()) {
158        return v.max(0) as usize;
159    }
160
161    if let Some(v) = env.get(env_key) {
162        if let Some(n) = parse_optional_int(Some(v)) {
163            return n.max(0) as usize;
164        }
165    }
166
167    default
168}