pythonic/
argument.rs

1use std::fmt::{Display, Formatter, Result};
2
3#[derive(Debug, Clone)]
4pub enum Argument {
5    FunctionDefinition {
6        name: String,
7        default: Option<String>,
8        help: Option<String>,
9        arg_type: Option<String>
10    },
11    Variable ( String ),
12    Unnamed ( String )
13}
14
15#[cfg(test)]
16mod tests {
17    mod definition {
18        use Argument;
19
20        #[test]
21        fn it_prints_an_argument_with_no_default() {
22            let arg = Argument::new("test", None, None, None);
23            assert_eq!("test", format!("{}", arg));
24        }
25
26        #[test]
27        fn it_prints_an_argument_with_a_default() {
28            let arg = Argument::new("test", Some(r#""value""#), None, None);
29            assert_eq!(r#"test="value""#, format!("{}", arg));
30        }
31    }
32
33    mod bare_argument {
34        use Argument;
35        #[test]
36        fn it_prints_an_argument() {
37            let arg = Argument::unnamed("world");
38            assert_eq!("\"world\"", format!("{}", arg));
39        }
40    }
41
42    mod function_argument {
43        use Argument;
44        #[test]
45        fn it_prints_an_argument() {
46            let arg = Argument::variable("name");
47            assert_eq!("name", format!("{}", arg));
48        }
49    }
50
51}
52
53impl Argument {
54    pub fn new<T: Display>(name: T,
55                           default: Option<T>,
56                           arg_type: Option<T>,
57                           help: Option<T>)
58                           -> Argument {
59        Argument::FunctionDefinition {
60            name: name.to_string(),
61            default: default.map(|s| s.to_string()),
62            arg_type: arg_type.map(|s| s.to_string()),
63            help: help.map(|s| s.to_string())
64        }
65    }
66
67    // pub fn bare<T: Display>(value: T) -> Argument {
68    //     Argument::unnamed(value)
69    // }
70
71    pub fn unnamed<T: Display>(value: T) -> Argument {
72        Argument::Unnamed(value.to_string())
73    }
74
75    // pub fn input<T: Display>(name: T) -> Argument {
76    //     Argument::variable(name)
77    // }
78
79    pub fn variable<T: Display>(name: T) -> Argument {
80        Argument::Variable (name.to_string())
81    }
82
83    pub fn has_help(&self) -> bool {
84        match self {
85            &Argument::FunctionDefinition{ref help, .. } => help.is_some(),
86            _ => false,
87        }
88    }
89
90    pub fn help_string(&self) -> Option<String> {
91        match self {
92            &Argument::FunctionDefinition{ref help,  ref name, ..} => {
93                let mut formatted_help = format!(":param {}:", name);
94
95                if let &Some(ref help_str) = help {
96                    formatted_help.push_str(&format!(" {}", help_str)[..]);
97                    Some(formatted_help)
98                } else {
99                    None
100                }
101            },
102            _ => None,
103        }
104    }
105
106    pub fn type_string(&self) -> Option<String> {
107        match self {
108            &Argument::FunctionDefinition{ref arg_type, ref name, ..} => {
109                let mut help = format!(":type {}:", name);
110                if let &Some(ref t) = arg_type {
111                    help.push_str(&format!(" {}", t)[..]);
112                    Some(help)
113                } else {
114                    None
115                }
116            },
117            _ => None,
118        }
119    }
120}
121
122impl Display for Argument {
123    fn fmt(&self, f: &mut Formatter) -> Result {
124        let mut output = String::new();
125        match self {
126            &Argument::FunctionDefinition{ref name, ref default, ..} => {
127                output.push_str(&name[..]);
128                if let &Some(ref default) = default {
129                    output.push_str(&format!("={}", default));
130                }
131            },
132            &Argument::Unnamed(ref value) => {
133                output.push_str(&format!("\"{}\"", value)[..]);
134            },
135            &Argument::Variable(ref name) => {
136                output.push_str(&format!("{}", name)[..]);
137            },
138        }
139        write!(f, "{}", output)
140    }
141}
142
143#[derive(Debug, Clone)]
144pub struct KeywordArgument {
145    pub keyword: String,
146    pub argument: String,
147}
148
149impl KeywordArgument {
150    pub fn new<T: Display>(name: T, arg: T) -> KeywordArgument {
151        KeywordArgument {
152            keyword: name.to_string(),
153            argument: arg.to_string(),
154        }
155    }
156}
157
158impl Display for KeywordArgument {
159    fn fmt(&self, f: &mut Formatter) -> Result {
160        write!(f, "{}={}", self.keyword, self.argument)
161    }
162}