rustless 0.10.0

Rustless is a REST-like API micro-framework for Rust.
Documentation
use regex;
use server::mime;

lazy_static! {
    static ref MEDIA_REGEX: regex::Regex = regex::Regex::new(r"vnd\.(?P<vendor>[a-zA-Z_-]+)(?:\.(?P<version>[a-zA-Z0-9]+)(?:\.(?P<param>[a-zA-Z0-9]+))?)?(?:\+(?P<format>[a-zA-Z0-9]+))?").unwrap();
}

pub fn is_json(mime: &mime::Mime) -> bool {
    match mime {
        &mime::Mime(mime::TopLevel::Application, mime::SubLevel::Json, _) => true,
        _ => false
    }
}

pub fn is_urlencoded(mime: &mime::Mime) -> bool {
    match mime {
        &mime::Mime(mime::TopLevel::Application, mime::SubLevel::WwwFormUrlEncoded, _) => true,
        _ => false
    }
}

pub fn is_form_data(mime: &mime::Mime) -> bool {
    match mime {
        &mime::Mime(mime::TopLevel::Multipart, mime::SubLevel::FormData, _) => true,
        _ => false
    }
}

#[derive(Debug)]
pub enum Format {
    JsonFormat,
    PlainTextFormat,
    OtherFormat(mime::Mime)
}

impl Format {
    pub fn from_mime(mime: &mime::Mime) -> Format {
        match mime {
            &mime::Mime(mime::TopLevel::Text, mime::SubLevel::Plain, _) => Format::PlainTextFormat,
            &mime::Mime(mime::TopLevel::Application, mime::SubLevel::Json, _) => Format::JsonFormat,
            _ => Format::OtherFormat(mime.clone())
        }
    }
}

pub struct Media {
    pub vendor: String,
    pub version: Option<String>,
    pub param: Option<String>,
    pub format: Format
}

impl Media {

    pub fn default() -> Media {
        Media::from_mime(&mime::Mime(mime::TopLevel::Text, mime::SubLevel::Plain, vec![]))
    }

    pub fn from_mime(mime: &mime::Mime) -> Media {
        Media {
            vendor: "default".to_string(),
            version: None,
            param: None,
            format: Format::from_mime(mime)
        }
    }

    pub fn from_vendor(mime: &mime::Mime) -> Option<Media> {
        match mime {
            &mime::Mime(mime::TopLevel::Application, mime::SubLevel::Ext(ref ext), _) => {
                match MEDIA_REGEX.captures(&ext) {
                    Some(captures) => {
                        let vendor = captures.name("vendor");
                        let version = captures.name("version").map(|s| s.to_string());
                        let param = captures.name("param").map(|s| s.to_string());
                        let format_str = captures.name("format").map(|s| s.to_string());

                        let format = match format_str {
                            Some(format) => if &format == "json" { Format::JsonFormat }
                                            else if &format == "txt" { Format::PlainTextFormat }
                                            else { Format::from_mime(mime) },
                            None => Format::from_mime(mime)
                        };

                        Some(Media {
                            vendor: vendor.unwrap().to_string(),
                            version: version,
                            param: param,
                            format: format
                        })
                    },
                    None => None
                }
            }
            _ => None
        }
    }
}

#[test]
fn asset_regexp() {
    let captures = MEDIA_REGEX.captures("application/vnd.github.v3.raw+json").unwrap();
    assert_eq!(captures.name("vendor").unwrap(), "github");
    assert_eq!(captures.name("version").unwrap(), "v3");
    assert_eq!(captures.name("param").unwrap(), "raw");
    assert_eq!(captures.name("format").unwrap(), "json");

    let captures = MEDIA_REGEX.captures("application/vnd.github.v3+json").unwrap();
    assert_eq!(captures.name("vendor").unwrap(), "github");
    assert_eq!(captures.name("version").unwrap(), "v3");
    assert_eq!(captures.name("param"), None);
    assert_eq!(captures.name("format").unwrap(), "json");

    let captures = MEDIA_REGEX.captures("application/vnd.github+json").unwrap();
    assert_eq!(captures.name("vendor").unwrap(), "github");
    assert_eq!(captures.name("version"), None);
    assert_eq!(captures.name("param"), None);
    assert_eq!(captures.name("format").unwrap(), "json");

    let captures = MEDIA_REGEX.captures("application/vnd.github").unwrap();
    assert_eq!(captures.name("vendor").unwrap(), "github");
    assert_eq!(captures.name("version"), None);
    assert_eq!(captures.name("param"), None);
    assert_eq!(captures.name("format"), None);

    let captures = MEDIA_REGEX.captures("application/vnd");
    assert!(captures.is_none());
}

#[test]
fn assert_media() {

    match Media::from_mime(&"application/json".parse().unwrap()).format {
        Format::JsonFormat => (),
        _ => panic!("Wrong format")
    }

    match Media::from_mime(&"text/plain".parse().unwrap()).format {
        Format::PlainTextFormat => (),
        _ => panic!("Wrong format")
    }

    match Media::from_mime(&"application/octet-stream".parse().unwrap()).format {
        Format::OtherFormat(_) => (),
        _ => panic!("Wrong format")
    }

}