pythonic 0.3.0

pythonic is a Rust AST builder that generates Python
Documentation
use std::fmt::{Display, Formatter, Result};

#[derive(Debug, Clone)]
pub enum Argument {
    FunctionDefinition {
        name: String,
        default: Option<String>,
        help: Option<String>,
        arg_type: Option<String>
    },
    Variable ( String ),
    Unnamed ( String )
}

#[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::unnamed("world");
            assert_eq!("\"world\"", format!("{}", arg));
        }
    }

    mod function_argument {
        use Argument;
        #[test]
        fn it_prints_an_argument() {
            let arg = Argument::variable("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::FunctionDefinition {
            name: name.to_string(),
            default: default.map(|s| s.to_string()),
            arg_type: arg_type.map(|s| s.to_string()),
            help: help.map(|s| s.to_string())
        }
    }

    // pub fn bare<T: Display>(value: T) -> Argument {
    //     Argument::unnamed(value)
    // }

    pub fn unnamed<T: Display>(value: T) -> Argument {
        Argument::Unnamed(value.to_string())
    }

    // pub fn input<T: Display>(name: T) -> Argument {
    //     Argument::variable(name)
    // }

    pub fn variable<T: Display>(name: T) -> Argument {
        Argument::Variable (name.to_string())
    }

    pub fn has_help(&self) -> bool {
        match self {
            &Argument::FunctionDefinition{ref help, .. } => help.is_some(),
            _ => false,
        }
    }

    pub fn help_string(&self) -> Option<String> {
        match self {
            &Argument::FunctionDefinition{ref help,  ref name, ..} => {
                let mut formatted_help = format!(":param {}:", name);

                if let &Some(ref help_str) = help {
                    formatted_help.push_str(&format!(" {}", help_str)[..]);
                    Some(formatted_help)
                } else {
                    None
                }
            },
            _ => None,
        }
    }

    pub fn type_string(&self) -> Option<String> {
        match self {
            &Argument::FunctionDefinition{ref arg_type, ref name, ..} => {
                let mut help = format!(":type {}:", name);
                if let &Some(ref t) = arg_type {
                    help.push_str(&format!(" {}", t)[..]);
                    Some(help)
                } else {
                    None
                }
            },
            _ => None,
        }
    }
}

impl Display for Argument {
    fn fmt(&self, f: &mut Formatter) -> Result {
        let mut output = String::new();
        match self {
            &Argument::FunctionDefinition{ref name, ref default, ..} => {
                output.push_str(&name[..]);
                if let &Some(ref default) = default {
                    output.push_str(&format!("={}", default));
                }
            },
            &Argument::Unnamed(ref value) => {
                output.push_str(&format!("\"{}\"", value)[..]);
            },
            &Argument::Variable(ref name) => {
                output.push_str(&format!("{}", name)[..]);
            },
        }
        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)
    }
}