1pub mod errors;
2
3#[cfg(test)]
4pub mod tests;
5
6use crate::lexing::{ Token, TokenKind };
7
8#[derive(Debug, Clone)]
15#[allow(dead_code)]
16pub struct Argument {
17 name: Option<String>,
18 value: Option<String>,
19 position: Option<usize>,
20}
21
22impl Argument {
23 pub fn get_name(&self) -> Option<&str> {
24 self.name.as_deref()
25 }
26
27 pub fn get_value(&self) -> Option<&str> {
28 self.value.as_deref()
29 }
30
31 pub fn get_position(&self) -> Option<usize> {
32 self.position
33 }
34}
35
36pub fn parse(mut input: Vec<Token>) -> Vec<Argument> {
37 let mut arguments: Vec<Argument> = Vec::new();
38 while !input.is_empty() {
39 let result = parse_argument(
40 &mut input,
41 arguments
42 .iter()
43 .filter(|it| it.position.is_some())
44 .count()
45 );
46
47 arguments.push(result);
48 }
49
50 arguments
51}
52
53fn parse_argument(input: &mut Vec<Token>, positional_count: usize) -> Argument {
54 let token = input.get(0).unwrap();
55 match token.get_kind() {
56 TokenKind::Dash => {
57 input.remove(0);
58 parse_named_argument(input)
59 }
60 _ => parse_positional_argument(input, positional_count),
61 }
62}
63
64fn parse_named_argument(input: &mut Vec<Token>) -> Argument {
65 let key = input.remove(0);
66 if input.is_empty() || *input[0].get_kind() != TokenKind::Equals {
67 return Argument { name: Some(key.get_value().to_string()), value: None, position: None };
68 }
69
70 let _ = input.remove(0);
71
72 let value = input.remove(0);
73
74 Argument {
75 name: Some(key.get_value().clone()),
76 value: Some(value.get_value().clone()),
77 position: None,
78 }
79}
80
81fn parse_positional_argument(input: &mut Vec<Token>, count: usize) -> Argument {
82 let value = input.remove(0);
83
84 Argument {
85 name: None,
86 value: Some(value.get_value().clone()),
87 position: Some(count),
88 }
89}