devrc/tasks/
arguments.rs

1use indexmap::IndexMap;
2
3use crate::{
4    devrcfile::Devrcfile,
5    errors::{DevrcError, DevrcResult},
6};
7
8use super::{params::ParamValue, TaskKind};
9
10pub type TaskArguments = IndexMap<String, (String, ParamValue)>;
11
12pub fn strip_arg_name(input: String, param_name: &str) -> DevrcResult<String> {
13    let prefix = format!("{:}=", param_name);
14
15    if input.starts_with(&prefix) {
16        Ok(input
17            .strip_prefix(&prefix)
18            .ok_or(DevrcError::TaskArgumentsParsingError)?
19            .to_string())
20    } else {
21        Ok(input)
22    }
23}
24
25// Try to guess is value argument or taskname
26pub fn is_argument(devrcfile: &Devrcfile, value: &str) -> bool {
27    match devrcfile.find_task(value) {
28        Ok(_) => value.contains(' ') || value.contains('='),
29        Err(_) => true,
30    }
31}
32
33pub fn extract_task_args(
34    task: &TaskKind,
35    parts: &[String],
36    devrcfile: &Devrcfile,
37) -> DevrcResult<(usize, TaskArguments)> {
38    let params = task.get_parameters(parts)?;
39
40    let mut arguments: TaskArguments = indexmap::IndexMap::new();
41
42    let mut taken_arguments_counter = 0;
43    for (idx, (key, value)) in params.iter().enumerate() {
44        match value {
45            ParamValue::Required => {
46                if let Some(value) = parts.get(idx) {
47                    taken_arguments_counter += 1;
48                    arguments.insert(
49                        key.to_string(),
50                        (
51                            strip_arg_name(value.to_string(), key)?,
52                            ParamValue::Required,
53                        ),
54                    )
55                } else {
56                    return Err(DevrcError::NotEnouthArguments);
57                }
58            }
59            ParamValue::Default(default) => {
60                if let Some(value) = parts.get(idx) {
61                    if is_argument(devrcfile, value) {
62                        taken_arguments_counter += 1;
63                        arguments.insert(
64                            key.to_string(),
65                            (
66                                strip_arg_name(value.to_string(), key)?,
67                                ParamValue::Default(default.clone()),
68                            ),
69                        )
70                    } else {
71                        arguments.insert(
72                            key.to_string(),
73                            (default.clone(), ParamValue::Default(default.clone())),
74                        )
75                    }
76                } else {
77                    arguments.insert(
78                        key.to_string(),
79                        (default.clone(), ParamValue::Default(default.clone())),
80                    )
81                }
82            }
83        };
84    }
85
86    Ok((taken_arguments_counter, arguments))
87}
88
89#[cfg(test)]
90mod tests {
91
92    #[test]
93    fn test_name() {}
94}