1use std::str::FromStr;
2
3use crate::{
4 cli_error::{CliError, CliResult},
5 input::{Completor, Input, InputType},
6};
7
8#[derive(Default)]
9pub struct Arg<'a, T: FromStr + Clone> {
10 pub name: String,
11 pub description: Option<String>,
12 pub value: Option<T>,
13 pub completor: Option<Completor<'a>>,
14 pub default_value: Option<T>,
15}
16
17impl<'a, T> Arg<'a, T>
18where
19 T: FromStr + Clone,
20{
21 pub fn name(name: &str) -> Self {
22 Self {
23 name: name.to_string(),
24 description: None,
25 value: None,
26 completor: None,
27 default_value: None,
28 }
29 }
30
31 pub fn default(mut self, default: T) -> Self {
32 self.default_value = Some(default);
33 self
34 }
35
36 pub fn description(mut self, description: &str) -> Self {
37 self.description = Some(description.to_string());
38 self
39 }
40
41 pub fn get(&self) -> T {
42 self.value
43 .clone()
44 .unwrap_or_else(|| self.default_value.clone().unwrap())
45 }
46
47 pub fn completor<F>(mut self, completor: F) -> Self
48 where
49 F: FnMut(&str) -> CliResult<Vec<String>> + 'a,
50 {
51 self.completor = Some(Box::new(completor));
52 self
53 }
54}
55
56impl<'a> Arg<'a, String> {
57 pub fn str(name: &str) -> Self {
58 Self::name(name)
59 }
60}
61
62impl<'a> Arg<'a, i32> {
63 pub fn i32(name: &str) -> Self {
64 Self::name(name)
65 }
66}
67
68impl<'a, T: FromStr + Clone> Input for Arg<'a, T> {
69 fn parse(&mut self, token: &str) -> CliResult<bool> {
70 if token.len() > 2 && &token[0..1] == "-" && &token[0..2] == "--" {
71 return Err(CliError::from(format!(
72 "unexpected flag \"{}\" found while looking for argument \"{}\"",
73 token, self.name
74 )));
75 }
76 self.value = Some(token.parse().map_err(|_| {
77 CliError::from(format!("{} cannot be parsed for {}.", token, self.name))
78 })?);
79
80 Ok(true)
81 }
82
83 fn display_name(&self) -> String {
84 self.name.clone()
85 }
86
87 fn type_name(&self) -> InputType {
88 InputType::Arg
89 }
90
91 fn parsed(&self) -> bool {
92 self.value.is_some()
93 }
94
95 fn complete(&mut self, value: &str) -> CliResult<Vec<String>> {
96 if let Some(completor) = &mut self.completor {
97 completor(value)
98 } else {
99 Ok(vec![])
100 }
101 }
102
103 fn is_bool_flag(&self) -> bool {
104 false
105 }
106
107 fn description(&self) -> Option<String> {
108 self.description.clone()
109 }
110
111 fn has_default(&self) -> bool {
112 self.default_value.is_some()
113 }
114}