<commit_before>//! # Mime
//!
//! Mime is now Media Type, technically, but `Mime` is more immediately
//! understandable, so the main type here is `Mime`.
//!
//! ## What is Mime?
//!
//! Example mime string: `text/plain;charset=utf-8`
//!
//! ```rust
//! # #[macro_use] extern crate mime;
//! # fn main() {
//! let plain_text: mime::Mime = "text/plain;charset=utf-8".parse().unwrap();
//! assert_eq!(plain_text, mime!(Text/Plain; Charset=Utf8));
//! # }
//! ```

#![doc(html_root_url = "https://hyperium.github.io/mime.rs")]
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(all(features = "nightly", test), feature(test))]

#[macro_use]
extern crate log;

#[cfg(features = "nightly")]
#[cfg(test)]
extern crate test;

use std::ascii::AsciiExt;
use std::fmt;
use std::iter::Enumerate;
use std::str::{FromStr, Chars};

macro_rules! inspect(
    ($s:expr, $t:expr) => ({
        let t = $t;
        trace!("inspect {}: {:?}", $s, t);
        t
    })
);

/// Mime, or Media Type. Encapsulates common registers types.
///
/// Consider that a traditional mime type contains a "top level type",
/// a "sub level type", and 0-N "parameters". And they're all strings.
/// Strings everywhere. Strings mean typos. Rust has type safety. We should
/// use types!
///
/// So, Mime bundles together this data into types so the compiler can catch
/// your typos.
///
/// This improves things so you use match without Strings:
///
/// ```rust
/// use mime::{Mime, TopLevel, SubLevel};
///
/// let mime: Mime = "application/json".parse().unwrap();
///
/// match mime {
///     Mime(TopLevel::Application, SubLevel::Json, _) => println!("matched json!"),
///     _ => ()
/// }
/// ```
#[derive(Clone, PartialEq, Debug)]
pub struct Mime(pub TopLevel, pub SubLevel, pub Vec<Param>);

/// Easily create a Mime without having to import so many enums.
///
/// # Example
///
/// ```
/// # #[macro_use] extern crate mime;
///
/// # fn main() {
/// let json = mime!(Application/Json);
/// let plain = mime!(Text/Plain; Charset=Utf8);
/// let text = mime!(Text/Html; Charset=("bar"), ("baz")=("quux"));
/// let img = mime!(Image/_);
/// # }
/// ```
#[macro_export]
macro_rules! mime {
    ($top:tt / $sub:tt) => (
        mime!($top / $sub;)
    );

    ($top:tt / $sub:tt ; $($attr:tt = $val:tt),*) => (
        $crate::Mime(
            __mime__ident_or_ext!(TopLevel::$top),
            __mime__ident_or_ext!(SubLevel::$sub),
            vec![ $((__mime__ident_or_ext!(Attr::$attr), __mime__ident_or_ext!(Value::$val))),* ]
        )
    );
}

#[doc(hidden)]
#[macro_export]
macro_rules! __mime__ident_or_ext {
    ($enoom:ident::_) => (
        $crate::$enoom::Star
    );
    ($enoom:ident::($inner:expr)) => (
        $crate::$enoom::Ext($inner.to_string())
    );
    ($enoom:ident::$var:ident) => (
        $crate::$enoom::$var
    )
}

macro_rules! enoom {
    (pub enum $en:ident; $ext:ident; $($ty:ident, $text:expr;)*) => (

        #[derive(Clone, Debug)]
        pub enum $en {
            $($ty),*,
            $ext(String)
        }

        impl PartialEq for $en {
            fn eq(&self, other: &$en) -> bool {
                match (self, other) {
                    $( (&$en::$ty, &$en::$ty) => true ),*,
                    (&$en::$ext(ref a), &$en::$ext(ref b)) => a == b,
                    _ => self.to_string() == other.to_string()
                }
            }
        }

        impl fmt::Display for $en {
            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                fmt.write_str(match *self {
                    $($en::$ty => $text),*,
                    $en::$ext(ref s) => s
                })
            }
        }

        impl FromStr for $en {
            type Err = ();
            fn from_str(s: &str) -> Result<$en, ()> {
                Ok(match s {
                    $(_s if _s == $text => $en::$ty),*,
                    s => $en::$ext(inspect!(stringify!($ext), s).to_string())
                })
            }
        }
    )
}

enoom! {
    pub enum TopLevel;
    Ext;
    Star, "*";
    Text, "text";
    Image, "image";
    Audio, "audio";
    Video, "video";
    Application, "application";
    Multipart, "multipart";
    Message, "message";
    Model, "model";
}

enoom! {
    pub enum SubLevel;
    Ext;
    Star, "*";

    // common text/*
    Plain, "plain";
    Html, "html";
    Xml, "xml";
    Javascript, "javascript";
    Css, "css";

    // common application/*
    Json, "json";
    WwwFormUrlEncoded, "x-www-form-urlencoded";

    // multipart/*
    FormData, "form-data";

    // common image/*
    Png, "png";
    Gif, "gif";
    Bmp, "bmp";
    Jpeg, "jpeg";
}

enoom! {
    pub enum Attr;
    Ext;
    Charset, "charset";
    Q, "q";
}

enoom! {
    pub enum Value;
    Ext;
    Utf8, "utf-8";
}

pub type Param = (Attr, Value);

impl fmt::Display for Mime {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let Mime(ref top, ref sub, ref params) = *self;
        try!(write!(fmt, "{}/{}", top, sub));
        fmt_params(params, fmt)
    }
}

impl FromStr for Mime {
    type Err = ();
    fn from_str(raw: &str) -> Result<Mime, ()> {
        let ascii = raw.to_ascii_lowercase(); // lifetimes :(
        let len = ascii.len();
        let mut iter = ascii.chars().enumerate();
        let mut params = vec![];
        // toplevel
        let mut start;
        let mut top;
        loop {
            match inspect!("top iter", iter.next()) {
                Some((0, c)) if is_restricted_name_first_char(c) => (),
                Some((i, c)) if i > 0 && is_restricted_name_char(c) => (),
                Some((i, '/')) if i > 0 => match FromStr::from_str(&ascii[..i]) {
                    Ok(t) => {
                        top = t;
                        start = i + 1;
                        break;
                    }
                    Err(_) => return Err(())
                },
                _ => return Err(()) // EOF and no toplevel is no Mime
            };

        }

        // sublevel
        let mut sub;
        loop {
            match inspect!("sub iter", iter.next()) {
                Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
                Some((i, c)) if i > start && is_restricted_name_char(c) => (),
                Some((i, ';')) if i > start => match FromStr::from_str(&ascii[start..i]) {
                    Ok(s) => {
                        sub = s;
                        start = i + 1;
                        break;
                    }
                    Err(_) => return Err(())
                },
                None => match FromStr::from_str(&ascii[start..]) {
                    Ok(s) => return Ok(Mime(top, s, params)),
                    Err(_) => return Err(())
                },
                _ => return Err(())
            };
        }

        // params
        debug!("starting params, len={}", len);
        loop {
            match inspect!("param", param_from_str(&ascii, &mut iter, start)) {
                Some((p, end)) => {
                    params.push(p);
                    start = end;
                    if start >= len {
                        break;
                    }
                }
                None => break
            }
        }

        Ok(Mime(top, sub, params))
    }
}

fn param_from_str(raw: &str, iter: &mut Enumerate<Chars>, mut start: usize) -> Option<(Param, usize)> {
    let mut attr;
    debug!("param_from_str, start={}", start);
    loop {
        match inspect!("attr iter", iter.next()) {
            Some((i, ' ')) if i == start => start = i + 1,
            Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
            Some((i, c)) if i > start && is_restricted_name_char(c) => (),
            Some((i, '=')) if i > start => match FromStr::from_str(&raw[start..i]) {
                Ok(a) => {
                    attr = inspect!("attr", a);
                    start = i + 1;
                    break;
                },
                Err(_) => return None
            },
            _ => return None
        }
    }
    let mut value;
    // values must be restrict-name-char or "anything goes"
    let mut is_quoted = false;
    loop {
        match inspect!("value iter", iter.next()) {
            Some((i, '"')) if i == start => {
                debug!("quoted");
                is_quoted = true;
                start = i + 1;
            },
            Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
            Some((i, '"')) if i > start && is_quoted => match FromStr::from_str(&raw[start..i]) {
                Ok(v) => {
                    value = v;
                    start = i + 1;
                    break;
                },
                Err(_) => return None
            },
            Some((i, c)) if i > start && is_quoted || is_restricted_name_char(c) => (),
            Some((i, ';')) if i > start => match FromStr::from_str(&raw[start..i]) {
                Ok(v) => {
                    value = v;
                    start = i + 1;
                    break;
                },
                Err(_) => return None
            },
            None => match FromStr::from_str(&raw[start..]) {
                Ok(v) => {
                    value = v;
                    start = raw.len();
                    break;
                },
                Err(_) => return None
            },

            _ => return None
        }
    }

    Some(((attr, value), start))
}

// From [RFC6838](http://tools.ietf.org/html/rfc6838#section-4.2):
//
// > All registered media types MUST be assigned top-level type and
// > subtype names.  The combination of these names serves to uniquely
// > identify the media type, and the subtype name facet (or the absence
// > of one) identifies the registration tree.  Both top-level type and
// > subtype names are case-insensitive.
// >
// > Type and subtype names MUST conform to the following ABNF:
// >
// >     type-name = restricted-name
// >     subtype-name = restricted-name
// >
// >     restricted-name = restricted-name-first *126restricted-name-chars
// >     restricted-name-first  = ALPHA / DIGIT
// >     restricted-name-chars  = ALPHA / DIGIT / "!" / "#" /
// >                              "$" / "&" / "-" / "^" / "_"
// >     restricted-name-chars =/ "." ; Characters before first dot always
// >                                  ; specify a facet name
// >     restricted-name-chars =/ "+" ; Characters after last plus always
// >                                  ; specify a structured syntax suffix
//
fn is_restricted_name_first_char(c: char) -> bool {
    match c {
        'a'...'z' |
        '0'...'9' => true,
        _ => false
    }
}

fn is_restricted_name_char(c: char) -> bool {
    if is_restricted_name_first_char(c) {
        true
    } else {
        match c {
            '!' |
            '#' |
            '$' |
            '&' |
            '-' |
            '^' |
            '.' |
            '+' |
            '_' => true,
            _ => false
        }
    }
}

#[inline]
fn fmt_params(params: &[Param], fmt: &mut fmt::Formatter) -> fmt::Result {
    for param in params.iter() {
        try!(fmt_param(param, fmt));
    }
    Ok(())
}

#[inline]
fn fmt_param(param: &Param, fmt: &mut fmt::Formatter) -> fmt::Result {
    let (ref attr, ref value) = *param;
    write!(fmt, "; {}={}", attr, value)
}

#[cfg(test)]
mod tests {
    use std::str::FromStr;
    #[cfg(features = "nightly")]
    use test::Bencher;

    #[test]
    fn test_mime_show() {
        let mime = mime!(Text/Plain);
        assert_eq!(mime.to_string(), "text/plain".to_string());
        let mime = mime!(Text/Plain; Charset=Utf8);
        assert_eq!(mime.to_string(), "text/plain; charset=utf-8".to_string());
    }

    #[test]
    fn test_mime_from_str() {
        assert_eq!(FromStr::from_str("text/plain"), Ok(mime!(Text/Plain)));
        assert_eq!(FromStr::from_str("TEXT/PLAIN"), Ok(mime!(Text/Plain)));
        assert_eq!(FromStr::from_str("text/plain; charset=utf-8"), Ok(mime!(Text/Plain; Charset=Utf8)));
        assert_eq!(FromStr::from_str("text/plain;charset=\"utf-8\""), Ok(mime!(Text/Plain; Charset=Utf8)));
        assert_eq!(FromStr::from_str("text/plain; charset=utf-8; foo=bar"),
            Ok(mime!(Text/Plain; Charset=Utf8, ("foo")=("bar"))));
    }

    #[cfg(features = "nightly")]
    #[bench]
    fn bench_show(b: &mut Bencher) {
        let mime = mime!(Text/Plain; Charset=Utf8, "foo"="bar");
        b.bytes = mime.to_string().as_bytes().len() as u64;
        b.iter(|| mime.to_string())
    }

    #[cfg(features = "nightly")]
    #[bench]
    fn bench_from_str(b: &mut Bencher) {
        let s = "text/plain; charset=utf-8; foo=bar";
        b.bytes = s.as_bytes().len() as u64;
        b.iter(|| s.parse::<Mime>())
    }
}
<commit_msg>make Mime generic over [Param]<commit_after>//! # Mime
//!
//! Mime is now Media Type, technically, but `Mime` is more immediately
//! understandable, so the main type here is `Mime`.
//!
//! ## What is Mime?
//!
//! Example mime string: `text/plain;charset=utf-8`
//!
//! ```rust
//! # #[macro_use] extern crate mime;
//! # fn main() {
//! let plain_text: mime::Mime = "text/plain;charset=utf-8".parse().unwrap();
//! assert_eq!(plain_text, mime!(Text/Plain; Charset=Utf8));
//! # }
//! ```

#![doc(html_root_url = "https://hyperium.github.io/mime.rs")]
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(all(features = "nightly", test), feature(test))]

#[macro_use]
extern crate log;

#[cfg(features = "nightly")]
#[cfg(test)]
extern crate test;

use std::ascii::AsciiExt;
use std::fmt;
use std::iter::Enumerate;
use std::str::{FromStr, Chars};

macro_rules! inspect(
    ($s:expr, $t:expr) => ({
        let t = $t;
        trace!("inspect {}: {:?}", $s, t);
        t
    })
);

/// Mime, or Media Type. Encapsulates common registers types.
///
/// Consider that a traditional mime type contains a "top level type",
/// a "sub level type", and 0-N "parameters". And they're all strings.
/// Strings everywhere. Strings mean typos. Rust has type safety. We should
/// use types!
///
/// So, Mime bundles together this data into types so the compiler can catch
/// your typos.
///
/// This improves things so you use match without Strings:
///
/// ```rust
/// use mime::{Mime, TopLevel, SubLevel};
///
/// let mime: Mime = "application/json".parse().unwrap();
///
/// match mime {
///     Mime(TopLevel::Application, SubLevel::Json, _) => println!("matched json!"),
///     _ => ()
/// }
/// ```
#[derive(Clone, Debug)]
pub struct Mime<T: AsRef<[Param]> = Vec<Param>>(pub TopLevel, pub SubLevel, pub T);

impl<LHS: AsRef<[Param]>, RHS: AsRef<[Param]>> PartialEq<Mime<RHS>> for Mime<LHS> {
    fn eq(&self, other: &Mime<RHS>) -> bool {
        self.0 == other.0 && self.1 == other.1 && self.2.as_ref() == other.2.as_ref()
    }
}

/// Easily create a Mime without having to import so many enums.
///
/// # Example
///
/// ```
/// # #[macro_use] extern crate mime;
///
/// # fn main() {
/// let json = mime!(Application/Json);
/// let plain = mime!(Text/Plain; Charset=Utf8);
/// let text = mime!(Text/Html; Charset=("bar"), ("baz")=("quux"));
/// let img = mime!(Image/_);
/// # }
/// ```
#[macro_export]
macro_rules! mime {
    ($top:tt / $sub:tt) => (
        mime!($top / $sub;)
    );

    ($top:tt / $sub:tt ; $($attr:tt = $val:tt),*) => (
        $crate::Mime(
            __mime__ident_or_ext!(TopLevel::$top),
            __mime__ident_or_ext!(SubLevel::$sub),
            [ $((__mime__ident_or_ext!(Attr::$attr), __mime__ident_or_ext!(Value::$val))),* ]
        )
    );
}

#[doc(hidden)]
#[macro_export]
macro_rules! __mime__ident_or_ext {
    ($enoom:ident::_) => (
        $crate::$enoom::Star
    );
    ($enoom:ident::($inner:expr)) => (
        $crate::$enoom::Ext($inner.to_string())
    );
    ($enoom:ident::$var:ident) => (
        $crate::$enoom::$var
    )
}

macro_rules! enoom {
    (pub enum $en:ident; $ext:ident; $($ty:ident, $text:expr;)*) => (

        #[derive(Clone, Debug)]
        pub enum $en {
            $($ty),*,
            $ext(String)
        }

        impl PartialEq for $en {
            fn eq(&self, other: &$en) -> bool {
                match (self, other) {
                    $( (&$en::$ty, &$en::$ty) => true ),*,
                    (&$en::$ext(ref a), &$en::$ext(ref b)) => a == b,
                    _ => self.to_string() == other.to_string()
                }
            }
        }

        impl fmt::Display for $en {
            fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                fmt.write_str(match *self {
                    $($en::$ty => $text),*,
                    $en::$ext(ref s) => s
                })
            }
        }

        impl FromStr for $en {
            type Err = ();
            fn from_str(s: &str) -> Result<$en, ()> {
                Ok(match s {
                    $(_s if _s == $text => $en::$ty),*,
                    s => $en::$ext(inspect!(stringify!($ext), s).to_string())
                })
            }
        }
    )
}

enoom! {
    pub enum TopLevel;
    Ext;
    Star, "*";
    Text, "text";
    Image, "image";
    Audio, "audio";
    Video, "video";
    Application, "application";
    Multipart, "multipart";
    Message, "message";
    Model, "model";
}

enoom! {
    pub enum SubLevel;
    Ext;
    Star, "*";

    // common text/*
    Plain, "plain";
    Html, "html";
    Xml, "xml";
    Javascript, "javascript";
    Css, "css";

    // common application/*
    Json, "json";
    WwwFormUrlEncoded, "x-www-form-urlencoded";

    // multipart/*
    FormData, "form-data";

    // common image/*
    Png, "png";
    Gif, "gif";
    Bmp, "bmp";
    Jpeg, "jpeg";
}

enoom! {
    pub enum Attr;
    Ext;
    Charset, "charset";
    Q, "q";
}

enoom! {
    pub enum Value;
    Ext;
    Utf8, "utf-8";
}

pub type Param = (Attr, Value);

impl<T: AsRef<[Param]>> fmt::Display for Mime<T> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let Mime(ref top, ref sub, ref params) = *self;
        try!(write!(fmt, "{}/{}", top, sub));
        fmt_params(params.as_ref(), fmt)
    }
}

impl FromStr for Mime {
    type Err = ();
    fn from_str(raw: &str) -> Result<Mime, ()> {
        let ascii = raw.to_ascii_lowercase(); // lifetimes :(
        let len = ascii.len();
        let mut iter = ascii.chars().enumerate();
        let mut params = vec![];
        // toplevel
        let mut start;
        let mut top;
        loop {
            match inspect!("top iter", iter.next()) {
                Some((0, c)) if is_restricted_name_first_char(c) => (),
                Some((i, c)) if i > 0 && is_restricted_name_char(c) => (),
                Some((i, '/')) if i > 0 => match FromStr::from_str(&ascii[..i]) {
                    Ok(t) => {
                        top = t;
                        start = i + 1;
                        break;
                    }
                    Err(_) => return Err(())
                },
                _ => return Err(()) // EOF and no toplevel is no Mime
            };

        }

        // sublevel
        let mut sub;
        loop {
            match inspect!("sub iter", iter.next()) {
                Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
                Some((i, c)) if i > start && is_restricted_name_char(c) => (),
                Some((i, ';')) if i > start => match FromStr::from_str(&ascii[start..i]) {
                    Ok(s) => {
                        sub = s;
                        start = i + 1;
                        break;
                    }
                    Err(_) => return Err(())
                },
                None => match FromStr::from_str(&ascii[start..]) {
                    Ok(s) => return Ok(Mime(top, s, params)),
                    Err(_) => return Err(())
                },
                _ => return Err(())
            };
        }

        // params
        debug!("starting params, len={}", len);
        loop {
            match inspect!("param", param_from_str(&ascii, &mut iter, start)) {
                Some((p, end)) => {
                    params.push(p);
                    start = end;
                    if start >= len {
                        break;
                    }
                }
                None => break
            }
        }

        Ok(Mime(top, sub, params))
    }
}

fn param_from_str(raw: &str, iter: &mut Enumerate<Chars>, mut start: usize) -> Option<(Param, usize)> {
    let mut attr;
    debug!("param_from_str, start={}", start);
    loop {
        match inspect!("attr iter", iter.next()) {
            Some((i, ' ')) if i == start => start = i + 1,
            Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
            Some((i, c)) if i > start && is_restricted_name_char(c) => (),
            Some((i, '=')) if i > start => match FromStr::from_str(&raw[start..i]) {
                Ok(a) => {
                    attr = inspect!("attr", a);
                    start = i + 1;
                    break;
                },
                Err(_) => return None
            },
            _ => return None
        }
    }
    let mut value;
    // values must be restrict-name-char or "anything goes"
    let mut is_quoted = false;
    loop {
        match inspect!("value iter", iter.next()) {
            Some((i, '"')) if i == start => {
                debug!("quoted");
                is_quoted = true;
                start = i + 1;
            },
            Some((i, c)) if i == start && is_restricted_name_first_char(c) => (),
            Some((i, '"')) if i > start && is_quoted => match FromStr::from_str(&raw[start..i]) {
                Ok(v) => {
                    value = v;
                    start = i + 1;
                    break;
                },
                Err(_) => return None
            },
            Some((i, c)) if i > start && is_quoted || is_restricted_name_char(c) => (),
            Some((i, ';')) if i > start => match FromStr::from_str(&raw[start..i]) {
                Ok(v) => {
                    value = v;
                    start = i + 1;
                    break;
                },
                Err(_) => return None
            },
            None => match FromStr::from_str(&raw[start..]) {
                Ok(v) => {
                    value = v;
                    start = raw.len();
                    break;
                },
                Err(_) => return None
            },

            _ => return None
        }
    }

    Some(((attr, value), start))
}

// From [RFC6838](http://tools.ietf.org/html/rfc6838#section-4.2):
//
// > All registered media types MUST be assigned top-level type and
// > subtype names.  The combination of these names serves to uniquely
// > identify the media type, and the subtype name facet (or the absence
// > of one) identifies the registration tree.  Both top-level type and
// > subtype names are case-insensitive.
// >
// > Type and subtype names MUST conform to the following ABNF:
// >
// >     type-name = restricted-name
// >     subtype-name = restricted-name
// >
// >     restricted-name = restricted-name-first *126restricted-name-chars
// >     restricted-name-first  = ALPHA / DIGIT
// >     restricted-name-chars  = ALPHA / DIGIT / "!" / "#" /
// >                              "$" / "&" / "-" / "^" / "_"
// >     restricted-name-chars =/ "." ; Characters before first dot always
// >                                  ; specify a facet name
// >     restricted-name-chars =/ "+" ; Characters after last plus always
// >                                  ; specify a structured syntax suffix
//
fn is_restricted_name_first_char(c: char) -> bool {
    match c {
        'a'...'z' |
        '0'...'9' => true,
        _ => false
    }
}

fn is_restricted_name_char(c: char) -> bool {
    if is_restricted_name_first_char(c) {
        true
    } else {
        match c {
            '!' |
            '#' |
            '$' |
            '&' |
            '-' |
            '^' |
            '.' |
            '+' |
            '_' => true,
            _ => false
        }
    }
}

#[inline]
fn fmt_params(params: &[Param], fmt: &mut fmt::Formatter) -> fmt::Result {
    for param in params.iter() {
        try!(fmt_param(param, fmt));
    }
    Ok(())
}

#[inline]
fn fmt_param(param: &Param, fmt: &mut fmt::Formatter) -> fmt::Result {
    let (ref attr, ref value) = *param;
    write!(fmt, "; {}={}", attr, value)
}

#[cfg(test)]
mod tests {
    use std::str::FromStr;
    #[cfg(features = "nightly")]
    use test::Bencher;
    use super::Mime;

    #[test]
    fn test_mime_show() {
        let mime = mime!(Text/Plain);
        assert_eq!(mime.to_string(), "text/plain".to_string());
        let mime = mime!(Text/Plain; Charset=Utf8);
        assert_eq!(mime.to_string(), "text/plain; charset=utf-8".to_string());
    }

    #[test]
    fn test_mime_from_str() {
        assert_eq!(Mime::from_str("text/plain").unwrap(), mime!(Text/Plain));
        assert_eq!(Mime::from_str("TEXT/PLAIN").unwrap(), mime!(Text/Plain));
        assert_eq!(Mime::from_str("text/plain; charset=utf-8").unwrap(), mime!(Text/Plain; Charset=Utf8));
        assert_eq!(Mime::from_str("text/plain;charset=\"utf-8\"").unwrap(), mime!(Text/Plain; Charset=Utf8));
        assert_eq!(Mime::from_str("text/plain; charset=utf-8; foo=bar").unwrap(),
            mime!(Text/Plain; Charset=Utf8, ("foo")=("bar")));
    }

    #[cfg(features = "nightly")]
    #[bench]
    fn bench_show(b: &mut Bencher) {
        let mime = mime!(Text/Plain; Charset=Utf8, "foo"="bar");
        b.bytes = mime.to_string().as_bytes().len() as u64;
        b.iter(|| mime.to_string())
    }

    #[cfg(features = "nightly")]
    #[bench]
    fn bench_from_str(b: &mut Bencher) {
        let s = "text/plain; charset=utf-8; foo=bar";
        b.bytes = s.as_bytes().len() as u64;
        b.iter(|| s.parse::<Mime>())
    }
}
<|endoftext|>


<commit_before>//! This is the main lib.rs file for Xt Core

// This file is part of Xt.

// This is the Xt text editor; it edits text.
// Copyright (C) 2016-2017  The Xt Developers

// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see
// <http://www.gnu.org/licenses/>.

#![cfg_attr(feature = "ci", feature(plugin))]
#![cfg_attr(feature = "ci", plugin(clippy))]
#![cfg_attr(feature = "ci", allow(unstable_features))]
#![cfg_attr(feature = "ci", deny(clippy))]

#![deny(missing_docs, missing_debug_implementations,
        missing_copy_implementations, trivial_casts,
        trivial_numeric_casts, unused_import_braces,
        unused_qualifications)]

#[macro_use]
extern crate slog;
extern crate slog_json;
extern crate slog_async;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

pub mod logging;
pub mod rpc;
pub mod server;
pub mod utils;
<commit_msg>Fix Clippy and CI bug<commit_after>//! This is the main lib.rs file for Xt Core

// This file is part of Xt.

// This is the Xt text editor; it edits text.
// Copyright (C) 2016-2017  The Xt Developers

// This program is free software: you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.

// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see
// <http://www.gnu.org/licenses/>.

#![cfg_attr(feature = "ci", feature(plugin))]
#![cfg_attr(feature = "ci", plugin(clippy))]
#![cfg_attr(feature = "ci", allow(unstable_features))]
#![deny(missing_docs, missing_debug_implementations,
        missing_copy_implementations, trivial_casts,
        trivial_numeric_casts, unused_import_braces,
        unused_qualifications)]

#[macro_use]
extern crate slog;
extern crate slog_json;
extern crate slog_async;

#[macro_use]
extern crate serde_derive;
extern crate serde_json;

pub mod logging;
pub mod rpc;
pub mod server;
pub mod utils;
<|endoftext|>


<commit_before>// -*- rust -*-
use std;
import std::c_vec::*;
import std::ctypes::*;

#[link_name = ""]
#[abi = "cdecl"]
native mod libc {
    fn malloc(n: size_t) -> *mutable u8;
    fn free(m: *mutable u8);
}

fn malloc(n: size_t) -> t<u8> {
    let mem = libc::malloc(n);

    assert mem as int != 0;

    ret unsafe { create_with_dtor(mem, n, bind libc::free(mem)) };
}

#[test]
fn test_basic() {
    let cv = malloc(16u);

    set(cv, 3u, 8u8);
    set(cv, 4u, 9u8);
    assert get(cv, 3u) == 8u8;
    assert get(cv, 4u) == 9u8;
    assert size(cv) == 16u;
}

#[test]
#[should_fail]
fn test_overrun_get() {
    let cv = malloc(16u);

    get(cv, 17u);
}

#[test]
#[should_fail]
fn test_overrun_set() {
    let cv = malloc(16u);

    set(cv, 17u, 0u8);
}

#[test]
fn test_and_I_mean_it() {
    let cv = malloc(16u);
    let p = unsafe { ptr(cv) };

    set(cv, 0u, 32u8);
    set(cv, 1u, 33u8);
    assert unsafe { *p } == 32u8;
    set(cv, 2u, 34u8); /* safety */
}
<commit_msg>Ignore some should_fail tests on win32<commit_after>// -*- rust -*-
use std;
import std::c_vec::*;
import std::ctypes::*;

#[link_name = ""]
#[abi = "cdecl"]
native mod libc {
    fn malloc(n: size_t) -> *mutable u8;
    fn free(m: *mutable u8);
}

fn malloc(n: size_t) -> t<u8> {
    let mem = libc::malloc(n);

    assert mem as int != 0;

    ret unsafe { create_with_dtor(mem, n, bind libc::free(mem)) };
}

#[test]
fn test_basic() {
    let cv = malloc(16u);

    set(cv, 3u, 8u8);
    set(cv, 4u, 9u8);
    assert get(cv, 3u) == 8u8;
    assert get(cv, 4u) == 9u8;
    assert size(cv) == 16u;
}

#[test]
#[should_fail]
#[ignore(cfg(target_os = "win32"))]
fn test_overrun_get() {
    let cv = malloc(16u);

    get(cv, 17u);
}

#[test]
#[should_fail]
#[ignore(cfg(target_os = "win32"))]
fn test_overrun_set() {
    let cv = malloc(16u);

    set(cv, 17u, 0u8);
}

#[test]
fn test_and_I_mean_it() {
    let cv = malloc(16u);
    let p = unsafe { ptr(cv) };

    set(cv, 0u, 32u8);
    set(cv, 1u, 33u8);
    assert unsafe { *p } == 32u8;
    set(cv, 2u, 34u8); /* safety */
}
<|endoftext|>


<commit_before><commit_msg>Mtext implementation<commit_after>/*
 * Copyright 2017 Sreejith Krishnan R
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

use std::rc::Rc;
use std::any::Any;

use ::layout::{MtextLayout, Layout};
use super::super::{
    TokenPrivate, Token, PresentationPrivate, Presentation, SpecifiedTokenProps, PropertyCalculator,
    SpecifiedPresentationProps, Element, InheritedProps, StyleProps, ElementType, TokenElement};
use ::platform::Context;

pub struct Mtext {
    token_props: SpecifiedTokenProps,
    presentation_props: SpecifiedPresentationProps,
}

impl Mtext {
    pub fn new(text: String) -> Mtext {
        Mtext {
            token_props: SpecifiedTokenProps {
                text: Rc::new(text),
                math_variant: None,
                math_size: None,
                dir: None,
            },
            presentation_props: SpecifiedPresentationProps {
                math_color: None,
                math_background: None,
            }
        }
    }
}

impl Element for Mtext {
    fn layout(&self, context: &Context, parent: Option<&Element>, inherited: &InheritedProps,
              style: &Option<&StyleProps>) -> Box<Layout> {
        let mut calculator = PropertyCalculator::new(
            context, self, parent, inherited, style.clone());

        Box::new(MtextLayout {
            token_element: self.layout_token_element(context, &mut calculator)
        })
    }

    fn type_info(&self) -> ElementType {
        ElementType::TokenElement(TokenElement::Mtext)
    }

    fn as_any(&self) -> &Any {
        self
    }
}

impl PresentationPrivate<Mtext> for Mtext {
    fn get_specified_presentation_props(&self) -> &SpecifiedPresentationProps {
        &self.presentation_props
    }

    fn get_specified_presentation_props_mut(&mut self) -> &mut SpecifiedPresentationProps {
        &mut self.presentation_props
    }
}

impl TokenPrivate<Mtext> for Mtext {
    fn get_specified_token_props(&self) -> &SpecifiedTokenProps {
        &self.token_props
    }

    fn get_specified_token_props_mut(&mut self) -> &mut SpecifiedTokenProps {
        &mut self.token_props
    }
}

impl Token<Mtext> for Mtext {}

impl Presentation<Mtext> for Mtext {}

#[cfg(test)]
mod test {
    use super::*;
    use ::test::skia::Snapshot;
    use ::props::{Color, MathSize, MathVariant};

    #[test]
    fn it_works() {
        let snap = Snapshot::default();

        snap.snap_element(
            &Mtext::new(String::from("hello world!")),
            "mtext_normal"
        );

        snap.snap_element(
            Mtext::new(String::from("double struck text")).with_math_variant(Some(MathVariant::DoubleStruck)),
            "mtext_variant"
        );

        snap.snap_element(
            Mtext::new(String::from("this is big")).with_math_size(Some(MathSize::BIG)),
            "mtext_big"
        );

        snap.snap_element(
            Mtext::new(String::from("this is written in red")).with_math_color(Some(Color::RGB(255, 0, 0))),
            "mtext_red"
        );

        snap.snap_element(
            Mtext::new(String::from("this is written on red bg")).with_math_background(Some(Color::RGB(255, 0, 0))),
            "mtext_red_bg"
        );
    }
}<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

mod sip;

use std::hash::{Hash, Hasher};
use std::default::Default;

struct MyHasher {
    hash: u64,
}

impl Default for MyHasher {
    fn default() -> MyHasher {
        MyHasher { hash: 0 }
    }
}

impl Hasher for MyHasher {
    fn write(&mut self, buf: &[u8]) {
        for byte in buf {
            self.hash += *byte as u64;
        }
    }
    fn finish(&self) -> u64 { self.hash }
}

#[test]
fn test_writer_hasher() {
    fn hash<T: Hash>(t: &T) -> u64 {
        let mut s = MyHasher { hash: 0 };
        t.hash(&mut s);
        s.finish()
    }

    assert_eq!(hash(&()), 0);

    assert_eq!(hash(&5_u8), 5);
    assert_eq!(hash(&5_u16), 5);
    assert_eq!(hash(&5_u32), 5);
    assert_eq!(hash(&5_u64), 5);
    assert_eq!(hash(&5_usize), 5);

    assert_eq!(hash(&5_i8), 5);
    assert_eq!(hash(&5_i16), 5);
    assert_eq!(hash(&5_i32), 5);
    assert_eq!(hash(&5_i64), 5);
    assert_eq!(hash(&5_isize), 5);

    assert_eq!(hash(&false), 0);
    assert_eq!(hash(&true), 1);

    assert_eq!(hash(&'a'), 97);

    let s: &str = "a";
    assert_eq!(hash(& s), 97 + 0xFF);
    // FIXME (#18283) Enable test
    //let s: Box<str> = box "a";
    //assert_eq!(hasher.hash(& s), 97 + 0xFF);
    let cs: &[u8] = &[1, 2, 3];
    assert_eq!(hash(& cs), 9);
    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
    let cs: Box<[u8]> = Box::new([1, 2, 3]);
    assert_eq!(hash(& cs), 9);

    // FIXME (#18248) Add tests for hashing Rc<str> and Rc<[T]>

    let ptr = 5_usize as *const i32;
    assert_eq!(hash(&ptr), 5);

    let ptr = 5_usize as *mut i32;
    assert_eq!(hash(&ptr), 5);
}

struct Custom { hash: u64 }
struct CustomHasher { output: u64 }

impl Hasher for CustomHasher {
    fn finish(&self) -> u64 { self.output }
    fn write(&mut self, _: &[u8]) { panic!() }
    fn write_u64(&mut self, data: u64) { self.output = data; }
}

impl Default for CustomHasher {
    fn default() -> CustomHasher {
        CustomHasher { output: 0 }
    }
}

impl Hash for Custom {
    fn hash<H: Hasher>(&self, state: &mut H) {
        state.write_u64(self.hash);
    }
}

#[test]
fn test_custom_state() {
    fn hash<T: Hash>(t: &T) -> u64 {
        let mut c = CustomHasher { output: 0 };
        t.hash(&mut c);
        c.finish()
    }

    assert_eq!(hash(&Custom { hash: 5 }), 5);
}
<commit_msg>Remove a FIXME in core/hash tests<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

mod sip;

use std::hash::{Hash, Hasher};
use std::default::Default;

struct MyHasher {
    hash: u64,
}

impl Default for MyHasher {
    fn default() -> MyHasher {
        MyHasher { hash: 0 }
    }
}

impl Hasher for MyHasher {
    fn write(&mut self, buf: &[u8]) {
        for byte in buf {
            self.hash += *byte as u64;
        }
    }
    fn finish(&self) -> u64 { self.hash }
}

#[test]
fn test_writer_hasher() {
    fn hash<T: Hash>(t: &T) -> u64 {
        let mut s = MyHasher { hash: 0 };
        t.hash(&mut s);
        s.finish()
    }

    assert_eq!(hash(&()), 0);

    assert_eq!(hash(&5_u8), 5);
    assert_eq!(hash(&5_u16), 5);
    assert_eq!(hash(&5_u32), 5);
    assert_eq!(hash(&5_u64), 5);
    assert_eq!(hash(&5_usize), 5);

    assert_eq!(hash(&5_i8), 5);
    assert_eq!(hash(&5_i16), 5);
    assert_eq!(hash(&5_i32), 5);
    assert_eq!(hash(&5_i64), 5);
    assert_eq!(hash(&5_isize), 5);

    assert_eq!(hash(&false), 0);
    assert_eq!(hash(&true), 1);

    assert_eq!(hash(&'a'), 97);

    let s: &str = "a";
    assert_eq!(hash(& s), 97 + 0xFF);
    let s: Box<str> = String::from("a").into_boxed_str();
    assert_eq!(hash(& s), 97 + 0xFF);
    let cs: &[u8] = &[1, 2, 3];
    assert_eq!(hash(& cs), 9);
    // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
    let cs: Box<[u8]> = Box::new([1, 2, 3]);
    assert_eq!(hash(& cs), 9);

    // FIXME (#18248) Add tests for hashing Rc<str> and Rc<[T]>

    let ptr = 5_usize as *const i32;
    assert_eq!(hash(&ptr), 5);

    let ptr = 5_usize as *mut i32;
    assert_eq!(hash(&ptr), 5);
}

struct Custom { hash: u64 }
struct CustomHasher { output: u64 }

impl Hasher for CustomHasher {
    fn finish(&self) -> u64 { self.output }
    fn write(&mut self, _: &[u8]) { panic!() }
    fn write_u64(&mut self, data: u64) { self.output = data; }
}

impl Default for CustomHasher {
    fn default() -> CustomHasher {
        CustomHasher { output: 0 }
    }
}

impl Hash for Custom {
    fn hash<H: Hasher>(&self, state: &mut H) {
        state.write_u64(self.hash);
    }
}

#[test]
fn test_custom_state() {
    fn hash<T: Hash>(t: &T) -> u64 {
        let mut c = CustomHasher { output: 0 };
        t.hash(&mut c);
        c.finish()
    }

    assert_eq!(hash(&Custom { hash: 5 }), 5);
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};

const NSEC_PER_SEC: u64 = 1_000_000_000;

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod inner {
    use cmp::Ordering;
    use fmt;
    use libc;
    use super::NSEC_PER_SEC;
    use sync::Once;
    use sys::cvt;
    use sys_common::mul_div_u64;
    use time::Duration;

    const USEC_PER_SEC: u64 = NSEC_PER_SEC / 1000;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
    pub struct Instant {
        t: u64
    }

    #[derive(Copy, Clone)]
    pub struct SystemTime {
        t: libc::timeval,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime {
        t: libc::timeval {
            tv_sec: 0,
            tv_usec: 0,
        },
    };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: unsafe { libc::mach_absolute_time() } }
        }

        pub fn sub_instant(&self, other: &Instant) -> Duration {
            let info = info();
            let diff = self.t.checked_sub(other.t)
                           .expect("second instant is later than self");
            let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64);
            Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)
        }

        pub fn add_duration(&self, other: &Duration) -> Instant {
            Instant {
                t: self.t.checked_add(dur2intervals(other))
                       .expect("overflow when adding duration to instant"),
            }
        }

        pub fn sub_duration(&self, other: &Duration) -> Instant {
            Instant {
                t: self.t.checked_sub(dur2intervals(other))
                       .expect("overflow when adding duration to instant"),
            }
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            let mut s = SystemTime {
                t: libc::timeval {
                    tv_sec: 0,
                    tv_usec: 0,
                },
            };
            cvt(unsafe {
                libc::gettimeofday(&mut s.t, 0 as *mut _)
            }).unwrap();
            return s
        }

        pub fn sub_time(&self, other: &SystemTime)
                        -> Result<Duration, Duration> {
            if self >= other {
                Ok(if self.t.tv_usec >= other.t.tv_usec {
                    Duration::new(self.t.tv_sec as u64 - other.t.tv_sec as u64,
                                  (self.t.tv_usec as u32 -
                                   other.t.tv_usec as u32) * 1000)
                } else {
                    Duration::new(self.t.tv_sec as u64 - 1 - other.t.tv_sec as u64,
                                  (self.t.tv_usec as u32 + (USEC_PER_SEC as u32) -
                                   other.t.tv_usec as u32) * 1000)
                })
            } else {
                match other.sub_time(self) {
                    Ok(d) => Err(d),
                    Err(d) => Ok(d),
                }
            }
        }

        pub fn add_duration(&self, other: &Duration) -> SystemTime {
            let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
            let mut secs = secs.expect("overflow when adding duration to time");

            // Nano calculations can't overflow because nanos are <1B which fit
            // in a u32.
            let mut usec = (other.subsec_nanos() / 1000) + self.t.tv_usec as u32;
            if usec >= USEC_PER_SEC as u32 {
                usec -= USEC_PER_SEC as u32;
                secs = secs.checked_add(1).expect("overflow when adding \
                                                   duration to time");
            }
            SystemTime {
                t: libc::timeval {
                    tv_sec: secs as libc::time_t,
                    tv_usec: usec as libc::suseconds_t,
                },
            }
        }

        pub fn sub_duration(&self, other: &Duration) -> SystemTime {
            let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
            let mut secs = secs.expect("overflow when subtracting duration \
                                        from time");

            // Similar to above, nanos can't overflow.
            let mut usec = self.t.tv_usec as i32 -
                           (other.subsec_nanos() / 1000) as i32;
            if usec < 0 {
                usec += USEC_PER_SEC as i32;
                secs = secs.checked_sub(1).expect("overflow when subtracting \
                                                   duration from time");
            }
            SystemTime {
                t: libc::timeval {
                    tv_sec: secs as libc::time_t,
                    tv_usec: usec as libc::suseconds_t,
                },
            }
        }
    }

    impl From<libc::timeval> for SystemTime {
        fn from(t: libc::timeval) -> SystemTime {
            SystemTime { t: t }
        }
    }

    impl PartialEq for SystemTime {
        fn eq(&self, other: &SystemTime) -> bool {
            self.t.tv_sec == other.t.tv_sec && self.t.tv_usec == other.t.tv_usec
        }
    }

    impl Eq for SystemTime {}

    impl PartialOrd for SystemTime {
        fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl Ord for SystemTime {
        fn cmp(&self, other: &SystemTime) -> Ordering {
            let me = (self.t.tv_sec, self.t.tv_usec);
            let other = (other.t.tv_sec, other.t.tv_usec);
            me.cmp(&other)
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("SystemTime")
             .field("tv_sec", &self.t.tv_sec)
             .field("tv_usec", &self.t.tv_usec)
             .finish()
        }
    }

    fn dur2intervals(dur: &Duration) -> u64 {
        let info = info();
        let nanos = dur.as_secs().checked_mul(NSEC_PER_SEC).and_then(|nanos| {
            nanos.checked_add(dur.subsec_nanos() as u64)
        }).expect("overflow converting duration to nanoseconds");
        mul_div_u64(nanos, info.denom as u64, info.numer as u64)
    }

    fn info() -> &'static libc::mach_timebase_info {
        static mut INFO: libc::mach_timebase_info = libc::mach_timebase_info {
            numer: 0,
            denom: 0,
        };
        static ONCE: Once = Once::new();

        unsafe {
            ONCE.call_once(|| {
                libc::mach_timebase_info(&mut INFO);
            });
            &INFO
        }
    }
}

#[cfg(not(any(target_os = "macos", target_os = "ios")))]
mod inner {
    use cmp::Ordering;
    use fmt;
    use libc;
    use super::NSEC_PER_SEC;
    use sys::cvt;
    use time::Duration;

    #[derive(Copy, Clone)]
    struct Timespec {
        t: libc::timespec,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
    pub struct Instant {
        t: Timespec,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime {
        t: Timespec {
            t: libc::timespec {
                tv_sec: 0,
                tv_nsec: 0,
            },
        },
    };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: Timespec::now(libc::CLOCK_MONOTONIC) }
        }

        pub fn sub_instant(&self, other: &Instant) -> Duration {
            self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
                panic!("other was less than the current instant")
            })
        }

        pub fn add_duration(&self, other: &Duration) -> Instant {
            Instant { t: self.t.add_duration(other) }
        }

        pub fn sub_duration(&self, other: &Duration) -> Instant {
            Instant { t: self.t.sub_duration(other) }
        }
    }

    impl fmt::Debug for Instant {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("Instant")
             .field("tv_sec", &self.t.t.tv_sec)
             .field("tv_nsec", &self.t.t.tv_nsec)
             .finish()
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) }
        }

        pub fn sub_time(&self, other: &SystemTime)
                        -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn add_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.add_duration(other) }
        }

        pub fn sub_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.sub_duration(other) }
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t: t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("SystemTime")
             .field("tv_sec", &self.t.t.tv_sec)
             .field("tv_nsec", &self.t.t.tv_nsec)
             .finish()
        }
    }

    impl Timespec {
        pub fn now(clock: libc::c_int) -> Timespec {
            let mut t = Timespec {
                t: libc::timespec {
                    tv_sec: 0,
                    tv_nsec: 0,
                }
            };
            cvt(unsafe {
                libc::clock_gettime(clock, &mut t.t)
            }).unwrap();
            t
        }

        fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
            if self >= other {
                Ok(if self.t.tv_nsec >= other.t.tv_nsec {
                    Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
                                  (self.t.tv_nsec - other.t.tv_nsec) as u32)
                } else {
                    Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
                                  self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
                                  other.t.tv_nsec as u32)
                })
            } else {
                match other.sub_timespec(self) {
                    Ok(d) => Err(d),
                    Err(d) => Ok(d),
                }
            }
        }

        fn add_duration(&self, other: &Duration) -> Timespec {
            let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
            let mut secs = secs.expect("overflow when adding duration to time");

            // Nano calculations can't overflow because nanos are <1B which fit
            // in a u32.
            let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
            if nsec >= NSEC_PER_SEC as u32 {
                nsec -= NSEC_PER_SEC as u32;
                secs = secs.checked_add(1).expect("overflow when adding \
                                                   duration to time");
            }
            Timespec {
                t: libc::timespec {
                    tv_sec: secs as libc::time_t,
                    tv_nsec: nsec as libc::c_long,
                },
            }
        }

        fn sub_duration(&self, other: &Duration) -> Timespec {
            let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
            let mut secs = secs.expect("overflow when subtracting duration \
                                        from time");

            // Similar to above, nanos can't overflow.
            let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
            if nsec < 0 {
                nsec += NSEC_PER_SEC as i32;
                secs = secs.checked_sub(1).expect("overflow when subtracting \
                                                   duration from time");
            }
            Timespec {
                t: libc::timespec {
                    tv_sec: secs as libc::time_t,
                    tv_nsec: nsec as libc::c_long,
                },
            }
        }
    }

    impl PartialEq for Timespec {
        fn eq(&self, other: &Timespec) -> bool {
            self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
        }
    }

    impl Eq for Timespec {}

    impl PartialOrd for Timespec {
        fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl Ord for Timespec {
        fn cmp(&self, other: &Timespec) -> Ordering {
            let me = (self.t.tv_sec, self.t.tv_nsec);
            let other = (other.t.tv_sec, other.t.tv_nsec);
            me.cmp(&other)
        }
    }
}
<commit_msg>Auto merge of #32273 - alexcrichton:fix-time-sub, r=aturon<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub use self::inner::{Instant, SystemTime, UNIX_EPOCH};

const NSEC_PER_SEC: u64 = 1_000_000_000;

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod inner {
    use cmp::Ordering;
    use fmt;
    use libc;
    use super::NSEC_PER_SEC;
    use sync::Once;
    use sys::cvt;
    use sys_common::mul_div_u64;
    use time::Duration;

    const USEC_PER_SEC: u64 = NSEC_PER_SEC / 1000;

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
    pub struct Instant {
        t: u64
    }

    #[derive(Copy, Clone)]
    pub struct SystemTime {
        t: libc::timeval,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime {
        t: libc::timeval {
            tv_sec: 0,
            tv_usec: 0,
        },
    };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: unsafe { libc::mach_absolute_time() } }
        }

        pub fn sub_instant(&self, other: &Instant) -> Duration {
            let info = info();
            let diff = self.t.checked_sub(other.t)
                           .expect("second instant is later than self");
            let nanos = mul_div_u64(diff, info.numer as u64, info.denom as u64);
            Duration::new(nanos / NSEC_PER_SEC, (nanos % NSEC_PER_SEC) as u32)
        }

        pub fn add_duration(&self, other: &Duration) -> Instant {
            Instant {
                t: self.t.checked_add(dur2intervals(other))
                       .expect("overflow when adding duration to instant"),
            }
        }

        pub fn sub_duration(&self, other: &Duration) -> Instant {
            Instant {
                t: self.t.checked_sub(dur2intervals(other))
                       .expect("overflow when adding duration to instant"),
            }
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            let mut s = SystemTime {
                t: libc::timeval {
                    tv_sec: 0,
                    tv_usec: 0,
                },
            };
            cvt(unsafe {
                libc::gettimeofday(&mut s.t, 0 as *mut _)
            }).unwrap();
            return s
        }

        pub fn sub_time(&self, other: &SystemTime)
                        -> Result<Duration, Duration> {
            if self >= other {
                Ok(if self.t.tv_usec >= other.t.tv_usec {
                    Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
                                  ((self.t.tv_usec -
                                    other.t.tv_usec) as u32) * 1000)
                } else {
                    Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
                                  (self.t.tv_usec as u32 + (USEC_PER_SEC as u32) -
                                   other.t.tv_usec as u32) * 1000)
                })
            } else {
                match other.sub_time(self) {
                    Ok(d) => Err(d),
                    Err(d) => Ok(d),
                }
            }
        }

        pub fn add_duration(&self, other: &Duration) -> SystemTime {
            let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
            let mut secs = secs.expect("overflow when adding duration to time");

            // Nano calculations can't overflow because nanos are <1B which fit
            // in a u32.
            let mut usec = (other.subsec_nanos() / 1000) + self.t.tv_usec as u32;
            if usec >= USEC_PER_SEC as u32 {
                usec -= USEC_PER_SEC as u32;
                secs = secs.checked_add(1).expect("overflow when adding \
                                                   duration to time");
            }
            SystemTime {
                t: libc::timeval {
                    tv_sec: secs as libc::time_t,
                    tv_usec: usec as libc::suseconds_t,
                },
            }
        }

        pub fn sub_duration(&self, other: &Duration) -> SystemTime {
            let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
            let mut secs = secs.expect("overflow when subtracting duration \
                                        from time");

            // Similar to above, nanos can't overflow.
            let mut usec = self.t.tv_usec as i32 -
                           (other.subsec_nanos() / 1000) as i32;
            if usec < 0 {
                usec += USEC_PER_SEC as i32;
                secs = secs.checked_sub(1).expect("overflow when subtracting \
                                                   duration from time");
            }
            SystemTime {
                t: libc::timeval {
                    tv_sec: secs as libc::time_t,
                    tv_usec: usec as libc::suseconds_t,
                },
            }
        }
    }

    impl From<libc::timeval> for SystemTime {
        fn from(t: libc::timeval) -> SystemTime {
            SystemTime { t: t }
        }
    }

    impl PartialEq for SystemTime {
        fn eq(&self, other: &SystemTime) -> bool {
            self.t.tv_sec == other.t.tv_sec && self.t.tv_usec == other.t.tv_usec
        }
    }

    impl Eq for SystemTime {}

    impl PartialOrd for SystemTime {
        fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl Ord for SystemTime {
        fn cmp(&self, other: &SystemTime) -> Ordering {
            let me = (self.t.tv_sec, self.t.tv_usec);
            let other = (other.t.tv_sec, other.t.tv_usec);
            me.cmp(&other)
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("SystemTime")
             .field("tv_sec", &self.t.tv_sec)
             .field("tv_usec", &self.t.tv_usec)
             .finish()
        }
    }

    fn dur2intervals(dur: &Duration) -> u64 {
        let info = info();
        let nanos = dur.as_secs().checked_mul(NSEC_PER_SEC).and_then(|nanos| {
            nanos.checked_add(dur.subsec_nanos() as u64)
        }).expect("overflow converting duration to nanoseconds");
        mul_div_u64(nanos, info.denom as u64, info.numer as u64)
    }

    fn info() -> &'static libc::mach_timebase_info {
        static mut INFO: libc::mach_timebase_info = libc::mach_timebase_info {
            numer: 0,
            denom: 0,
        };
        static ONCE: Once = Once::new();

        unsafe {
            ONCE.call_once(|| {
                libc::mach_timebase_info(&mut INFO);
            });
            &INFO
        }
    }
}

#[cfg(not(any(target_os = "macos", target_os = "ios")))]
mod inner {
    use cmp::Ordering;
    use fmt;
    use libc;
    use super::NSEC_PER_SEC;
    use sys::cvt;
    use time::Duration;

    #[derive(Copy, Clone)]
    struct Timespec {
        t: libc::timespec,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
    pub struct Instant {
        t: Timespec,
    }

    #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
    pub struct SystemTime {
        t: Timespec,
    }

    pub const UNIX_EPOCH: SystemTime = SystemTime {
        t: Timespec {
            t: libc::timespec {
                tv_sec: 0,
                tv_nsec: 0,
            },
        },
    };

    impl Instant {
        pub fn now() -> Instant {
            Instant { t: Timespec::now(libc::CLOCK_MONOTONIC) }
        }

        pub fn sub_instant(&self, other: &Instant) -> Duration {
            self.t.sub_timespec(&other.t).unwrap_or_else(|_| {
                panic!("other was less than the current instant")
            })
        }

        pub fn add_duration(&self, other: &Duration) -> Instant {
            Instant { t: self.t.add_duration(other) }
        }

        pub fn sub_duration(&self, other: &Duration) -> Instant {
            Instant { t: self.t.sub_duration(other) }
        }
    }

    impl fmt::Debug for Instant {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("Instant")
             .field("tv_sec", &self.t.t.tv_sec)
             .field("tv_nsec", &self.t.t.tv_nsec)
             .finish()
        }
    }

    impl SystemTime {
        pub fn now() -> SystemTime {
            SystemTime { t: Timespec::now(libc::CLOCK_REALTIME) }
        }

        pub fn sub_time(&self, other: &SystemTime)
                        -> Result<Duration, Duration> {
            self.t.sub_timespec(&other.t)
        }

        pub fn add_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.add_duration(other) }
        }

        pub fn sub_duration(&self, other: &Duration) -> SystemTime {
            SystemTime { t: self.t.sub_duration(other) }
        }
    }

    impl From<libc::timespec> for SystemTime {
        fn from(t: libc::timespec) -> SystemTime {
            SystemTime { t: Timespec { t: t } }
        }
    }

    impl fmt::Debug for SystemTime {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            f.debug_struct("SystemTime")
             .field("tv_sec", &self.t.t.tv_sec)
             .field("tv_nsec", &self.t.t.tv_nsec)
             .finish()
        }
    }

    impl Timespec {
        pub fn now(clock: libc::c_int) -> Timespec {
            let mut t = Timespec {
                t: libc::timespec {
                    tv_sec: 0,
                    tv_nsec: 0,
                }
            };
            cvt(unsafe {
                libc::clock_gettime(clock, &mut t.t)
            }).unwrap();
            t
        }

        fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> {
            if self >= other {
                Ok(if self.t.tv_nsec >= other.t.tv_nsec {
                    Duration::new((self.t.tv_sec - other.t.tv_sec) as u64,
                                  (self.t.tv_nsec - other.t.tv_nsec) as u32)
                } else {
                    Duration::new((self.t.tv_sec - 1 - other.t.tv_sec) as u64,
                                  self.t.tv_nsec as u32 + (NSEC_PER_SEC as u32) -
                                  other.t.tv_nsec as u32)
                })
            } else {
                match other.sub_timespec(self) {
                    Ok(d) => Err(d),
                    Err(d) => Ok(d),
                }
            }
        }

        fn add_duration(&self, other: &Duration) -> Timespec {
            let secs = (self.t.tv_sec as i64).checked_add(other.as_secs() as i64);
            let mut secs = secs.expect("overflow when adding duration to time");

            // Nano calculations can't overflow because nanos are <1B which fit
            // in a u32.
            let mut nsec = other.subsec_nanos() + self.t.tv_nsec as u32;
            if nsec >= NSEC_PER_SEC as u32 {
                nsec -= NSEC_PER_SEC as u32;
                secs = secs.checked_add(1).expect("overflow when adding \
                                                   duration to time");
            }
            Timespec {
                t: libc::timespec {
                    tv_sec: secs as libc::time_t,
                    tv_nsec: nsec as libc::c_long,
                },
            }
        }

        fn sub_duration(&self, other: &Duration) -> Timespec {
            let secs = (self.t.tv_sec as i64).checked_sub(other.as_secs() as i64);
            let mut secs = secs.expect("overflow when subtracting duration \
                                        from time");

            // Similar to above, nanos can't overflow.
            let mut nsec = self.t.tv_nsec as i32 - other.subsec_nanos() as i32;
            if nsec < 0 {
                nsec += NSEC_PER_SEC as i32;
                secs = secs.checked_sub(1).expect("overflow when subtracting \
                                                   duration from time");
            }
            Timespec {
                t: libc::timespec {
                    tv_sec: secs as libc::time_t,
                    tv_nsec: nsec as libc::c_long,
                },
            }
        }
    }

    impl PartialEq for Timespec {
        fn eq(&self, other: &Timespec) -> bool {
            self.t.tv_sec == other.t.tv_sec && self.t.tv_nsec == other.t.tv_nsec
        }
    }

    impl Eq for Timespec {}

    impl PartialOrd for Timespec {
        fn partial_cmp(&self, other: &Timespec) -> Option<Ordering> {
            Some(self.cmp(other))
        }
    }

    impl Ord for Timespec {
        fn cmp(&self, other: &Timespec) -> Ordering {
            let me = (self.t.tv_sec, self.t.tv_nsec);
            let other = (other.t.tv_sec, other.t.tv_nsec);
            me.cmp(&other)
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>sends a message if cannot determine color<commit_after><|endoftext|>


<commit_before>use alloc::boxed::Box;

use graphics::bmp::*;

use common::debug;
use common::resource::URL;
use common::string::{String, ToString};
use common::vec::Vec;

pub struct Package {
    pub url: URL,
    pub id: String,
    pub name: String,
    pub binary: URL,
    pub icon: BMPFile,
    pub accepts: Vec<String>,
    pub authors: Vec<String>,
    pub descriptions: Vec<String>,
}

impl Package {
    pub fn from_url(url: &URL) -> Box<Self> {
        let mut package = box Package {
            url: url.clone(),
            id: String::new(),
            name: String::new(),
            binary: URL::new(),
            icon: BMPFile::new(),
            accepts: Vec::new(),
            authors: Vec::new(),
            descriptions: Vec::new(),
        };

        let path_parts = url.path_parts();
        if path_parts.len() > 0 {
            if let Some(part) = path_parts.get(path_parts.len() - 1) {
                package.id = part.clone();
                package.binary = URL::from_string(&(url.to_string() + part + ".bin"));
            }
        }

        let mut info = String::new();
        if let Some(mut resource) = URL::from_string(&(url.to_string() + "_REDOX")).open() {
            let mut vec: Vec<u8> = Vec::new();
            resource.read_to_end(&mut vec);
            info = String::from_utf8(&vec);
        }

        for line in info.split("\n".to_string()) {
            if line.starts_with("name=".to_string()) {
                package.name = line.substr(5, line.len() - 5);
            } else if line.starts_with("binary=".to_string()) {
                package.binary = URL::from_string(&(url.to_string() +
                                                    line.substr(7, line.len() - 7)));
            } else if line.starts_with("icon=".to_string()) {
                if let Some(mut resource) = URL::from_string(&line.substr(5, line.len() - 5)).open() {
                    let mut vec: Vec<u8> = Vec::new();
                    resource.read_to_end(&mut vec);
                    package.icon = BMPFile::from_data(&vec);
                }
            } else if line.starts_with("accept=".to_string()) {
                package.accepts.push(line.substr(7, line.len() - 7));
            } else if line.starts_with("author=".to_string()) {
                package.authors.push(line.substr(7, line.len() - 7));
            } else if line.starts_with("description=".to_string()) {
                package.descriptions.push(line.substr(12, line.len() - 12));
            } else {
                debug::d("Unknown package info: ");
                line.d();
                debug::dl();
            }
        }

        package
    }

    pub fn d(&self) {
        debug::d("URL: ");
        self.url.d();
        debug::dl();

        debug::d("ID: ");
        self.id.d();
        debug::dl();

        debug::d("Name: ");
        self.name.d();
        debug::dl();

        debug::d("Binary: ");
        self.binary.d();
        debug::dl();

        debug::d("Icon: ");
        debug::dd(self.icon.size.width);
        debug::d("x");
        debug::dd(self.icon.size.height);
        debug::dl();

        for accept in self.accepts.iter() {
            debug::d("Accept: ");
            accept.d();
            debug::dl();
        }

        for author in self.authors.iter() {
            debug::d("Author: ");
            author.d();
            debug::dl();
        }

        for description in self.descriptions.iter() {
            debug::d("Description: ");
            description.d();
            debug::dl();
        }
    }
}
<commit_msg>Split _REDOX-files by lines not by "\n"-pattern<commit_after>use alloc::boxed::Box;

use graphics::bmp::*;

use common::debug;
use common::resource::URL;
use common::string::{String, ToString};
use common::vec::Vec;

pub struct Package {
    pub url: URL,
    pub id: String,
    pub name: String,
    pub binary: URL,
    pub icon: BMPFile,
    pub accepts: Vec<String>,
    pub authors: Vec<String>,
    pub descriptions: Vec<String>,
}

impl Package {
    pub fn from_url(url: &URL) -> Box<Self> {
        let mut package = box Package {
            url: url.clone(),
            id: String::new(),
            name: String::new(),
            binary: URL::new(),
            icon: BMPFile::new(),
            accepts: Vec::new(),
            authors: Vec::new(),
            descriptions: Vec::new(),
        };

        let path_parts = url.path_parts();
        if path_parts.len() > 0 {
            if let Some(part) = path_parts.get(path_parts.len() - 1) {
                package.id = part.clone();
                package.binary = URL::from_string(&(url.to_string() + part + ".bin"));
            }
        }

        let mut info = String::new();
        if let Some(mut resource) = URL::from_string(&(url.to_string() + "_REDOX")).open() {
            let mut vec: Vec<u8> = Vec::new();
            resource.read_to_end(&mut vec);
            info = String::from_utf8(&vec);
        }

        for line in info.lines() {
            if line.starts_with("name=".to_string()) {
                package.name = line.substr(5, line.len() - 5);
            } else if line.starts_with("binary=".to_string()) {
                package.binary = URL::from_string(&(url.to_string() +
                                                    line.substr(7, line.len() - 7)));
            } else if line.starts_with("icon=".to_string()) {
                if let Some(mut resource) = URL::from_string(&line.substr(5, line.len() - 5)).open() {
                    let mut vec: Vec<u8> = Vec::new();
                    resource.read_to_end(&mut vec);
                    package.icon = BMPFile::from_data(&vec);
                }
            } else if line.starts_with("accept=".to_string()) {
                package.accepts.push(line.substr(7, line.len() - 7));
            } else if line.starts_with("author=".to_string()) {
                package.authors.push(line.substr(7, line.len() - 7));
            } else if line.starts_with("description=".to_string()) {
                package.descriptions.push(line.substr(12, line.len() - 12));
            } else {
                debug::d("Unknown package info: ");
                line.d();
                debug::dl();
            }
        }

        package
    }

    pub fn d(&self) {
        debug::d("URL: ");
        self.url.d();
        debug::dl();

        debug::d("ID: ");
        self.id.d();
        debug::dl();

        debug::d("Name: ");
        self.name.d();
        debug::dl();

        debug::d("Binary: ");
        self.binary.d();
        debug::dl();

        debug::d("Icon: ");
        debug::dd(self.icon.size.width);
        debug::d("x");
        debug::dd(self.icon.size.height);
        debug::dl();

        for accept in self.accepts.iter() {
            debug::d("Accept: ");
            accept.d();
            debug::dl();
        }

        for author in self.authors.iter() {
            debug::d("Author: ");
            author.d();
            debug::dl();
        }

        for description in self.descriptions.iter() {
            debug::d("Description: ");
            description.d();
            debug::dl();
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Adjust the errors<commit_after><|endoftext|>


<commit_before><commit_msg>node_query.rs<commit_after>extern crate rusqlite

use  common::Node;

use common::types::StructType;
use common::types::FnType;
use common::Criteria;

use common::utils::load_file;

use super::base::Dao;
use super::base::SqlConfig;
use super::node_dao::NodeDao;

fn get_sql_config() -> SqlConfig {
    let db = match Connection::open_in_memory() {
        Ok(c) => c,
        Err(err) => panic!("OPEN TEST DB FAILED: {}", err),
    };

    let read_sql = String::from("res/sql/entity/read.sql");
    let delete_sql = String::from("res/sql/entity/delete.sql");
    let insert_sql = String::from("res/sql/entity/insert.sql");
    let update_sql = String::from("res/sql/entity/update.sql");
    let list_sql = String::from("res/sql/entity/list.sql");

    SqlConfig {
        connection: db,
        read_sql: load_file(&read_sql).unwrap(),
        delete_sql: load_file(&delete_sql).unwrap(),
        insert_sql: load_file(&insert_sql).unwrap(),
        update_sql: load_file(&update_sql).unwrap(),
        list_sql: load_file(&list_sql).unwrap(),
    }
}

fn init_test_db() -> SqlConfig {
    let config = get_sql_config();

    let init_sql = String::from("res/sql/entity/init.sql");
    let init_test_sql = String::from("res/sql/entity/init_test.sql");

    let init_query = load_file(&init_sql).unwrap();
    let init_test_query = load_file(&init_test_sql).unwrap();

    match config.connection.execute(init_query.as_str(), &[]) {
        Ok(_) => {}
        Err(err) => panic!("CREATE TEST TABLE FAILED: {}", err),
    };

    match config.connection.execute(init_test_query.as_str(), &[]) {
        Ok(_) => {}
        Err(err) => panic!("INIT TEST DB FAILED: {}", err),
    };

    config
}

#[test]
fn read() {
    let dao = NodeDao { config: init_test_db() };
    let id_test = 1;
    let node = Node {
        id: id_test,
        parent_id: String::from("1"),
        name: String::from("test_read"),
        url: String::from("test_url"),
        struct_type: StructType::Node,
        fn_type: FnType::None,
        rev_no: 0,
    };

}
<|endoftext|>


<commit_before><commit_msg>atomic: use raw pointers<commit_after><|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ffi::CStr;
use io;
use libc::{self, c_int, size_t, sockaddr, socklen_t};
use net::{SocketAddr, Shutdown};
use str;
use sys::fd::FileDesc;
use sys_common::{AsInner, FromInner, IntoInner};
use sys_common::net::{getsockopt, setsockopt};
use time::Duration;

pub use sys::{cvt, cvt_r};
pub extern crate libc as netc;

pub type wrlen_t = size_t;

// See below for the usage of SOCK_CLOEXEC, but this constant is only defined on
// Linux currently (e.g. support doesn't exist on other platforms). In order to
// get name resolution to work and things to compile we just define a dummy
// SOCK_CLOEXEC here for other platforms. Note that the dummy constant isn't
// actually ever used (the blocks below are wrapped in `if cfg!` as well.
#[cfg(target_os = "linux")]
use libc::SOCK_CLOEXEC;
#[cfg(not(target_os = "linux"))]
const SOCK_CLOEXEC: c_int = 0;

pub struct Socket(FileDesc);

pub fn init() {}

pub fn cvt_gai(err: c_int) -> io::Result<()> {
    if err == 0 { return Ok(()) }

    let detail = unsafe {
        str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap()
            .to_owned()
    };
    Err(io::Error::new(io::ErrorKind::Other,
                       &format!("failed to lookup address information: {}",
                                detail)[..]))
}

impl Socket {
    pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
        let fam = match *addr {
            SocketAddr::V4(..) => libc::AF_INET,
            SocketAddr::V6(..) => libc::AF_INET6,
        };
        Socket::new_raw(fam, ty)
    }

    pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
        unsafe {
            // On linux we first attempt to pass the SOCK_CLOEXEC flag to
            // atomically create the socket and set it as CLOEXEC. Support for
            // this option, however, was added in 2.6.27, and we still support
            // 2.6.18 as a kernel, so if the returned error is EINVAL we
            // fallthrough to the fallback.
            if cfg!(target_os = "linux") {
                match cvt(libc::socket(fam, ty | SOCK_CLOEXEC, 0)) {
                    Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
                    Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
                    Err(e) => return Err(e),
                }
            }

            let fd = cvt(libc::socket(fam, ty, 0))?;
            let fd = FileDesc::new(fd);
            fd.set_cloexec()?;
            Ok(Socket(fd))
        }
    }

    pub fn new_pair(fam: c_int, ty: c_int) -> io::Result<(Socket, Socket)> {
        unsafe {
            let mut fds = [0, 0];

            // Like above, see if we can set cloexec atomically
            if cfg!(target_os = "linux") {
                match cvt(libc::socketpair(fam, ty | SOCK_CLOEXEC, 0, fds.as_mut_ptr())) {
                    Ok(_) => {
                        return Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1]))));
                    }
                    Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {},
                    Err(e) => return Err(e),
                }
            }

            cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?;
            let a = FileDesc::new(fds[0]);
            let b = FileDesc::new(fds[1]);
            a.set_cloexec()?;
            b.set_cloexec()?;
            Ok((Socket(a), Socket(b)))
        }
    }

    pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t)
                  -> io::Result<Socket> {
        // Unfortunately the only known way right now to accept a socket and
        // atomically set the CLOEXEC flag is to use the `accept4` syscall on
        // Linux. This was added in 2.6.28, however, and because we support
        // 2.6.18 we must detect this support dynamically.
        if cfg!(target_os = "linux") {
            weak! {
                fn accept4(c_int, *mut sockaddr, *mut socklen_t, c_int) -> c_int
            }
            if let Some(accept) = accept4.get() {
                let res = cvt_r(|| unsafe {
                    accept(self.0.raw(), storage, len, SOCK_CLOEXEC)
                });
                match res {
                    Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
                    Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {}
                    Err(e) => return Err(e),
                }
            }
        }

        let fd = cvt_r(|| unsafe {
            libc::accept(self.0.raw(), storage, len)
        })?;
        let fd = FileDesc::new(fd);
        fd.set_cloexec()?;
        Ok(Socket(fd))
    }

    pub fn duplicate(&self) -> io::Result<Socket> {
        self.0.duplicate().map(Socket)
    }

    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }

    pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
        self.0.read_to_end(buf)
    }

    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    pub fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> {
        let timeout = match dur {
            Some(dur) => {
                if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
                    return Err(io::Error::new(io::ErrorKind::InvalidInput,
                                              "cannot set a 0 duration timeout"));
                }

                let secs = if dur.as_secs() > libc::time_t::max_value() as u64 {
                    libc::time_t::max_value()
                } else {
                    dur.as_secs() as libc::time_t
                };
                let mut timeout = libc::timeval {
                    tv_sec: secs,
                    tv_usec: (dur.subsec_nanos() / 1000) as libc::suseconds_t,
                };
                if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
                    timeout.tv_usec = 1;
                }
                timeout
            }
            None => {
                libc::timeval {
                    tv_sec: 0,
                    tv_usec: 0,
                }
            }
        };
        setsockopt(self, libc::SOL_SOCKET, kind, timeout)
    }

    pub fn timeout(&self, kind: libc::c_int) -> io::Result<Option<Duration>> {
        let raw: libc::timeval = getsockopt(self, libc::SOL_SOCKET, kind)?;
        if raw.tv_sec == 0 && raw.tv_usec == 0 {
            Ok(None)
        } else {
            let sec = raw.tv_sec as u64;
            let nsec = (raw.tv_usec as u32) * 1000;
            Ok(Some(Duration::new(sec, nsec)))
        }
    }

    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
        let how = match how {
            Shutdown::Write => libc::SHUT_WR,
            Shutdown::Read => libc::SHUT_RD,
            Shutdown::Both => libc::SHUT_RDWR,
        };
        cvt(unsafe { libc::shutdown(self.0.raw(), how) })?;
        Ok(())
    }

    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
        setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int)
    }

    pub fn nodelay(&self) -> io::Result<bool> {
        let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY)?;
        Ok(raw != 0)
    }

    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
        let mut nonblocking = nonblocking as libc::c_ulong;
        cvt(unsafe { libc::ioctl(*self.as_inner(), libc::FIONBIO, &mut nonblocking) }).map(|_| ())
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
        if raw == 0 {
            Ok(None)
        } else {
            Ok(Some(io::Error::from_raw_os_error(raw as i32)))
        }
    }
}

impl AsInner<c_int> for Socket {
    fn as_inner(&self) -> &c_int { self.0.as_inner() }
}

impl FromInner<c_int> for Socket {
    fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) }
}

impl IntoInner<c_int> for Socket {
    fn into_inner(self) -> c_int { self.0.into_raw() }
}
<commit_msg>Fix argument to FIONBIO ioctl<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ffi::CStr;
use io;
use libc::{self, c_int, size_t, sockaddr, socklen_t};
use net::{SocketAddr, Shutdown};
use str;
use sys::fd::FileDesc;
use sys_common::{AsInner, FromInner, IntoInner};
use sys_common::net::{getsockopt, setsockopt};
use time::Duration;

pub use sys::{cvt, cvt_r};
pub extern crate libc as netc;

pub type wrlen_t = size_t;

// See below for the usage of SOCK_CLOEXEC, but this constant is only defined on
// Linux currently (e.g. support doesn't exist on other platforms). In order to
// get name resolution to work and things to compile we just define a dummy
// SOCK_CLOEXEC here for other platforms. Note that the dummy constant isn't
// actually ever used (the blocks below are wrapped in `if cfg!` as well.
#[cfg(target_os = "linux")]
use libc::SOCK_CLOEXEC;
#[cfg(not(target_os = "linux"))]
const SOCK_CLOEXEC: c_int = 0;

pub struct Socket(FileDesc);

pub fn init() {}

pub fn cvt_gai(err: c_int) -> io::Result<()> {
    if err == 0 { return Ok(()) }

    let detail = unsafe {
        str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap()
            .to_owned()
    };
    Err(io::Error::new(io::ErrorKind::Other,
                       &format!("failed to lookup address information: {}",
                                detail)[..]))
}

impl Socket {
    pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
        let fam = match *addr {
            SocketAddr::V4(..) => libc::AF_INET,
            SocketAddr::V6(..) => libc::AF_INET6,
        };
        Socket::new_raw(fam, ty)
    }

    pub fn new_raw(fam: c_int, ty: c_int) -> io::Result<Socket> {
        unsafe {
            // On linux we first attempt to pass the SOCK_CLOEXEC flag to
            // atomically create the socket and set it as CLOEXEC. Support for
            // this option, however, was added in 2.6.27, and we still support
            // 2.6.18 as a kernel, so if the returned error is EINVAL we
            // fallthrough to the fallback.
            if cfg!(target_os = "linux") {
                match cvt(libc::socket(fam, ty | SOCK_CLOEXEC, 0)) {
                    Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
                    Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {}
                    Err(e) => return Err(e),
                }
            }

            let fd = cvt(libc::socket(fam, ty, 0))?;
            let fd = FileDesc::new(fd);
            fd.set_cloexec()?;
            Ok(Socket(fd))
        }
    }

    pub fn new_pair(fam: c_int, ty: c_int) -> io::Result<(Socket, Socket)> {
        unsafe {
            let mut fds = [0, 0];

            // Like above, see if we can set cloexec atomically
            if cfg!(target_os = "linux") {
                match cvt(libc::socketpair(fam, ty | SOCK_CLOEXEC, 0, fds.as_mut_ptr())) {
                    Ok(_) => {
                        return Ok((Socket(FileDesc::new(fds[0])), Socket(FileDesc::new(fds[1]))));
                    }
                    Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {},
                    Err(e) => return Err(e),
                }
            }

            cvt(libc::socketpair(fam, ty, 0, fds.as_mut_ptr()))?;
            let a = FileDesc::new(fds[0]);
            let b = FileDesc::new(fds[1]);
            a.set_cloexec()?;
            b.set_cloexec()?;
            Ok((Socket(a), Socket(b)))
        }
    }

    pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t)
                  -> io::Result<Socket> {
        // Unfortunately the only known way right now to accept a socket and
        // atomically set the CLOEXEC flag is to use the `accept4` syscall on
        // Linux. This was added in 2.6.28, however, and because we support
        // 2.6.18 we must detect this support dynamically.
        if cfg!(target_os = "linux") {
            weak! {
                fn accept4(c_int, *mut sockaddr, *mut socklen_t, c_int) -> c_int
            }
            if let Some(accept) = accept4.get() {
                let res = cvt_r(|| unsafe {
                    accept(self.0.raw(), storage, len, SOCK_CLOEXEC)
                });
                match res {
                    Ok(fd) => return Ok(Socket(FileDesc::new(fd))),
                    Err(ref e) if e.raw_os_error() == Some(libc::ENOSYS) => {}
                    Err(e) => return Err(e),
                }
            }
        }

        let fd = cvt_r(|| unsafe {
            libc::accept(self.0.raw(), storage, len)
        })?;
        let fd = FileDesc::new(fd);
        fd.set_cloexec()?;
        Ok(Socket(fd))
    }

    pub fn duplicate(&self) -> io::Result<Socket> {
        self.0.duplicate().map(Socket)
    }

    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }

    pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
        self.0.read_to_end(buf)
    }

    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    pub fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> {
        let timeout = match dur {
            Some(dur) => {
                if dur.as_secs() == 0 && dur.subsec_nanos() == 0 {
                    return Err(io::Error::new(io::ErrorKind::InvalidInput,
                                              "cannot set a 0 duration timeout"));
                }

                let secs = if dur.as_secs() > libc::time_t::max_value() as u64 {
                    libc::time_t::max_value()
                } else {
                    dur.as_secs() as libc::time_t
                };
                let mut timeout = libc::timeval {
                    tv_sec: secs,
                    tv_usec: (dur.subsec_nanos() / 1000) as libc::suseconds_t,
                };
                if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
                    timeout.tv_usec = 1;
                }
                timeout
            }
            None => {
                libc::timeval {
                    tv_sec: 0,
                    tv_usec: 0,
                }
            }
        };
        setsockopt(self, libc::SOL_SOCKET, kind, timeout)
    }

    pub fn timeout(&self, kind: libc::c_int) -> io::Result<Option<Duration>> {
        let raw: libc::timeval = getsockopt(self, libc::SOL_SOCKET, kind)?;
        if raw.tv_sec == 0 && raw.tv_usec == 0 {
            Ok(None)
        } else {
            let sec = raw.tv_sec as u64;
            let nsec = (raw.tv_usec as u32) * 1000;
            Ok(Some(Duration::new(sec, nsec)))
        }
    }

    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
        let how = match how {
            Shutdown::Write => libc::SHUT_WR,
            Shutdown::Read => libc::SHUT_RD,
            Shutdown::Both => libc::SHUT_RDWR,
        };
        cvt(unsafe { libc::shutdown(self.0.raw(), how) })?;
        Ok(())
    }

    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
        setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int)
    }

    pub fn nodelay(&self) -> io::Result<bool> {
        let raw: c_int = getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY)?;
        Ok(raw != 0)
    }

    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
        let mut nonblocking = nonblocking as libc::c_int;
        cvt(unsafe { libc::ioctl(*self.as_inner(), libc::FIONBIO, &mut nonblocking) }).map(|_| ())
    }

    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
        let raw: c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)?;
        if raw == 0 {
            Ok(None)
        } else {
            Ok(Some(io::Error::from_raw_os_error(raw as i32)))
        }
    }
}

impl AsInner<c_int> for Socket {
    fn as_inner(&self) -> &c_int { self.0.as_inner() }
}

impl FromInner<c_int> for Socket {
    fn from_inner(fd: c_int) -> Socket { Socket(FileDesc::new(fd)) }
}

impl IntoInner<c_int> for Socket {
    fn into_inner(self) -> c_int { self.0.into_raw() }
}
<|endoftext|>


<commit_before><commit_msg>Show tried paths in ResourceNotFound error message<commit_after><|endoftext|>


<commit_before>use super::*;

impl Editor {
    /// Go to next char
    pub fn next(&mut self) {
        if self.x() == self.text[self.y()].len() {
            if self.y() >= self.text.len() {
                self.text.push_back(VecDeque::new())
            }
            if self.y() < self.text.len() - 1 {
                self.cursor_mut().x = 0;
                self.cursor_mut().y += 1;
            }

        } else {
            self.cursor_mut().x += 1;
        }
    }

    /// Go to previous char
    pub fn previous(&mut self) {
        if self.x() == 0 {
            if self.y() > 0 {
                self.cursor_mut().y -= 1;
                self.cursor_mut().x = self.text[self.y() - 1].len();
            }
        } else {
            self.cursor_mut().y -= 1;
        }

    }

    /// Go right
    pub fn right(&mut self, n: usize) {
        let x = self.x() + n;
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.x += n;

        if x > text[y].len() {
            curs.x = text[y].len();
        }
    }
    /// Go left
    pub fn left(&mut self, n: usize) {
        let x = self.x();
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        if n <= x {
            curs.x = x - n;
        } else {
            curs.x = 0;
        }

    }
    /// Go up
    pub fn up(&mut self, n: usize) {
        let y = self.y();
        let curs = self.cursor_mut();
        if n <= y {
            curs.y -= n;
        } else {
            curs.y = 0;
        }
    }
    /// Go down
    pub fn down(&mut self, n: usize) {
        let x = self.x();
        let y = self.y() + n;

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.y += n;

        if y >= text.len() {
            curs.y = text.len() - 1;
        }
    }
}
<commit_msg>Fix backspace<commit_after>use super::*;

impl Editor {
    /// Go to next char
    pub fn next(&mut self) {
        if self.x() == self.text[self.y()].len() {
            if self.y() >= self.text.len() {
                self.text.push_back(VecDeque::new())
            }
            if self.y() < self.text.len() - 1 {
                self.cursor_mut().x = 0;
                self.cursor_mut().y += 1;
            }

        } else {
            self.cursor_mut().x += 1;
        }
    }

    /// Go to previous char
    pub fn previous(&mut self) {
        if self.x() == 0 {
            if self.y() > 0 {
                self.cursor_mut().y -= 1;
                self.cursor_mut().x = self.text[self.y()].len();
            }
        } else {
            self.cursor_mut().x -= 1;
        }

    }

    /// Go right
    pub fn right(&mut self, n: usize) {
        let x = self.x() + n;
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.x += n;

        if x > text[y].len() {
            curs.x = text[y].len();
        }
    }
    /// Go left
    pub fn left(&mut self, n: usize) {
        let x = self.x();
        let y = self.y();

        let text = self.text.clone();
        let curs = self.cursor_mut();

        if n <= x {
            curs.x = x - n;
        } else {
            curs.x = 0;
        }

    }
    /// Go up
    pub fn up(&mut self, n: usize) {
        let y = self.y();
        let curs = self.cursor_mut();
        if n <= y {
            curs.y -= n;
        } else {
            curs.y = 0;
        }
    }
    /// Go down
    pub fn down(&mut self, n: usize) {
        let x = self.x();
        let y = self.y() + n;

        let text = self.text.clone();
        let curs = self.cursor_mut();

        curs.y += n;

        if y >= text.len() {
            curs.y = text.len() - 1;
        }
    }
}
<|endoftext|>