use std::fmt::{Display, Formatter, Result};
#[derive(Debug, Clone)]
pub struct Argument {
pub name: Option<String>,
pub default: Option<String>,
pub value: Option<String>,
pub arg_type: Option<String>,
pub help: Option<String>,
argument_type: ArgumentType,
}
#[derive(Debug, Clone)]
enum ArgumentType {
FunctionDefinition,
FunctionCall {
bare: bool,
},
}
#[cfg(test)]
mod tests {
mod definition {
use Argument;
#[test]
fn it_prints_an_argument_with_no_default() {
let arg = Argument::new("test", None, None, None);
assert_eq!("test", format!("{}", arg));
}
#[test]
fn it_prints_an_argument_with_a_default() {
let arg = Argument::new("test", Some(r#""value""#), None, None);
assert_eq!(r#"test="value""#, format!("{}", arg));
}
}
mod bare_argument {
use Argument;
#[test]
fn it_prints_an_argument() {
let arg = Argument::bare("world");
assert_eq!("\"world\"", format!("{}", arg));
}
}
mod function_argument {
use Argument;
#[test]
fn it_prints_an_argument() {
let arg = Argument::input("name");
assert_eq!("name", format!("{}", arg));
}
}
}
impl Argument {
pub fn new<T: Display>(name: T,
default: Option<T>,
arg_type: Option<T>,
help: Option<T>)
-> Argument {
Argument {
name: Some(name.to_string()),
default: default.map(|s| s.to_string()),
value: None,
arg_type: arg_type.map(|s| s.to_string()),
help: help.map(|s| s.to_string()),
argument_type: ArgumentType::FunctionDefinition,
}
}
pub fn bare<T: Display>(value: T) -> Argument {
Argument {
name: None,
default: None,
value: Some(value.to_string()),
arg_type: None,
help: None,
argument_type: ArgumentType::FunctionCall { bare: true },
}
}
pub fn input<T: Display>(name: T) -> Argument {
Argument {
name: Some(name.to_string()),
default: None,
value: None,
arg_type: None,
help: None,
argument_type: ArgumentType::FunctionCall { bare: false },
}
}
pub fn has_help(&self) -> bool {
self.help.is_some()
}
pub fn help_string(&self) -> String {
if let Some(ref name) = self.name {
let mut help = format!(":param {}:", name);
if let Some(ref help_str) = self.help {
help.push_str(&format!(" {}", help_str)[..]);
}
help
} else {
String::new()
}
}
pub fn type_string(&self) -> String {
if let Some(ref name) = self.name {
let mut help = format!(":type {}:", name);
if let Some(ref t) = self.arg_type {
help.push_str(&format!(" {}", t)[..]);
}
help
} else {
String::new()
}
}
}
impl Display for Argument {
fn fmt(&self, f: &mut Formatter) -> Result {
let mut output = String::new();
match self.argument_type {
ArgumentType::FunctionDefinition => {
if let Some(ref name) = self.name {
output.push_str(&name[..]);
} else {
panic!("You must provide a name for a function definition's argument")
}
if let Some(ref default) = self.default {
output.push_str(&format!("={}", default)[..]);
}
}
ArgumentType::FunctionCall { bare: true } => {
if let Some(ref value) = self.value {
output.push_str(&format!("\"{}\"", value)[..]);
} else {
panic!("You must provide a value for a bare argument")
}
}
ArgumentType::FunctionCall { bare: false } => {
if let Some(ref name) = self.name {
output.push_str(&format!("{}", name)[..]);
} else {
panic!("You must provide a name for a function call")
}
}
}
write!(f, "{}", output)
}
}
#[derive(Debug, Clone)]
pub struct KeywordArgument {
pub keyword: String,
pub argument: String,
}
impl KeywordArgument {
pub fn new<T: Display>(name: T, arg: T) -> KeywordArgument {
KeywordArgument {
keyword: name.to_string(),
argument: arg.to_string(),
}
}
}
impl Display for KeywordArgument {
fn fmt(&self, f: &mut Formatter) -> Result {
write!(f, "{}={}", self.keyword, self.argument)
}
}