css_variable_lsp/
flags.rs1use 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}