<commit_before>use std::ptr;
use std::ops;
use std::os::raw::{c_int,c_char,c_uint};
use std::ffi::CStr;

#[repr(C)]
#[derive(PartialEq,Eq,Debug)]
struct LuaMatch {
    start: c_int,
    end: c_int
}

static LUA_MAXCAPTURES: usize = 32;

#[link(name = "lua-str", kind="static")]
extern {
    fn str_match (
        s: *const u8, ls: c_uint, p: *const u8, lp: c_uint,
        err_msg: *mut *mut c_char,
        mm: *mut LuaMatch
        ) -> c_int;
}

pub struct LuaPattern<'a> {
    patt: &'a [u8],
    matches: Vec<LuaMatch>,
    n_match: usize
}

impl <'a> LuaPattern<'a> {
    pub fn new(patt: &'a str) -> LuaPattern<'a> {
        LuaPattern::from_bytes(patt.as_bytes())
    }

    pub fn from_bytes (bytes: &'a [u8]) -> LuaPattern<'a> {
        let mut matches: Vec<LuaMatch> = Vec::with_capacity(LUA_MAXCAPTURES);
        unsafe {matches.set_len(LUA_MAXCAPTURES);}
        LuaPattern{patt: bytes, matches: matches, n_match: 0}
    }

    pub fn matches_bytes(&mut self, s: &[u8]) -> bool {
        let c_ptr: *mut c_char = ptr::null_mut();
        let pvoid = Box::into_raw(Box::new(c_ptr));
        let err_msg : *mut *mut c_char = pvoid;

        unsafe {
           self.n_match = str_match(s.as_ptr(),s.len() as c_uint,
                self.patt.as_ptr(),self.patt.len() as c_uint,
                err_msg, self.matches.as_mut_ptr()) as usize;
            let ep = *err_msg;
            if ! ep.is_null() {
                panic!(format!("lua-pattern {:?}",CStr::from_ptr(ep)));
            }
        }

        self.n_match > 0
    }

    pub fn matches(&mut self, text: &str) -> bool {
        self.matches_bytes(text.as_bytes())
    }

    pub fn captures<'b>(&mut self, text: &'b str) -> Vec<&'b str> {
        let mut res = Vec::new();
        self.capture_into(text, &mut res);
        res
    }

    pub fn match_captures<'b>(&'a mut self, text: &'b str) -> Captures<'a,'b> {
        self.matches(text);
        Captures {m: self, text: text}
    }

    pub fn capture_into<'b>(&mut self, text: &'b str, vec: &mut Vec<&'b str>) -> bool {
        self.matches(text);
        vec.clear();
        for i in 0..self.n_match {
            vec.push(&text[self.capture(i)]);
        }
        self.n_match > 0
    }

    pub fn range(&self) -> ops::Range<usize> {
        self.capture(0)
    }

    pub fn capture(&self, i: usize) -> ops::Range<usize> {
        ops::Range{
            start: self.matches[i].start as usize,
            end: self.matches[i].end as usize
        }
    }

    pub fn first_match<'b>(&mut self, text: &'b str) -> Option<&'b str> {
        self.matches(text);
        if self.n_match > 0 {
            Some(&text[self.capture(if self.n_match > 1 {1} else {0})])
        } else {
            None
        }
    }

    pub fn gmatch<'b>(&'a mut self, text: &'b str) -> GMatch<'a,'b> {
        GMatch{m: self, text: text}
    }

    pub fn gsub <F> (&mut self, text: &str, lookup: F) -> String
    where F: Fn(Captures)-> String {
        let mut slice = text;
        let mut res = String::new();
        while self.matches(slice) {
            // full range of match
            let all = self.range();
            let captures = Captures{m: self, text: slice};
            let repl = lookup(captures);
            // append everything up to match
            res.push_str(&slice[0..all.start]);
            res.push_str(&repl);
            slice = &slice[all.end..];
        }
        res.push_str(slice);
        res
    }

}

pub struct Captures<'a,'b> {
    m: &'a LuaPattern<'a>,
    text: &'b str
}

impl <'a,'b> Captures<'a,'b> {
    pub fn get(&self, i: usize) -> &'b str {
        &self.text[self.m.capture(i)]
    }

    pub fn num_matches(&self) -> usize {
        self.m.n_match
    }
}

pub struct CaptureIter<'a,'b> {
    cc: Captures<'a,'b>,
    idx: usize,
    top: usize
}

impl <'a,'b>Iterator for CaptureIter<'a,'b> {
    type Item = &'b str;

    fn next(&mut self) -> Option<Self::Item> {
        if self.idx < self.top {
            let res = self.cc.get(self.idx);
            self.idx += 1;
            Some(res)
        } else {
            None
        }
    }
}

impl <'a,'b> IntoIterator for Captures<'a,'b> {
    type Item = &'b str;
    type IntoIter = CaptureIter<'a,'b>;

    fn into_iter(self) -> Self::IntoIter {
        CaptureIter{idx: 0, top: self.num_matches(),cc: self}
    }
}

pub struct GMatch<'a,'b> {
    m: &'a mut LuaPattern<'a>,
    text: &'b str
}

impl <'a,'b>Iterator for GMatch<'a,'b> {
    type Item = &'b str;

    fn next(&mut self) -> Option<Self::Item> {
        if ! self.m.matches(self.text) {
            None
        } else {
            let first = if self.m.n_match > 1 {1} else {0};
            let slice = &self.text[self.m.capture(first)];
            self.text = &self.text[self.m.range().end..];
            Some(slice)
        }
    }

}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn captures_and_matching() {
        let mut m = LuaPattern::new("(one).+");
        assert_eq!(m.captures(" one two"), &["one two","one"]);
        let empty: &[&str] = &[];
        assert_eq!(m.captures("four"), empty);

        assert_eq!(m.matches("one dog"), true);
        assert_eq!(m.matches("dog one "), true);
        assert_eq!(m.matches("dog one"), false);

        let text = "one dog";
        let mut m = LuaPattern::new("^(%a+)");
        assert_eq!(m.matches(text), true);
        assert_eq!(&text[m.capture(1)], "one");
        assert_eq!(m.matches(" one dog"), false);

        // captures without allocation
        let captures = m.match_captures(text);
        assert_eq!(captures.get(0), "one");
        assert_eq!(captures.get(1), "one");

        let mut m = LuaPattern::new("(%S+)%s*=%s*(.+)");

        //  captures as Vec
        let cc = m.captures(" hello= bonzo dog");
        assert_eq!(cc[0], "hello= bonzo dog");
        assert_eq!(cc[1], "hello");
        assert_eq!(cc[2], "bonzo dog");

        // captures as iterator
        let mut iter = m.match_captures(" frodo = baggins").into_iter();
        assert_eq!(iter.next(), Some("frodo = baggins"));
        assert_eq!(iter.next(), Some("frodo"));
        assert_eq!(iter.next(), Some("baggins"));
        assert_eq!(iter.next(), None);

    }

    #[test]
    fn gmatch() {
        let mut m = LuaPattern::new("%a+");
        let mut iter = m.gmatch("one two three");
        assert_eq!(iter.next(), Some("one"));
        assert_eq!(iter.next(), Some("two"));
        assert_eq!(iter.next(), Some("three"));
        assert_eq!(iter.next(), None);

        let mut m = LuaPattern::new("(%a+)");
        let mut iter = m.gmatch("one two three");
        assert_eq!(iter.next(), Some("one"));
        assert_eq!(iter.next(), Some("two"));
        assert_eq!(iter.next(), Some("three"));
        assert_eq!(iter.next(), None);

    }

    #[test]
    fn gsub() {
        use std::collections::HashMap;

        let mut m = LuaPattern::new("%$(%S+)");
        let res = m.gsub("hello $dolly you're so $fine!",
            |cc| cc.get(1).to_uppercase()
        );
        assert_eq!(res,"hello DOLLY you're so FINE!");

        let mut map = HashMap::new();
        map.insert("dolly", "baby");
        map.insert("fine", "cool");
        map.insert("good-looking", "pretty");

        let mut m = LuaPattern::new("%$%((.-)%)");
        let res = m.gsub("hello $(dolly) you're so $(fine) and $(good-looking)",
            |cc| map.get(cc.get(1)).unwrap_or(&"?").to_string()
        );
        assert_eq!(res,"hello baby you're so cool and pretty");

    }
}
<commit_msg>added iterator over byte slice matches<commit_after>use std::ptr;
use std::ops;
use std::os::raw::{c_int,c_char,c_uint};
use std::ffi::CStr;

#[repr(C)]
struct LuaMatch {
    start: c_int,
    end: c_int
}

static LUA_MAXCAPTURES: usize = 32;

#[link(name = "lua-str", kind="static")]
extern {
    fn str_match (
        s: *const u8, ls: c_uint, p: *const u8, lp: c_uint,
        err_msg: *mut *mut c_char,
        mm: *mut LuaMatch
        ) -> c_int;
}

/// Represents a Lua string pattern and the results of a match
pub struct LuaPattern<'a> {
    patt: &'a [u8],
    matches: Vec<LuaMatch>,
    n_match: usize
}

impl <'a> LuaPattern<'a> {
    /// Create a new Lua pattern from a string
    pub fn new(patt: &'a str) -> LuaPattern<'a> {
        LuaPattern::from_bytes(patt.as_bytes())
    }

    /// Create a new Lua pattern from a slice of bytes
    pub fn from_bytes (bytes: &'a [u8]) -> LuaPattern<'a> {
        let mut matches: Vec<LuaMatch> = Vec::with_capacity(LUA_MAXCAPTURES);
        unsafe {matches.set_len(LUA_MAXCAPTURES);}
        LuaPattern{patt: bytes, matches: matches, n_match: 0}
    }

    /// Match a slice of bytes with a pattern
    pub fn matches_bytes(&mut self, s: &[u8]) -> bool {
        let c_ptr: *mut c_char = ptr::null_mut();
        let pvoid = Box::into_raw(Box::new(c_ptr));
        let err_msg : *mut *mut c_char = pvoid;

        unsafe {
           self.n_match = str_match(s.as_ptr(),s.len() as c_uint,
                self.patt.as_ptr(),self.patt.len() as c_uint,
                err_msg, self.matches.as_mut_ptr()) as usize;
            let ep = *err_msg;
            if ! ep.is_null() {
                panic!(format!("lua-pattern {:?}",CStr::from_ptr(ep)));
            }
        }

        self.n_match > 0
    }

    /// Match a string with a pattern
    pub fn matches(&mut self, text: &str) -> bool {
        self.matches_bytes(text.as_bytes())
    }

    /// Collect all captures of this match as a vector of strings.
    pub fn captures<'b>(&mut self, text: &'b str) -> Vec<&'b str> {
        let mut res = Vec::new();
        self.capture_into(text, &mut res);
        res
    }

    pub fn match_captures<'b>(&'a mut self, text: &'b str) -> Captures<'a,'b> {
        self.matches(text);
        Captures {m: self, text: text}
    }

    /// Collect all captures of this match into the provided vector.
    pub fn capture_into<'b>(&mut self, text: &'b str, vec: &mut Vec<&'b str>) -> bool {
        self.matches(text);
        vec.clear();
        for i in 0..self.n_match {
            vec.push(&text[self.capture(i)]);
        }
        self.n_match > 0
    }

    /// The full match (same as `capture(0)`)
    pub fn range(&self) -> ops::Range<usize> {
        self.capture(0)
    }

    /// Get the nth capture of the match.
    pub fn capture(&self, i: usize) -> ops::Range<usize> {
        ops::Range{
            start: self.matches[i].start as usize,
            end: self.matches[i].end as usize
        }
    }

    pub fn first_match<'b>(&mut self, text: &'b str) -> Option<&'b str> {
        self.matches(text);
        if self.n_match > 0 {
            Some(&text[self.capture(if self.n_match > 1 {1} else {0})])
        } else {
            None
        }
    }

    /// An iterator over all matches in a string.
    pub fn gmatch<'b>(&'a mut self, text: &'b str) -> GMatch<'a,'b> {
        GMatch{m: self, text: text}
    }

    /// An iterator over all matches in a slice of bytes.
    pub fn gmatch_bytes<'b>(&'a mut self, bytes: &'b [u8]) -> GMatchBytes<'a,'b> {
        GMatchBytes{m: self, bytes: bytes}
    }

    /// Globally substitute ('gsub') all matches with a replacement
    /// string.
    pub fn gsub <F> (&mut self, text: &str, lookup: F) -> String
    where F: Fn(Captures)-> String {
        let mut slice = text;
        let mut res = String::new();
        while self.matches(slice) {
            // full range of match
            let all = self.range();
            let captures = Captures{m: self, text: slice};
            let repl = lookup(captures);
            // append everything up to match
            res.push_str(&slice[0..all.start]);
            res.push_str(&repl);
            slice = &slice[all.end..];
        }
        res.push_str(slice);
        res
    }
}

/// Low-overhead convenient access to match captures
pub struct Captures<'a,'b> {
    m: &'a LuaPattern<'a>,
    text: &'b str
}

impl <'a,'b> Captures<'a,'b> {
    /// get the capture as a string slice
    pub fn get(&self, i: usize) -> &'b str {
        &self.text[self.m.capture(i)]
    }

    /// number of matches
    pub fn num_matches(&self) -> usize {
        self.m.n_match
    }
}

/// Iterator over all captures
pub struct CaptureIter<'a,'b> {
    cc: Captures<'a,'b>,
    idx: usize,
    top: usize
}

impl <'a,'b>Iterator for CaptureIter<'a,'b> {
    type Item = &'b str;

    fn next(&mut self) -> Option<Self::Item> {
        if self.idx < self.top {
            let res = self.cc.get(self.idx);
            self.idx += 1;
            Some(res)
        } else {
            None
        }
    }
}

impl <'a,'b> IntoIterator for Captures<'a,'b> {
    type Item = &'b str;
    type IntoIter = CaptureIter<'a,'b>;

    fn into_iter(self) -> Self::IntoIter {
        CaptureIter{idx: 0, top: self.num_matches(),cc: self}
    }
}

/// Iterator for gmatch
pub struct GMatch<'a,'b> {
    m: &'a mut LuaPattern<'a>,
    text: &'b str
}

impl <'a,'b>Iterator for GMatch<'a,'b> {
    type Item = &'b str;

    fn next(&mut self) -> Option<Self::Item> {
        if ! self.m.matches(self.text) {
            None
        } else {
            let first = if self.m.n_match > 1 {1} else {0};
            let slice = &self.text[self.m.capture(first)];
            self.text = &self.text[self.m.range().end..];
            Some(slice)
        }
    }

}

/// Iterator for gmatch_bytes
pub struct GMatchBytes<'a,'b> {
    m: &'a mut LuaPattern<'a>,
    bytes: &'b [u8]
}

impl <'a,'b>Iterator for GMatchBytes<'a,'b> {
    type Item = &'b [u8];

    fn next(&mut self) -> Option<Self::Item> {
        if ! self.m.matches_bytes(self.bytes) {
            None
        } else {
            let first = if self.m.n_match > 1 {1} else {0};
            let slice = &self.bytes[self.m.capture(first)];
            self.bytes = &self.bytes[self.m.range().end..];
            Some(slice)
        }
    }

}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn captures_and_matching() {
        let mut m = LuaPattern::new("(one).+");
        assert_eq!(m.captures(" one two"), &["one two","one"]);
        let empty: &[&str] = &[];
        assert_eq!(m.captures("four"), empty);

        assert_eq!(m.matches("one dog"), true);
        assert_eq!(m.matches("dog one "), true);
        assert_eq!(m.matches("dog one"), false);

        let text = "one dog";
        let mut m = LuaPattern::new("^(%a+)");
        assert_eq!(m.matches(text), true);
        assert_eq!(&text[m.capture(1)], "one");
        assert_eq!(m.matches(" one dog"), false);

        // captures without allocation
        let captures = m.match_captures(text);
        assert_eq!(captures.get(0), "one");
        assert_eq!(captures.get(1), "one");

        let mut m = LuaPattern::new("(%S+)%s*=%s*(.+)");

        //  captures as Vec
        let cc = m.captures(" hello= bonzo dog");
        assert_eq!(cc[0], "hello= bonzo dog");
        assert_eq!(cc[1], "hello");
        assert_eq!(cc[2], "bonzo dog");

        // captures as iterator
        let mut iter = m.match_captures(" frodo = baggins").into_iter();
        assert_eq!(iter.next(), Some("frodo = baggins"));
        assert_eq!(iter.next(), Some("frodo"));
        assert_eq!(iter.next(), Some("baggins"));
        assert_eq!(iter.next(), None);

    }

    #[test]
    fn gmatch() {
        let mut m = LuaPattern::new("%a+");
        let mut iter = m.gmatch("one two three");
        assert_eq!(iter.next(), Some("one"));
        assert_eq!(iter.next(), Some("two"));
        assert_eq!(iter.next(), Some("three"));
        assert_eq!(iter.next(), None);

        let mut m = LuaPattern::new("(%a+)");
        let mut iter = m.gmatch("one two three");
        assert_eq!(iter.next(), Some("one"));
        assert_eq!(iter.next(), Some("two"));
        assert_eq!(iter.next(), Some("three"));
        assert_eq!(iter.next(), None);

    }

    #[test]
    fn gsub() {
        use std::collections::HashMap;

        let mut m = LuaPattern::new("%$(%S+)");
        let res = m.gsub("hello $dolly you're so $fine!",
            |cc| cc.get(1).to_uppercase()
        );
        assert_eq!(res,"hello DOLLY you're so FINE!");

        let mut map = HashMap::new();
        map.insert("dolly", "baby");
        map.insert("fine", "cool");
        map.insert("good-looking", "pretty");

        let mut m = LuaPattern::new("%$%((.-)%)");
        let res = m.gsub("hello $(dolly) you're so $(fine) and $(good-looking)",
            |cc| map.get(cc.get(1)).unwrap_or(&"?").to_string()
        );
        assert_eq!(res,"hello baby you're so cool and pretty");

    }
}
<|endoftext|>


<commit_before><commit_msg>Add mark/sweep functionality to ScopeManager, wrapping calls in AllocBox<commit_after><|endoftext|>


<commit_before><commit_msg>Error should implement Debug so we can unwrap results<commit_after><|endoftext|>


<commit_before><commit_msg>refactor helpers<commit_after><|endoftext|>


<commit_before>#[derive(Debug, PartialEq, Eq)]
struct Status {
    untracked: bool,
    unstaged: bool,
    staged: bool,
    ahead: bool,
    behind: bool,
    branch: String,
    upstream: String,
}

impl Status {
    fn new(status_txt: &str) -> Result<Status, &'static str> {
        let mut s = Status {
            untracked: false,
            unstaged: false,
            staged: false,
            ahead: false,
            behind: false,
            branch: String::new(),
            upstream: String::new(),
        };
        for line in status_txt.lines() {
            if line.starts_with("?") {
                s.untracked = true;
            }
            if line.starts_with("1 .M") {
                s.unstaged = true;
            }
            if line.starts_with("1 M.") {
                s.staged = true;
            }
            if line.starts_with("# branch.head") {
                let v: Vec<&str> = line.split(' ').collect();
                s.branch = String::from(v[2]);
            }
            if line.starts_with("# branch.upstream") {
                let v: Vec<&str> = line.split(' ').collect();
                s.upstream = String::from(v[2]);
            }
            if line.starts_with("# branch.ab") {
                let v: Vec<&str> = line.split(' ').collect();
                if v[2] != "+0" {
                    s.ahead = true;
                }
                if v[3] != "-0" {
                    s.behind = true;
                }
            }
        }
        Ok(s)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn parse_dirty() {
        let test_status = "\
# branch.oid 3845e7a3c3aadaaebb2d1b261bf07a9357d35a79
# branch.head master
# branch.upstream origin/master
# branch.ab +1 -1
1 M. N... 100644 100644 100644 1290f45e7ad7575848a436d8febbd6c4ba07f1f3 311c77295c5b6056f4599c2b8d0a019d4c76746a README.md
1 .M N... 100644 100644 100644 5e8a8090976077ddf16252a560460a20dbbdd6a5 5e8a8090976077ddf16252a560460a20dbbdd6a5 gh-pages.sh
? foo.txt
";
        assert_eq!(
            Status::new(&test_status).unwrap(),
            Status {
                untracked: true,
                unstaged: true,
                staged: true,
                branch: String::from("master"),
                upstream: String::from("origin/master"),
                ahead: true,
                behind: true,
            }
        );
    }

    #[test]
    fn parse_clean() {
        let test_status = "\
# branch.oid 3845e7a3c3aadaaebb2d1b261bf07a9357d35a79
# branch.head master
# branch.upstream origin/master
# branch.ab +0 -0
";
        assert_eq!(
            Status::new(&test_status).unwrap(),
            Status {
                untracked: false,
                unstaged: false,
                staged: false,
                branch: String::from("master"),
                upstream: String::from("origin/master"),
                ahead: false,
                behind: false,
            }
        );
    }
}
<commit_msg>Detect unstaged and staged changes on same file<commit_after>#[derive(Debug, PartialEq, Eq)]
struct Status {
    untracked: bool,
    unstaged: bool,
    staged: bool,
    ahead: bool,
    behind: bool,
    branch: String,
    upstream: String,
}

impl Status {
    fn new(status_txt: &str) -> Result<Status, &'static str> {
        let mut s = Status {
            untracked: false,
            unstaged: false,
            staged: false,
            ahead: false,
            behind: false,
            branch: String::new(),
            upstream: String::new(),
        };
        for line in status_txt.lines() {
            if line.starts_with("?") {
                s.untracked = true;
            }
            if line.starts_with("1 .M") {
                s.unstaged = true;
            }
            if line.starts_with("1 M.") {
                s.staged = true;
            }
            if line.starts_with("1 MM") {
                s.unstaged = true;
                s.staged = true;
            }
            if line.starts_with("# branch.head") {
                let v: Vec<&str> = line.split(' ').collect();
                s.branch = String::from(v[2]);
            }
            if line.starts_with("# branch.upstream") {
                let v: Vec<&str> = line.split(' ').collect();
                s.upstream = String::from(v[2]);
            }
            if line.starts_with("# branch.ab") {
                let v: Vec<&str> = line.split(' ').collect();
                if v[2] != "+0" {
                    s.ahead = true;
                }
                if v[3] != "-0" {
                    s.behind = true;
                }
            }
        }
        Ok(s)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn parse_dirty() {
        let test_status = "\
# branch.oid 3845e7a3c3aadaaebb2d1b261bf07a9357d35a79
# branch.head master
# branch.upstream origin/master
# branch.ab +1 -1
1 M. N... 100644 100644 100644 1290f45e7ad7575848a436d8febbd6c4ba07f1f3 311c77295c5b6056f4599c2b8d0a019d4c76746a README.md
1 .M N... 100644 100644 100644 5e8a8090976077ddf16252a560460a20dbbdd6a5 5e8a8090976077ddf16252a560460a20dbbdd6a5 gh-pages.sh
? foo.txt
";
        assert_eq!(
            Status::new(&test_status).unwrap(),
            Status {
                untracked: true,
                unstaged: true,
                staged: true,
                branch: String::from("master"),
                upstream: String::from("origin/master"),
                ahead: true,
                behind: true,
            }
        );
    }

    #[test]
    fn parse_clean() {
        let test_status = "\
# branch.oid 3845e7a3c3aadaaebb2d1b261bf07a9357d35a79
# branch.head master
# branch.upstream origin/master
# branch.ab +0 -0
";
        assert_eq!(
            Status::new(&test_status).unwrap(),
            Status {
                untracked: false,
                unstaged: false,
                staged: false,
                branch: String::from("master"),
                upstream: String::from("origin/master"),
                ahead: false,
                behind: false,
            }
        );
    }

    #[test]
    fn parse_staged_and_unstaged_changes_on_same_file() {
        let test_status = "\
# branch.oid 3845e7a3c3aadaaebb2d1b261bf07a9357d35a79
# branch.head master
# branch.upstream origin/master
# branch.ab +0 -0
1 MM N... 100644 100644 100644 1290f45e7ad7575848a436d8febbd6c4ba07f1f3 311c77295c5b6056f4599c2b8d0a019d4c76746a README.md
";
        assert_eq!(
            Status::new(&test_status).unwrap(),
            Status {
                untracked: false,
                unstaged: true,
                staged: true,
                branch: String::from("master"),
                upstream: String::from("origin/master"),
                ahead: false,
                behind: false,
            }
        );
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
#![macro_escape]

use std::fmt;
use std::mem;
use std::ops::Index;
use std::raw::Slice;
use std::slice::AsSlice;
use matrix::Matrix;

pub struct Mat<T> {
    rows: uint,
    cols: uint,
    data: Vec<T>,
}

impl<T> Mat<T> {
    #[inline]
    pub fn new() -> Mat<T> {
        let _data: Vec<T> = Vec::new();
        Mat { rows: 0, cols: 0, data: _data }
    }

    #[inline]
    pub fn zero(rows: uint, cols: uint) -> Mat<T> {
        let mut _data: Vec<T> = Vec::with_capacity(rows * cols);
        unsafe { _data.set_len(rows * cols); }
        Mat { rows: rows, cols: cols, data: _data}
    }

    #[inline]
    pub fn push(&mut self, value: T) {
        self.data.push(value);
    }

    #[inline]
    pub fn rows(&self) -> uint {
        self.rows
    }

    #[inline]
    pub fn cols(&self) -> uint {
        self.cols
    }

    #[inline]
    pub unsafe fn set_rows(&mut self, rows: uint) {
        self.rows = rows;
    }

    #[inline]
    pub unsafe fn set_cols(&mut self, cols: uint) {
        self.cols = cols;
    }

    #[inline]
    pub unsafe fn as_slice<'a>(&'a self) -> &'a [T] {
        self.data.as_slice()
    }

    #[inline]
    pub unsafe fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        self.data.as_mut_slice()
    }
}

impl<T> Index<uint, [T]> for Mat<T> {
    fn index<'a>(&'a self, index: &uint) -> &'a [T] {
        unsafe {
            let ptr = self.data.as_slice().as_ptr().offset((*index * self.cols) as int);
            mem::transmute(Slice { data: ptr, len: self.cols })
        }
    }
}

impl<T: fmt::Show> fmt::Show for Mat<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for i in range(0u, self.rows) {
            match writeln!(f, "{}", &self[i]) {
                Ok(_) => (),
                x => return x,
            }
        }

        Ok(())
    }
}

#[macro_export]
macro_rules! mat(
    ($([$($e: expr),+]),*) => ({
        // leading _ to allow empty construction without a warning.
        let mut _temp = Mat::new();
        let mut rows = 0u;
        let mut _cols;
        $(
            rows += 1;
            _cols = 0u;
            $(
                _cols += 1;
                _temp.push($e);
            )+
        )*

        unsafe {
            _temp.set_rows(rows);
            _temp.set_cols(_cols);
        }

        _temp
    });
)

#[cfg(test)]
mod tests {
    extern crate test;

    use mat::Mat;

    #[test]
    fn index() {
        let m = mat![[1f32,2f32],[3f32,4f32]];

        assert_eq!(1.0, m[0][0]);
        assert_eq!(2.0, m[0][1]);
        assert_eq!(3.0, m[1][0]);
        assert_eq!(4.0, m[1][1]);
    }
}
<commit_msg>Implement PartialEq for Mat<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
#![macro_escape]

use std::fmt;
use std::mem;
use std::ops::Index;
use std::raw::Slice;
use std::slice::AsSlice;
use matrix::Matrix;

pub struct Mat<T> {
    rows: uint,
    cols: uint,
    data: Vec<T>,
}

impl<T> Mat<T> {
    #[inline]
    pub fn new() -> Mat<T> {
        let _data: Vec<T> = Vec::new();
        Mat { rows: 0, cols: 0, data: _data }
    }

    #[inline]
    pub fn zero(rows: uint, cols: uint) -> Mat<T> {
        let mut _data: Vec<T> = Vec::with_capacity(rows * cols);
        unsafe { _data.set_len(rows * cols); }
        Mat { rows: rows, cols: cols, data: _data}
    }

    #[inline]
    pub fn push(&mut self, value: T) {
        self.data.push(value);
    }

    #[inline]
    pub fn rows(&self) -> uint {
        self.rows
    }

    #[inline]
    pub fn cols(&self) -> uint {
        self.cols
    }

    #[inline]
    pub unsafe fn set_rows(&mut self, rows: uint) {
        self.rows = rows;
    }

    #[inline]
    pub unsafe fn set_cols(&mut self, cols: uint) {
        self.cols = cols;
    }

    #[inline]
    pub unsafe fn as_slice<'a>(&'a self) -> &'a [T] {
        self.data.as_slice()
    }

    #[inline]
    pub unsafe fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
        self.data.as_mut_slice()
    }
}

impl<T: PartialEq> PartialEq for Mat<T> {
    fn eq(&self, other: &Mat<T>) -> bool {
        self.rows == other.rows &&
        self.cols == other.cols &&
        self.data == other.data
    }
}

impl<T> Index<uint, [T]> for Mat<T> {
    fn index<'a>(&'a self, index: &uint) -> &'a [T] {
        unsafe {
            let ptr = self.data.as_slice().as_ptr().offset((*index * self.cols) as int);
            mem::transmute(Slice { data: ptr, len: self.cols })
        }
    }
}

impl<T: fmt::Show> fmt::Show for Mat<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for i in range(0u, self.rows) {
            match writeln!(f, "{}", &self[i]) {
                Ok(_) => (),
                x => return x,
            }
        }

        Ok(())
    }
}

#[macro_export]
macro_rules! mat(
    ($([$($e: expr),+]),*) => ({
        // leading _ to allow empty construction without a warning.
        let mut _temp = Mat::new();
        let mut rows = 0u;
        let mut _cols;
        $(
            rows += 1;
            _cols = 0u;
            $(
                _cols += 1;
                _temp.push($e);
            )+
        )*

        unsafe {
            _temp.set_rows(rows);
            _temp.set_cols(_cols);
        }

        _temp
    });
)

#[cfg(test)]
mod tests {
    extern crate test;

    use mat::Mat;

    #[test]
    fn index() {
        let m = mat![[1f32,2f32],[3f32,4f32]];

        assert_eq!(1.0, m[0][0]);
        assert_eq!(2.0, m[0][1]);
        assert_eq!(3.0, m[1][0]);
        assert_eq!(4.0, m[1][1]);
    }
}
<|endoftext|>


<commit_before>use super::mpz::{mpz_struct, Mpz, mpz_ptr, mpz_srcptr};
use super::mpf::{Mpf, mpf_srcptr};
use ffi::*;
use libc::{c_double, c_int, c_ulong};
use std::convert::{From, Into};
use std::mem::uninitialized;
use std::fmt;
use std::cmp::Ordering::{self, Greater, Less, Equal};
use std::ops::{Div, Mul, Add, Sub, Neg};

#[repr(C)]
pub struct mpq_struct {
    _mp_num: mpz_struct,
    _mp_den: mpz_struct
}

pub type mpq_srcptr = *const mpq_struct;
pub type mpq_ptr = *mut mpq_struct;

#[link(name = "gmp")]
extern "C" {
    fn __gmpq_init(x: mpq_ptr);
    fn __gmpq_clear(x: mpq_ptr);
    fn __gmpq_set(rop: mpq_ptr, op: mpq_srcptr);
    fn __gmpq_set_z(rop: mpq_ptr, op: mpz_srcptr);
    fn __gmpq_set_ui(rop: mpq_ptr, op1: c_ulong, op2: c_ulong);
    fn __gmpq_set_d(rop: mpq_ptr, op: c_double);
    fn __gmpq_set_f(rop: mpq_ptr, op: mpf_srcptr);
    fn __gmpq_cmp(op1: mpq_srcptr, op2: mpq_srcptr) -> c_int;
    fn __gmpq_cmp_ui(op1: mpq_srcptr, num2: c_ulong, den2: c_ulong) -> c_int;
    fn __gmpq_equal(op1: mpq_srcptr, op2: mpq_srcptr) -> c_int;
    fn __gmpq_add(sum: mpq_ptr, addend1: mpq_srcptr, addend2: mpq_srcptr);
    fn __gmpq_sub(difference: mpq_ptr, minuend: mpq_srcptr, subtrahend: mpq_srcptr);
    fn __gmpq_mul(product: mpq_ptr, multiplier: mpq_srcptr, multiplicand: mpq_srcptr);
    fn __gmpq_div(product: mpq_ptr, multiplier: mpq_srcptr, multiplicand: mpq_srcptr);
    fn __gmpq_neg(negated_operand: mpq_ptr, operand: mpq_srcptr);
    fn __gmpq_abs(rop: mpq_ptr, op: mpq_srcptr);
    fn __gmpq_inv(inverted_number: mpq_ptr, number: mpq_srcptr);
    fn __gmpq_get_num(numerator: mpz_ptr, rational: mpq_srcptr);
    fn __gmpq_get_den(denominator: mpz_ptr, rational: mpq_srcptr);
    fn __gmpq_set_num(rational: mpq_ptr, numerator: mpz_srcptr);
    fn __gmpq_set_den(rational: mpq_ptr, denominator: mpz_srcptr);
    fn __gmpq_canonicalize(rational: mpq_ptr);
    fn __gmpq_get_d(rational: mpq_srcptr) -> c_double;
}

pub struct Mpq {
    mpq: mpq_struct,
}

unsafe impl Send for Mpq { }

impl Drop for Mpq {
    fn drop(&mut self) { unsafe { __gmpq_clear(&mut self.mpq) } }
}

impl Mpq {
    pub unsafe fn inner(&self) -> mpq_srcptr {
        &self.mpq
    }

    pub unsafe fn inner_mut(&mut self) -> mpq_ptr {
        &mut self.mpq
    }

    pub fn new() -> Mpq {
        unsafe {
            let mut mpq = uninitialized();
            __gmpq_init(&mut mpq);
            Mpq { mpq: mpq }
        }
    }

    pub fn ratio(num: &Mpz, den: &Mpz) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_set_num(&mut res.mpq, num.inner());
            __gmpq_set_den(&mut res.mpq, den.inner());
            res
        }
    }

    pub fn canonicalize(&mut self) {
        unsafe {
            __gmpq_canonicalize(&mut self.mpq);
        }
    }

    pub fn set(&mut self, other: &Mpq) {
        unsafe { __gmpq_set(&mut self.mpq, &other.mpq) }
    }

    pub fn set_z(&mut self, other: &Mpz) {
        unsafe { __gmpq_set_z(&mut self.mpq, other.inner()) }
    }

    pub fn set_d(&mut self, other: f64) {
        unsafe { __gmpq_set_d(&mut self.mpq, other) }
    }

    pub fn set_f(&mut self, other: &Mpf) {
        unsafe { __gmpq_set_f(&mut self.mpq, other.inner()) }
    }

    pub fn get_num(&self) -> Mpz {
        unsafe {
            let mut res = Mpz::new();
            __gmpq_get_num(res.inner_mut(), &self.mpq);
            res
        }
    }

    pub fn get_den(&self) -> Mpz {
        unsafe {
            let mut res = Mpz::new();
            __gmpq_get_den(res.inner_mut(), &self.mpq);
            res
        }
    }

    pub fn abs(&self) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_abs(&mut res.mpq, &self.mpq);
            res
        }
    }

    pub fn invert(&self) -> Mpq {
        unsafe {
            if self.is_zero() {
                panic!("divide by zero")
            }

            let mut res = Mpq::new();
            __gmpq_inv(&mut res.mpq, &self.mpq);
            res
        }
    }

    pub fn floor(&self) -> Mpz {
        let mut res = Mpz::new();
        unsafe {
            __gmpz_fdiv_q(res.inner_mut(), &self.mpq._mp_num, &self.mpq._mp_den);
        }
        res
    }

    pub fn ceil(&self) -> Mpz {
        let mut res = Mpz::new();
        unsafe {
            __gmpz_cdiv_q(res.inner_mut(), &self.mpq._mp_num, &self.mpq._mp_den);
        }
        res
    }

    pub fn one() -> Mpq {
        let mut res = Mpq::new();
        unsafe { __gmpq_set_ui(&mut res.mpq, 1, 1) }
        res
    }

    pub fn zero() -> Mpq { Mpq::new() }
    pub fn is_zero(&self) -> bool {
        unsafe { __gmpq_cmp_ui(&self.mpq, 0, 1) == 0 }
    }
}

impl Clone for Mpq {
    fn clone(&self) -> Mpq {
        let mut res = Mpq::new();
        res.set(self);
        res
    }
}

impl Eq for Mpq { }
impl PartialEq for Mpq {
    fn eq(&self, other: &Mpq) -> bool {
        unsafe { __gmpq_equal(&self.mpq, &other.mpq) != 0 }
    }
}

impl Ord for Mpq {
    fn cmp(&self, other: &Mpq) -> Ordering {
        let cmp = unsafe { __gmpq_cmp(&self.mpq, &other.mpq) };
        if cmp == 0 {
            Equal
        } else if cmp < 0 {
            Less
        } else {
            Greater
        }
    }
}
impl PartialOrd for Mpq {
    fn partial_cmp(&self, other: &Mpq) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'a, 'b> Add<&'a Mpq> for &'b Mpq {
    type Output = Mpq;
    fn add(self, other: &Mpq) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_add(&mut res.mpq, &self.mpq, &other.mpq);
            res
        }
    }
}

impl<'a> Add<&'a Mpq> for Mpq {
    type Output = Mpq;
    #[inline]
    fn add(mut self, other: &Mpq) -> Mpq {
        unsafe {
            __gmpq_add(&mut self.mpq, &self.mpq, &other.mpq);
            self
        }
    }
}

impl<'a, 'b> Sub<&'a Mpq> for &'b Mpq {
    type Output = Mpq;
    fn sub(self, other: &Mpq) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_sub(&mut res.mpq, &self.mpq, &other.mpq);
            res
        }
    }
}

impl<'a> Sub<&'a Mpq> for Mpq {
    type Output = Mpq;
    #[inline]
    fn sub(mut self, other: &Mpq) -> Mpq {
        unsafe {
            __gmpq_sub(&mut self.mpq, &self.mpq, &other.mpq);
            self
        }
    }
}

impl<'a, 'b> Mul<&'a Mpq> for &'b Mpq {
    type Output = Mpq;
    fn mul(self, other: &Mpq) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_mul(&mut res.mpq, &self.mpq, &other.mpq);
            res
        }
    }
}

impl<'a> Mul<&'a Mpq> for Mpq {
    type Output = Mpq;
    #[inline]
    fn mul(mut self, other: &Mpq) -> Mpq {
        unsafe {
            __gmpq_mul(&mut self.mpq, &self.mpq, &other.mpq);
            self
        }
    }
}

impl<'a, 'b> Div<&'a Mpq> for &'b Mpq {
    type Output = Mpq;
    fn div(self, other: &Mpq) -> Mpq {
        unsafe {
            if other.is_zero() {
                panic!("divide by zero")
            }

            let mut res = Mpq::new();
            __gmpq_div(&mut res.mpq, &self.mpq, &other.mpq);
            res
        }
    }
}

impl<'a> Div<&'a Mpq> for Mpq {
    type Output = Mpq;
    #[inline]
    fn div(mut self, other: &Mpq) -> Mpq {
        unsafe {
            if other.is_zero() {
                panic!("divide by zero")
            }

            __gmpq_div(&mut self.mpq, &self.mpq, &other.mpq);
            self
        }
    }
}

impl<'b> Neg for &'b Mpq {
    type Output = Mpq;
    fn neg(self) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_neg(&mut res.mpq, &self.mpq);
            res
        }
    }
}

impl Neg for Mpq {
    type Output = Mpq;
    #[inline]
    fn neg(mut self) -> Mpq {
        unsafe {
            __gmpq_neg(&mut self.mpq, &self.mpq);
            self
        }
    }
}

impl Into<Option<i64>> for Mpq {
    fn into(self) -> Option<i64> {
        panic!("not implemented")
    }
}

impl Into<Option<u64>> for Mpq {
    fn into(self) -> Option<u64> {
        panic!("not implemented")
    }
}

impl Into<f64> for Mpq {
    fn into(self) -> f64 {
        unsafe {
            __gmpq_get_d(&self.mpq) as f64
        }
    }
}

impl From<i64> for Mpq {
    fn from(other: i64) -> Mpq {
        let mut res = Mpq::new();
        res.set_z(&From::<i64>::from(other));
        res
    }
}

impl From<u64> for Mpq {
    fn from(other: u64) -> Mpq {
        let mut res = Mpq::new();
        res.set_z(&From::<u64>::from(other));
        res
    }
}

impl fmt::Debug for Mpq {
    /// Renders as `numer/denom`. If denom=1, renders as numer.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let numer = self.get_num();
        let denom = self.get_den();

        if denom == From::<i64>::from(1) {
            write!(f, "{}", numer)
        } else {
            write!(f, "{}/{}", numer, denom)
        }
    }
}

gen_overloads!(Mpq);
<commit_msg>Mpq: Implement From<i32>, From<u32><commit_after>use super::mpz::{mpz_struct, Mpz, mpz_ptr, mpz_srcptr};
use super::mpf::{Mpf, mpf_srcptr};
use ffi::*;
use libc::{c_double, c_int, c_ulong};
use std::convert::{From, Into};
use std::mem::uninitialized;
use std::fmt;
use std::cmp::Ordering::{self, Greater, Less, Equal};
use std::ops::{Div, Mul, Add, Sub, Neg};

#[repr(C)]
pub struct mpq_struct {
    _mp_num: mpz_struct,
    _mp_den: mpz_struct
}

pub type mpq_srcptr = *const mpq_struct;
pub type mpq_ptr = *mut mpq_struct;

#[link(name = "gmp")]
extern "C" {
    fn __gmpq_init(x: mpq_ptr);
    fn __gmpq_clear(x: mpq_ptr);
    fn __gmpq_set(rop: mpq_ptr, op: mpq_srcptr);
    fn __gmpq_set_z(rop: mpq_ptr, op: mpz_srcptr);
    fn __gmpq_set_ui(rop: mpq_ptr, op1: c_ulong, op2: c_ulong);
    fn __gmpq_set_d(rop: mpq_ptr, op: c_double);
    fn __gmpq_set_f(rop: mpq_ptr, op: mpf_srcptr);
    fn __gmpq_cmp(op1: mpq_srcptr, op2: mpq_srcptr) -> c_int;
    fn __gmpq_cmp_ui(op1: mpq_srcptr, num2: c_ulong, den2: c_ulong) -> c_int;
    fn __gmpq_equal(op1: mpq_srcptr, op2: mpq_srcptr) -> c_int;
    fn __gmpq_add(sum: mpq_ptr, addend1: mpq_srcptr, addend2: mpq_srcptr);
    fn __gmpq_sub(difference: mpq_ptr, minuend: mpq_srcptr, subtrahend: mpq_srcptr);
    fn __gmpq_mul(product: mpq_ptr, multiplier: mpq_srcptr, multiplicand: mpq_srcptr);
    fn __gmpq_div(product: mpq_ptr, multiplier: mpq_srcptr, multiplicand: mpq_srcptr);
    fn __gmpq_neg(negated_operand: mpq_ptr, operand: mpq_srcptr);
    fn __gmpq_abs(rop: mpq_ptr, op: mpq_srcptr);
    fn __gmpq_inv(inverted_number: mpq_ptr, number: mpq_srcptr);
    fn __gmpq_get_num(numerator: mpz_ptr, rational: mpq_srcptr);
    fn __gmpq_get_den(denominator: mpz_ptr, rational: mpq_srcptr);
    fn __gmpq_set_num(rational: mpq_ptr, numerator: mpz_srcptr);
    fn __gmpq_set_den(rational: mpq_ptr, denominator: mpz_srcptr);
    fn __gmpq_canonicalize(rational: mpq_ptr);
    fn __gmpq_get_d(rational: mpq_srcptr) -> c_double;
}

pub struct Mpq {
    mpq: mpq_struct,
}

unsafe impl Send for Mpq { }

impl Drop for Mpq {
    fn drop(&mut self) { unsafe { __gmpq_clear(&mut self.mpq) } }
}

impl Mpq {
    pub unsafe fn inner(&self) -> mpq_srcptr {
        &self.mpq
    }

    pub unsafe fn inner_mut(&mut self) -> mpq_ptr {
        &mut self.mpq
    }

    pub fn new() -> Mpq {
        unsafe {
            let mut mpq = uninitialized();
            __gmpq_init(&mut mpq);
            Mpq { mpq: mpq }
        }
    }

    pub fn ratio(num: &Mpz, den: &Mpz) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_set_num(&mut res.mpq, num.inner());
            __gmpq_set_den(&mut res.mpq, den.inner());
            res
        }
    }

    pub fn canonicalize(&mut self) {
        unsafe {
            __gmpq_canonicalize(&mut self.mpq);
        }
    }

    pub fn set(&mut self, other: &Mpq) {
        unsafe { __gmpq_set(&mut self.mpq, &other.mpq) }
    }

    pub fn set_z(&mut self, other: &Mpz) {
        unsafe { __gmpq_set_z(&mut self.mpq, other.inner()) }
    }

    pub fn set_d(&mut self, other: f64) {
        unsafe { __gmpq_set_d(&mut self.mpq, other) }
    }

    pub fn set_f(&mut self, other: &Mpf) {
        unsafe { __gmpq_set_f(&mut self.mpq, other.inner()) }
    }

    pub fn get_num(&self) -> Mpz {
        unsafe {
            let mut res = Mpz::new();
            __gmpq_get_num(res.inner_mut(), &self.mpq);
            res
        }
    }

    pub fn get_den(&self) -> Mpz {
        unsafe {
            let mut res = Mpz::new();
            __gmpq_get_den(res.inner_mut(), &self.mpq);
            res
        }
    }

    pub fn abs(&self) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_abs(&mut res.mpq, &self.mpq);
            res
        }
    }

    pub fn invert(&self) -> Mpq {
        unsafe {
            if self.is_zero() {
                panic!("divide by zero")
            }

            let mut res = Mpq::new();
            __gmpq_inv(&mut res.mpq, &self.mpq);
            res
        }
    }

    pub fn floor(&self) -> Mpz {
        let mut res = Mpz::new();
        unsafe {
            __gmpz_fdiv_q(res.inner_mut(), &self.mpq._mp_num, &self.mpq._mp_den);
        }
        res
    }

    pub fn ceil(&self) -> Mpz {
        let mut res = Mpz::new();
        unsafe {
            __gmpz_cdiv_q(res.inner_mut(), &self.mpq._mp_num, &self.mpq._mp_den);
        }
        res
    }

    pub fn one() -> Mpq {
        let mut res = Mpq::new();
        unsafe { __gmpq_set_ui(&mut res.mpq, 1, 1) }
        res
    }

    pub fn zero() -> Mpq { Mpq::new() }
    pub fn is_zero(&self) -> bool {
        unsafe { __gmpq_cmp_ui(&self.mpq, 0, 1) == 0 }
    }
}

impl Clone for Mpq {
    fn clone(&self) -> Mpq {
        let mut res = Mpq::new();
        res.set(self);
        res
    }
}

impl Eq for Mpq { }
impl PartialEq for Mpq {
    fn eq(&self, other: &Mpq) -> bool {
        unsafe { __gmpq_equal(&self.mpq, &other.mpq) != 0 }
    }
}

impl Ord for Mpq {
    fn cmp(&self, other: &Mpq) -> Ordering {
        let cmp = unsafe { __gmpq_cmp(&self.mpq, &other.mpq) };
        if cmp == 0 {
            Equal
        } else if cmp < 0 {
            Less
        } else {
            Greater
        }
    }
}
impl PartialOrd for Mpq {
    fn partial_cmp(&self, other: &Mpq) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<'a, 'b> Add<&'a Mpq> for &'b Mpq {
    type Output = Mpq;
    fn add(self, other: &Mpq) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_add(&mut res.mpq, &self.mpq, &other.mpq);
            res
        }
    }
}

impl<'a> Add<&'a Mpq> for Mpq {
    type Output = Mpq;
    #[inline]
    fn add(mut self, other: &Mpq) -> Mpq {
        unsafe {
            __gmpq_add(&mut self.mpq, &self.mpq, &other.mpq);
            self
        }
    }
}

impl<'a, 'b> Sub<&'a Mpq> for &'b Mpq {
    type Output = Mpq;
    fn sub(self, other: &Mpq) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_sub(&mut res.mpq, &self.mpq, &other.mpq);
            res
        }
    }
}

impl<'a> Sub<&'a Mpq> for Mpq {
    type Output = Mpq;
    #[inline]
    fn sub(mut self, other: &Mpq) -> Mpq {
        unsafe {
            __gmpq_sub(&mut self.mpq, &self.mpq, &other.mpq);
            self
        }
    }
}

impl<'a, 'b> Mul<&'a Mpq> for &'b Mpq {
    type Output = Mpq;
    fn mul(self, other: &Mpq) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_mul(&mut res.mpq, &self.mpq, &other.mpq);
            res
        }
    }
}

impl<'a> Mul<&'a Mpq> for Mpq {
    type Output = Mpq;
    #[inline]
    fn mul(mut self, other: &Mpq) -> Mpq {
        unsafe {
            __gmpq_mul(&mut self.mpq, &self.mpq, &other.mpq);
            self
        }
    }
}

impl<'a, 'b> Div<&'a Mpq> for &'b Mpq {
    type Output = Mpq;
    fn div(self, other: &Mpq) -> Mpq {
        unsafe {
            if other.is_zero() {
                panic!("divide by zero")
            }

            let mut res = Mpq::new();
            __gmpq_div(&mut res.mpq, &self.mpq, &other.mpq);
            res
        }
    }
}

impl<'a> Div<&'a Mpq> for Mpq {
    type Output = Mpq;
    #[inline]
    fn div(mut self, other: &Mpq) -> Mpq {
        unsafe {
            if other.is_zero() {
                panic!("divide by zero")
            }

            __gmpq_div(&mut self.mpq, &self.mpq, &other.mpq);
            self
        }
    }
}

impl<'b> Neg for &'b Mpq {
    type Output = Mpq;
    fn neg(self) -> Mpq {
        unsafe {
            let mut res = Mpq::new();
            __gmpq_neg(&mut res.mpq, &self.mpq);
            res
        }
    }
}

impl Neg for Mpq {
    type Output = Mpq;
    #[inline]
    fn neg(mut self) -> Mpq {
        unsafe {
            __gmpq_neg(&mut self.mpq, &self.mpq);
            self
        }
    }
}

impl Into<Option<i64>> for Mpq {
    fn into(self) -> Option<i64> {
        panic!("not implemented")
    }
}

impl Into<Option<u64>> for Mpq {
    fn into(self) -> Option<u64> {
        panic!("not implemented")
    }
}

impl Into<f64> for Mpq {
    fn into(self) -> f64 {
        unsafe {
            __gmpq_get_d(&self.mpq) as f64
        }
    }
}

impl From<Mpz> for Mpq {
    fn from(other: Mpz) -> Mpq {
        let mut res = Mpq::new();
        res.set_z(&other);
        res
    }
}

impl From<i64> for Mpq {
    fn from(other: i64) -> Mpq {
        From::<Mpz>::from(From::<i64>::from(other))
    }
}

impl From<i32> for Mpq {
    fn from(other: i32) -> Mpq {
        From::<Mpz>::from(From::<i32>::from(other))
    }
}

impl From<u64> for Mpq {
    fn from(other: u64) -> Mpq {
        From::<Mpz>::from(From::<u64>::from(other))
    }
}

impl From<u32> for Mpq {
    fn from(other: u32) -> Mpq {
        From::<Mpz>::from(From::<u32>::from(other))
    }
}

impl fmt::Debug for Mpq {
    /// Renders as `numer/denom`. If denom=1, renders as numer.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let numer = self.get_num();
        let denom = self.get_den();

        if denom == From::<i64>::from(1) {
            write!(f, "{}", numer)
        } else {
            write!(f, "{}/{}", numer, denom)
        }
    }
}

gen_overloads!(Mpq);
<|endoftext|>


<commit_before>//! Rust representations of docker json structures

use std::collections::HashMap;

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct SearchResult {
    pub description: String,
    pub is_official: bool,
    pub is_automated: bool,
    pub name: String,
    pub star_count: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Image {
    pub Created: u64,
    pub Id: String,
    pub ParentId: String,
    pub Labels: Option<HashMap<String, String>>,
    pub RepoTags: Vec<String>,
    pub RepoDigests: Option<Vec<String>>,
    pub VirtualSize: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct ImageDetails {
    pub Architecture: String,
    pub Author: String,
    pub Comment: String,
    pub Config: Config,
    pub Created: String,
    pub DockerVersion: String,
    pub Id: String,
    pub Os: String,
    pub Parent: String,
    pub Size: u64,
    pub VirtualSize: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Container {
    pub Created: u64,
    pub Command: String,
    pub Id: String,
    pub Image: String,
    pub Labels: HashMap<String, String>,
    pub Names: Vec<String>,
    pub Ports: Vec<Port>,
    pub Status: String,
    pub SizeRw: Option<u64>,
    pub SizeRootFs: Option<u64>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct ContainerDetails {
    pub AppArmorProfile: String,
    pub Args: Vec<String>,
    pub Config: Config,
    pub Created: String,
    pub Driver: String,
    // pub ExecIDs: ??
    pub HostConfig: HostConfig,
    pub HostnamePath: String,
    pub HostsPath: String,
    pub LogPath: String,
    pub Id: String,
    pub Image: String,
    pub MountLabel: String,
    pub Name: String,
    pub NetworkSettings: NetworkSettings,
    pub Path: String,
    pub ProcessLabel: String,
    pub ResolvConfPath: String,
    pub RestartCount: u64,
    pub State: State,
    pub Mounts: Vec<Mount>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Mount {
    pub Source: String,
    pub Destination: String,
    pub Mode: String,
    pub RW: bool,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct State {
    pub Error: String,
    pub ExitCode: u64,
    pub FinishedAt: String,
    pub OOMKilled: bool,
    pub Paused: bool,
    pub Pid: u64,
    pub Restarting: bool,
    pub Running: bool,
    pub StartedAt: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct NetworkSettings {
    pub Bridge: String,
    pub Gateway: String,
    pub IPAddress: String,
    pub IPPrefixLen: u64,
    pub MacAddress: String, /*    pub PortMapping: Option<???>,
                             *   pub Ports: Option<???> */
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct HostConfig {
    pub CgroupParent: Option<String>,
    pub ContainerIDFile: String,
    pub CpuShares: Option<u64>,
    pub CpusetCpus: Option<String>,
    pub Memory: Option<u64>,
    pub MemorySwap: Option<i64>,
    pub NetworkMode: String,
    pub PidMode: Option<String>,
    // pub PortBindings: ???
    pub Privileged: bool,
    pub PublishAllPorts: bool,
    pub ReadonlyRootfs: Option<bool>, /* pub RestartPolicy: ???
                                       * pub SecurityOpt: Option<???>,
                                       * pub Ulimits: Option<???>
                                       * pub VolumesFrom: Option<??/> */
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Config {
    pub AttachStderr: bool,
    pub AttachStdin: bool,
    pub AttachStdout: bool,
    pub Cmd: Option<Vec<String>>,
    pub Domainname: String,
    pub Entrypoint: Option<Vec<String>>,
    pub Env: Option<Vec<String>>,
    // ExposedPorts
    pub Hostname: String,
    pub Image: String,
    pub Labels: HashMap<String, String>,
    // pub MacAddress: String,
    pub OnBuild: Option<Vec<String>>,
    // pub NetworkDisabled: bool,
    pub OpenStdin: bool,
    pub StdinOnce: bool,
    pub Tty: bool,
    pub User: String,
    pub WorkingDir: String,
}

impl Config {
    pub fn env(&self) -> HashMap<String, String> {
        let mut map = HashMap::new();
        match self.Env {
            Some(ref vars) => {
                for e in vars {
                    let pair: Vec<&str> = e.split("=").collect();
                    map.insert(pair[0].to_owned(), pair[1].to_owned());
                }
            }
            _ => (),
        };
        map
    }
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Port {
    pub IP: Option<String>,
    pub PrivatePort: u64,
    pub PublicPort: Option<u64>,
    pub Type: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Stats {
    pub read: String,
    pub networks: HashMap<String, Network>,
    pub memory_stats: MemoryStats,
    pub blkio_stats: BlkioStats,
    pub cpu_stats: CpuStats,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Network {
    pub rx_dropped: u64,
    pub rx_bytes: u64,
    pub rx_errors: u64,
    pub tx_packets: u64,
    pub tx_dropped: u64,
    pub rx_packets: u64,
    pub tx_errors: u64,
    pub tx_bytes: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct IPAM {
    pub Driver: String,
    pub Config: Vec<HashMap<String, String>>,
    pub Options: Option<HashMap<String, String>>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct NetworkDetails {
    pub Name: String,
    pub Id: String,
    pub Scope: String,
    pub Driver: String,
    pub EnableIPv6: bool,
    pub IPAM: IPAM,
    pub Internal: bool,
    pub Attachable: bool,
    pub Containers: HashMap<String, NetworkContainerDetails>,
    pub Options: Option<HashMap<String, String>>,
    pub Labels: Option<HashMap<String, String>>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct NetworkContainerDetails {
    pub EndpointID: String,
    pub MacAddress: String,
    pub IPv4Address: String,
    pub IPv6Address: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct NetworkCreateInfo {
    pub Id: String,
    pub Warning: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct MemoryStats {
    pub max_usage: u64,
    pub usage: u64,
    pub failcnt: Option<u64>,
    pub limit: u64,
    pub stats: MemoryStat,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct MemoryStat {
    pub total_pgmajfault: u64,
    pub cache: u64,
    pub mapped_file: u64,
    pub total_inactive_file: u64,
    pub pgpgout: u64,
    pub rss: u64,
    pub total_mapped_file: u64,
    pub writeback: u64,
    pub unevictable: u64,
    pub pgpgin: u64,
    pub total_unevictable: u64,
    pub pgmajfault: u64,
    pub total_rss: u64,
    pub total_rss_huge: u64,
    pub total_writeback: u64,
    pub total_inactive_anon: u64,
    pub rss_huge: u64,
    pub hierarchical_memory_limit: u64,
    pub hierarchical_memsw_limit: u64,
    pub total_pgfault: u64,
    pub total_active_file: u64,
    pub active_anon: u64,
    pub total_active_anon: u64,
    pub total_pgpgout: u64,
    pub total_cache: u64,
    pub inactive_anon: u64,
    pub active_file: u64,
    pub pgfault: u64,
    pub inactive_file: u64,
    pub total_pgpgin: u64,
    pub swap: u64,
    pub total_swap: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct CpuStats {
    pub cpu_usage: CpuUsage,
    pub system_cpu_usage: u64,
    pub throttling_data: ThrottlingData,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct CpuUsage {
    pub percpu_usage: Vec<u64>,
    pub usage_in_usermode: u64,
    pub total_usage: u64,
    pub usage_in_kernelmode: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct ThrottlingData {
    pub periods: u64,
    pub throttled_periods: u64,
    pub throttled_time: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct BlkioStats {
    pub io_service_bytes_recursive: Vec<BlkioStat>,
    pub io_serviced_recursive: Vec<BlkioStat>,
    pub io_queue_recursive: Vec<BlkioStat>,
    pub io_service_time_recursive: Vec<BlkioStat>,
    pub io_wait_time_recursive: Vec<BlkioStat>,
    pub io_merged_recursive: Vec<BlkioStat>,
    pub io_time_recursive: Vec<BlkioStat>,
    pub sectors_recursive: Vec<BlkioStat>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct BlkioStat {
    pub major: u64,
    pub minor: u64,
    pub op: String,
    pub value: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Change {
    pub Kind: u64,
    pub Path: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Top {
    pub Titles: Vec<String>,
    pub Processes: Vec<Vec<String>>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Version {
    pub ApiVersion: String,
    pub Version: String,
    pub GitCommit: String,
    pub GoVersion: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Info {
    pub Containers: u64,
    pub Images: u64,
    pub Driver: String,
    pub DockerRootDir: String,
    pub DriverStatus: Vec<Vec<String>>,
    pub ID: String,
    pub KernelVersion: String,
    // pub Labels: Option<???>,
    pub MemTotal: u64,
    pub MemoryLimit: bool,
    pub NCPU: u64,
    pub NEventsListener: u64,
    pub NGoroutines: u64,
    pub Name: String,
    pub OperatingSystem: String,
    // pub RegistryConfig:???
    pub SwapLimit: bool,
    pub SystemTime: Option<String>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct ContainerCreateInfo {
    pub Id: String,
    pub Warnings: Option<Vec<String>>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct History {
    pub Id: String,
    pub Created: u64,
    pub CreatedBy: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Exit {
    pub StatusCode: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Event {
    pub status: Option<String>,
    pub id: Option<String>,
    pub from: Option<String>,
    pub time: u64,
    pub timeNano: u64,
}

#[derive(Clone, Debug)]
pub enum Status {
    Untagged(String),
    Deleted(String),
}
<commit_msg>Add details entries for container networks<commit_after>//! Rust representations of docker json structures

use std::collections::HashMap;

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct SearchResult {
    pub description: String,
    pub is_official: bool,
    pub is_automated: bool,
    pub name: String,
    pub star_count: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Image {
    pub Created: u64,
    pub Id: String,
    pub ParentId: String,
    pub Labels: Option<HashMap<String, String>>,
    pub RepoTags: Vec<String>,
    pub RepoDigests: Option<Vec<String>>,
    pub VirtualSize: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct ImageDetails {
    pub Architecture: String,
    pub Author: String,
    pub Comment: String,
    pub Config: Config,
    pub Created: String,
    pub DockerVersion: String,
    pub Id: String,
    pub Os: String,
    pub Parent: String,
    pub Size: u64,
    pub VirtualSize: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Container {
    pub Created: u64,
    pub Command: String,
    pub Id: String,
    pub Image: String,
    pub Labels: HashMap<String, String>,
    pub Names: Vec<String>,
    pub Ports: Vec<Port>,
    pub Status: String,
    pub SizeRw: Option<u64>,
    pub SizeRootFs: Option<u64>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct ContainerDetails {
    pub AppArmorProfile: String,
    pub Args: Vec<String>,
    pub Config: Config,
    pub Created: String,
    pub Driver: String,
    // pub ExecIDs: ??
    pub HostConfig: HostConfig,
    pub HostnamePath: String,
    pub HostsPath: String,
    pub LogPath: String,
    pub Id: String,
    pub Image: String,
    pub MountLabel: String,
    pub Name: String,
    pub NetworkSettings: NetworkSettings,
    pub Path: String,
    pub ProcessLabel: String,
    pub ResolvConfPath: String,
    pub RestartCount: u64,
    pub State: State,
    pub Mounts: Vec<Mount>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Mount {
    pub Source: String,
    pub Destination: String,
    pub Mode: String,
    pub RW: bool,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct State {
    pub Error: String,
    pub ExitCode: u64,
    pub FinishedAt: String,
    pub OOMKilled: bool,
    pub Paused: bool,
    pub Pid: u64,
    pub Restarting: bool,
    pub Running: bool,
    pub StartedAt: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct NetworkSettings {
    pub Bridge: String,
    pub Gateway: String,
    pub IPAddress: String,
    pub IPPrefixLen: u64,
    pub MacAddress: String, /*    pub PortMapping: Option<???>,
                             *   pub Ports: Option<???> */
    pub Networks: HashMap<String, NetworkEntry>
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct NetworkEntry {
    pub NetworkID: String,
    pub EndpointID: String,
    pub Gateway: String,
    pub IPAddress: String,
    pub IPPrefixLen: u64,
    pub IPv6Gateway: String,
    pub GlobalIPv6Address: String,
    pub GlobalIPv6PrefixLen: u64,
    pub MacAddress: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct HostConfig {
    pub CgroupParent: Option<String>,
    pub ContainerIDFile: String,
    pub CpuShares: Option<u64>,
    pub CpusetCpus: Option<String>,
    pub Memory: Option<u64>,
    pub MemorySwap: Option<i64>,
    pub NetworkMode: String,
    pub PidMode: Option<String>,
    // pub PortBindings: ???
    pub Privileged: bool,
    pub PublishAllPorts: bool,
    pub ReadonlyRootfs: Option<bool>, /* pub RestartPolicy: ???
                                       * pub SecurityOpt: Option<???>,
                                       * pub Ulimits: Option<???>
                                       * pub VolumesFrom: Option<??/> */
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
#[allow(non_snake_case)]
pub struct Config {
    pub AttachStderr: bool,
    pub AttachStdin: bool,
    pub AttachStdout: bool,
    pub Cmd: Option<Vec<String>>,
    pub Domainname: String,
    pub Entrypoint: Option<Vec<String>>,
    pub Env: Option<Vec<String>>,
    // ExposedPorts
    pub Hostname: String,
    pub Image: String,
    pub Labels: HashMap<String, String>,
    // pub MacAddress: String,
    pub OnBuild: Option<Vec<String>>,
    // pub NetworkDisabled: bool,
    pub OpenStdin: bool,
    pub StdinOnce: bool,
    pub Tty: bool,
    pub User: String,
    pub WorkingDir: String,
}

impl Config {
    pub fn env(&self) -> HashMap<String, String> {
        let mut map = HashMap::new();
        match self.Env {
            Some(ref vars) => {
                for e in vars {
                    let pair: Vec<&str> = e.split("=").collect();
                    map.insert(pair[0].to_owned(), pair[1].to_owned());
                }
            }
            _ => (),
        };
        map
    }
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Port {
    pub IP: Option<String>,
    pub PrivatePort: u64,
    pub PublicPort: Option<u64>,
    pub Type: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Stats {
    pub read: String,
    pub networks: HashMap<String, Network>,
    pub memory_stats: MemoryStats,
    pub blkio_stats: BlkioStats,
    pub cpu_stats: CpuStats,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Network {
    pub rx_dropped: u64,
    pub rx_bytes: u64,
    pub rx_errors: u64,
    pub tx_packets: u64,
    pub tx_dropped: u64,
    pub rx_packets: u64,
    pub tx_errors: u64,
    pub tx_bytes: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct IPAM {
    pub Driver: String,
    pub Config: Vec<HashMap<String, String>>,
    pub Options: Option<HashMap<String, String>>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct NetworkDetails {
    pub Name: String,
    pub Id: String,
    pub Scope: String,
    pub Driver: String,
    pub EnableIPv6: bool,
    pub IPAM: IPAM,
    pub Internal: bool,
    pub Attachable: bool,
    pub Containers: HashMap<String, NetworkContainerDetails>,
    pub Options: Option<HashMap<String, String>>,
    pub Labels: Option<HashMap<String, String>>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct NetworkContainerDetails {
    pub EndpointID: String,
    pub MacAddress: String,
    pub IPv4Address: String,
    pub IPv6Address: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct NetworkCreateInfo {
    pub Id: String,
    pub Warning: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct MemoryStats {
    pub max_usage: u64,
    pub usage: u64,
    pub failcnt: Option<u64>,
    pub limit: u64,
    pub stats: MemoryStat,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct MemoryStat {
    pub total_pgmajfault: u64,
    pub cache: u64,
    pub mapped_file: u64,
    pub total_inactive_file: u64,
    pub pgpgout: u64,
    pub rss: u64,
    pub total_mapped_file: u64,
    pub writeback: u64,
    pub unevictable: u64,
    pub pgpgin: u64,
    pub total_unevictable: u64,
    pub pgmajfault: u64,
    pub total_rss: u64,
    pub total_rss_huge: u64,
    pub total_writeback: u64,
    pub total_inactive_anon: u64,
    pub rss_huge: u64,
    pub hierarchical_memory_limit: u64,
    pub hierarchical_memsw_limit: u64,
    pub total_pgfault: u64,
    pub total_active_file: u64,
    pub active_anon: u64,
    pub total_active_anon: u64,
    pub total_pgpgout: u64,
    pub total_cache: u64,
    pub inactive_anon: u64,
    pub active_file: u64,
    pub pgfault: u64,
    pub inactive_file: u64,
    pub total_pgpgin: u64,
    pub swap: u64,
    pub total_swap: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct CpuStats {
    pub cpu_usage: CpuUsage,
    pub system_cpu_usage: u64,
    pub throttling_data: ThrottlingData,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct CpuUsage {
    pub percpu_usage: Vec<u64>,
    pub usage_in_usermode: u64,
    pub total_usage: u64,
    pub usage_in_kernelmode: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct ThrottlingData {
    pub periods: u64,
    pub throttled_periods: u64,
    pub throttled_time: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct BlkioStats {
    pub io_service_bytes_recursive: Vec<BlkioStat>,
    pub io_serviced_recursive: Vec<BlkioStat>,
    pub io_queue_recursive: Vec<BlkioStat>,
    pub io_service_time_recursive: Vec<BlkioStat>,
    pub io_wait_time_recursive: Vec<BlkioStat>,
    pub io_merged_recursive: Vec<BlkioStat>,
    pub io_time_recursive: Vec<BlkioStat>,
    pub sectors_recursive: Vec<BlkioStat>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct BlkioStat {
    pub major: u64,
    pub minor: u64,
    pub op: String,
    pub value: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Change {
    pub Kind: u64,
    pub Path: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Top {
    pub Titles: Vec<String>,
    pub Processes: Vec<Vec<String>>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Version {
    pub ApiVersion: String,
    pub Version: String,
    pub GitCommit: String,
    pub GoVersion: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Info {
    pub Containers: u64,
    pub Images: u64,
    pub Driver: String,
    pub DockerRootDir: String,
    pub DriverStatus: Vec<Vec<String>>,
    pub ID: String,
    pub KernelVersion: String,
    // pub Labels: Option<???>,
    pub MemTotal: u64,
    pub MemoryLimit: bool,
    pub NCPU: u64,
    pub NEventsListener: u64,
    pub NGoroutines: u64,
    pub Name: String,
    pub OperatingSystem: String,
    // pub RegistryConfig:???
    pub SwapLimit: bool,
    pub SystemTime: Option<String>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct ContainerCreateInfo {
    pub Id: String,
    pub Warnings: Option<Vec<String>>,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct History {
    pub Id: String,
    pub Created: u64,
    pub CreatedBy: String,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Exit {
    pub StatusCode: u64,
}

#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Event {
    pub status: Option<String>,
    pub id: Option<String>,
    pub from: Option<String>,
    pub time: u64,
    pub timeNano: u64,
}

#[derive(Clone, Debug)]
pub enum Status {
    Untagged(String),
    Deleted(String),
}
<|endoftext|>


<commit_before>//! Run time length encoding and decoding based on byte streams.
//!
//! A run is defined as a sequence of identical bytes of length two or greater.
//! A run of byte a and length n is encoded by a two repitions of a, followed
//! by a length specification which describes how much often these bytes are
//! repeated. Such a specification is a string of bytes
//! with dynamic length. The most significat bit of each byte in this string
//! indicates if the byte is the last byte in the string. The rest of the bits
//! are concatenated using the Little Endian convention.
//!
//! Every byte string is a prefix of a valid RLE encoding!

use std::io::{self, Write, Read};
use std::iter::repeat;
use std::collections::VecDeque;

/// This structure is used to compress a stream of bytes using a RLE
/// compression algorithm. This is a wrapper around an internal writer which
/// bytes will be written to.
pub struct Encoder<W> {
    w: W,
    reps: u64,
    byte: u8,
    in_run: bool
}

impl<W: Write> Encoder<W> {
    /// Creates a new encoder which will have its output written to the given
    /// output stream.
    pub fn new(w: W) -> Encoder<W> {
        Encoder {
            w: w,
            reps: 0,
            byte: 0,
            in_run: false
        }
    }

    /// This function is used to flag that this session of compression is done
    /// with. The stream is finished up (final bytes are written), and then the
    /// wrapped writer is returned.
    pub fn finish(mut self) -> (W, io::Result<()>) {
        (self.w, self.flush())
    }

    fn process_byte(&mut self, byte: u8) -> io::Result<()> {
        // TODO: move this check to write, so it won't be called as often?
        if ! self.in_run {
            self.byte = byte;
            self.reps = 1;
            self.in_run = true;
            return Ok(());
        }

        if self.byte == byte {
            self.reps += 1;
            return Ok(())
        }

        if self.byte != byte {
            self.flush();
            self.reps = 1;
            self.byte = byte;
        }

        Ok(())
    }
}

impl<W: Write> Write for Encoder<W> {
    fn write(&mut self, mut buf: &[u8]) -> io::Result<usize> {
        let mut bytes_written = 0;

        for byte in buf {
            try!(self.process_byte(*byte));
            bytes_written += 1;
        }

        Ok(bytes_written)
    }

    fn flush(&mut self) -> io::Result<()> {
        if self.reps == 1 {
            try!(self.w.write(&[self.byte]));
        } else if self.reps > 1 {
            let mut buf = [0; 11];
            let mut reps_encode = self.reps - 2;
            buf[0] = self.byte;
            buf[1] = self.byte;

            let mut index = 2;

            loop {
                buf[index] = (reps_encode & 0b0111_1111) as u8;
                reps_encode = reps_encode >> 7;

                if reps_encode == 0 {
                    buf[index] = buf[index] | 0b1000_0000;
                    break;
                }

                index += 1;
            }

            try!(self.w.write(&buf[..(index + 1)]));
        }

        Ok(())
    }
}

struct RunBuilder {
    byte: u8,
    slice: [u8; 9],
    byte_count: u8
}

impl RunBuilder {
    fn new(byte: u8) -> Run {
        Run {
            byte: u8,
            slice: [0; 9],
            byte_count: 0
        }
    }
}

struct Run {
    byte: u8,
    reps: u64
}

enum DecoderState {
    Clean,
    Single(u8),
    Run(RunBuilder)
}

pub struct Decoder<R> {
    r: R,
    buf: VecDeque<u8>,
    state: DecoderState,
    run: Option<Run>
}

impl<R: Read> Decoder<R> {
    pub fn new(r: R) -> Decoder<R> {
        Decoder {
            r: r,
            state: DecoderState::Clean
        }
    }

    fn read_byte(&mut self) -> io::Result<Option<u8>> {
        if let None = self.run {
            self.run = try!(self.read_run());
        }

        if let Some(Run { byte: b, reps: r }) = self.run {
            if r <= 1 {
                self.run = None;
            } else {
                self.run = Some(Run { byte: b, reps: r - 1 });
            }

            return Ok(Some(b))
        }

        Ok(None)
    }

    fn read_run(&mut self) -> io::Result<Run> {
        // TODO: diz b wher da magik happen
    }

    fn fill_buff(&mut self) -> io::Result<()> {
        let mut buf = [0u8; 256];
        try!(self.r.read(&mut buf));

        for &byte in buf {
            self.buf.push_back(byte);
        }

        Ok(())
    }

    fn fetch_byte(&mut self) -> io::Result<Option<u8>> {
        match self.buf.pop_front() {
            Some(byte) => Ok(Some(byte)),
            None => {
                try!(self.fill_buf());

                match self.buf.pop_front() {
                    None => Ok(None),
                    Ok(byte) => Ok(Some(byte))
                }
            }
        }
    }
}

impl<R: Read> Read for Decoder<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let mut bytes_read = 0;

        for _ in 0..buf.len() {
            match try!(self.read_byte()) {
                Some(b) => buf[bytes_read] = b,
                None => return Ok(bytes_read)
            }

            bytes_read += 1;
        }

        Ok(bytes_read)
    }
}

#[cfg(test)]
mod test {
    use super::Encoder;
    use std::io::Write;
    use std::iter::{Iterator, repeat};

    fn test_encode(input: &[u8], output: &[u8]) {
        let mut encoder = Encoder::new(Vec::new());
        encoder.write_all(input).unwrap();
        let (buf, _) = encoder.finish();

        assert_eq!(&buf[..], output);
    }

    #[test]
    fn simple_encoding() {
        test_encode(b"", b"");
        test_encode(b"a", b"a");
        test_encode(b"abca123", b"abca123");
        test_encode(&[20, 20, 20, 20, 20, 15], &[20, 20, 5 - 2 + 128, 15]);
        test_encode(&[0, 0], &[0, 0, 2 - 2 + 128]);
    }

    #[test]
    fn long_runs() {
        let mut data = repeat(5).take(129).collect::<Vec<_>>();
        test_encode(&data[..], &[5, 5, 255]);

        let mut data = [1, 3, 4, 4].iter().map(|&x| x).chain(repeat(100).take(2 + 52 + 128)).collect::<Vec<_>>();
        test_encode(&data[..], &[1, 3, 4, 4, 0 + 128, 100, 100, 52, 1 + 128]);
    }
}
<commit_msg>Finish RLE decoder<commit_after>/*!

Run time length encoding and decoding based on byte streams, see
https://en.wikipedia.org/wiki/Run-length_encoding.

A run is defined as a sequence of identical bytes of length two or greater.
A run of byte a and length n is encoded by a two repitions of a, followed
by a length specification which describes how much often these bytes are
repeated. Such a specification is a string of bytes with dynamic length.
The most significat bit of each byte in this string indicates if the byte is
the last byte in the string. The rest of the bits are concatenated using
the Little Endian convention.

# Example

```rust
use compress::rle;
use std::io::{Write, Read};

let input = b"Helloooo world!!";

let mut encoder = rle::Encoder::new(Vec::new());
encoder.write_all(&input[..]).unwrap();
let (buf, _): (Vec<u8>, _) = encoder.finish();

let mut decoder = rle::Decoder::new(&buf[..]);
let mut decoder_buf = Vec::new();
decoder.read_to_end(&mut decoder_buf).unwrap();

assert_eq!(&input[..], &decoder_buf[..]);
```

!*/

use std::io::{self, Write, Read};
use std::collections::VecDeque;

/// This structure is used to compress a stream of bytes using a RLE
/// compression algorithm. This is a wrapper around an internal writer which
/// bytes will be written to.
pub struct Encoder<W> {
    w: W,
    reps: u64,
    byte: u8,
    in_run: bool
}

impl<W: Write> Encoder<W> {
    /// Creates a new encoder which will have its output written to the given
    /// output stream.
    pub fn new(w: W) -> Encoder<W> {
        Encoder {
            w: w,
            reps: 0,
            byte: 0,
            in_run: false
        }
    }

    /// This function is used to flag that this session of compression is done
    /// with. The stream is finished up (final bytes are written), and then the
    /// wrapped writer is returned.
    pub fn finish(mut self) -> (W, io::Result<()>) {
        let result = self.flush();

        (self.w, result)
    }

    fn process_byte(&mut self, byte: u8) -> io::Result<()> {
        // TODO: move this check to self.write(), so it won't be called as often?
        if ! self.in_run {
            self.byte = byte;
            self.reps = 1;
            self.in_run = true;
            return Ok(());
        }

        if self.byte == byte {
            self.reps += 1;
            return Ok(())
        }

        if self.byte != byte {
            try!(self.flush());
            self.reps = 1;
            self.byte = byte;
        }

        Ok(())
    }
}

impl<W: Write> Write for Encoder<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let mut bytes_written = 0;

        for byte in buf {
            try!(self.process_byte(*byte));
            bytes_written += 1;
        }

        Ok(bytes_written)
    }

    fn flush(&mut self) -> io::Result<()> {
        if self.reps == 1 {
            try!(self.w.write(&[self.byte]));
        } else if self.reps > 1 {
            let mut buf = [0; 11];
            let mut reps_encode = self.reps - 2;
            buf[0] = self.byte;
            buf[1] = self.byte;

            let mut index = 2;

            loop {
                buf[index] = (reps_encode & 0b0111_1111) as u8;
                reps_encode = reps_encode >> 7;

                if reps_encode == 0 {
                    buf[index] = buf[index] | 0b1000_0000;
                    break;
                }

                index += 1;
            }

            try!(self.w.write(&buf[..(index + 1)]));
        }

        Ok(())
    }
}

struct RunBuilder {
    byte: u8,
    slice: [u8; 9],
    byte_count: u8
}

impl RunBuilder {
    fn new(byte: u8) -> RunBuilder {
        RunBuilder {
            byte: byte,
            slice: [0; 9],
            byte_count: 0
        }
    }

    fn to_run(&mut self) -> Run {
        let reps = 2 + self.slice.iter().enumerate().fold(0u64, |reps, (i, &byte)| {
            reps | (((byte & 0b0111_1111) as u64) << (i as u32 * 7))
        });

        Run {
            byte: self.byte,
            reps: reps
        }
    }

    fn add_byte(&mut self, byte: u8) -> io::Result<()> {
        if self.byte_count >= 9 {
            Err(io::Error::new(io::ErrorKind::Other, "Overly long run"))
        } else {
            self.slice[self.byte_count as usize] = byte;
            self.byte_count += 1;
            Ok(())
        }
    }
}

struct Run {
    byte: u8,
    reps: u64
}

enum DecoderState {
    Clean,
    Single(u8),
    Run(RunBuilder)
}

/// This structure is used to decode a run length encoded stream. This wraps
/// an internal reader which is read from when this decoder's read method is
/// called.
pub struct Decoder<R> {
    r: R,
    buf: VecDeque<u8>,
    state: DecoderState,
    run: Option<Run>
}

impl<R: Read> Decoder<R> {
    /// Creates a new decoder which will read data from the given stream. The
    /// inner stream can be re-acquired by moving out of the `r` field of this
    /// structure.
    pub fn new(r: R) -> Decoder<R> {
        Decoder {
            r: r,
            buf: VecDeque::with_capacity(32),
            state: DecoderState::Clean,
            run: None
        }
    }

    fn read_byte(&mut self) -> io::Result<Option<u8>> {
        if let None = self.run {
            try!(self.read_run());
        }

        if let Some(Run { byte: b, reps: r }) = self.run {
            if r <= 1 {
                self.run = None;
            } else {
                self.run = Some(Run { byte: b, reps: r - 1 });
            }

            return Ok(Some(b))
        }

        Ok(None)
    }

    fn read_run(&mut self) -> io::Result<()> {
        // FIXME: this solution suuuxx
        let mut reset = false;

        while let Some(byte) = try!(self.fetch_byte()) {
            match self.state {
                DecoderState::Clean => {
                    self.state = DecoderState::Single(byte);
                },
                DecoderState::Single(current) => {
                    if byte == current {
                        self.state = DecoderState::Run(RunBuilder::new(byte));
                    } else {
                        self.run = Some(Run { byte: current, reps: 1 });
                        self.state = DecoderState::Single(byte);
                        break;
                    }
                },
                DecoderState::Run(ref mut run_builder) => {
                    try!(run_builder.add_byte(byte));

                    if Self::is_final_run_byte(byte) {
                        self.run = Some(run_builder.to_run());
                        reset = true;
                        break;
                    }
                }
            }
        }

        if reset {
            self.state = DecoderState::Clean;
        }

        // internal read object exhausted -- flush remaining state into run
        if let None = self.run {
            self.run = match self.state {
                DecoderState::Clean => None,
                DecoderState::Single(byte) => Some(Run { byte: byte, reps: 1 }),
                DecoderState::Run(ref mut run_builder) => Some(run_builder.to_run())
            };

            self.state = DecoderState::Clean;
        }

        Ok(())
    }

    fn is_final_run_byte(byte: u8) -> bool {
        0b1000_0000 & byte != 0
    }

    fn fill_buf(&mut self) -> io::Result<()> {
        let mut buf = [0u8; 32];
        let bytes_read = try!(self.r.read(&mut buf));

        for &byte in &buf[..bytes_read] {
            self.buf.push_back(byte);
        }

        Ok(())
    }

    fn fetch_byte(&mut self) -> io::Result<Option<u8>> {
        match self.buf.pop_front() {
            Some(byte) => Ok(Some(byte)),
            None => {
                try!(self.fill_buf());

                match self.buf.pop_front() {
                    None => Ok(None),
                    Some(byte) => Ok(Some(byte))
                }
            }
        }
    }
}

impl<R: Read> Read for Decoder<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let mut bytes_read = 0;

        for _ in 0..buf.len() {
            match try!(self.read_byte()) {
                Some(b) => buf[bytes_read] = b,
                None => return Ok(bytes_read)
            }

            bytes_read += 1;
        }

        Ok(bytes_read)
    }
}

#[cfg(test)]
mod test {
    use super::{Decoder, Encoder};
    use super::super::rand::{OsRng, Rng};
    use std::io::{Write, Read};
    use std::iter::{Iterator, repeat};

    fn test_encode(input: &[u8], output: &[u8]) {
        let mut encoder = Encoder::new(Vec::new());
        encoder.write_all(input).unwrap();
        let (buf, _) = encoder.finish();

        assert_eq!(output, &buf[..]);
    }

    fn test_decode(input: &[u8], output: &[u8]) {
        let mut decoder = Decoder::new(input);
        let mut buf = Vec::new();
        decoder.read_to_end(&mut buf).unwrap();

        assert_eq!(output, &buf[..]);
    }

    fn test_roundtrip(input: &[u8]) {
        let mut encoder = Encoder::new(Vec::new());
        encoder.write_all(input).unwrap();
        let (buf, _) = encoder.finish();

        let mut decoder = Decoder::new(&buf[..]);
        let mut decoder_buf = Vec::new();
        decoder.read_to_end(&mut decoder_buf).unwrap();

        assert_eq!(input, &decoder_buf[..]);
    }

    #[test]
    fn simple_encoding() {
        test_encode(b"", b"");
        test_encode(b"a", b"a");
        test_encode(b"abca123", b"abca123");
        test_encode(&[20, 20, 20, 20, 20, 15], &[20, 20, 5 - 2 + 128, 15]);
        test_encode(&[0, 0], &[0, 0, 2 - 2 + 128]);
    }

    #[test]
    fn long_run_encoding() {
        let mut data = repeat(5).take(129).collect::<Vec<_>>();
        test_encode(&data[..], &[5, 5, 255]);

        data = [1, 3, 4, 4].iter().map(|&x| x).chain(repeat(100).take(2 + 52 + 128)).collect::<Vec<_>>();
        test_encode(&data[..], &[1, 3, 4, 4, 0 + 128, 100, 100, 52, 1 + 128]);
    }

    #[test]
    fn simple_decoding() {
        test_decode(b"", b"");
        test_decode(b"a", b"a");
        test_decode(b"abca123", b"abca123");
        test_decode(&[20, 20, 5 - 2 + 128, 15], &[20, 20, 20, 20, 20, 15]);
        test_decode(&[0, 0, 2 - 2 + 128], &[0, 0]);
    }

    #[test]
    fn long_run_decoding() {
        let data = [1, 3, 4, 4].iter().map(|&x| x).chain(repeat(100).take(2 + 52 + 128)).collect::<Vec<_>>();

        test_decode(&[1, 3, 4, 4, 0 + 128, 100, 100, 52, 1 + 128], &data[..]);
    }

    #[test]
    fn random_roundtrips() {
        let mut rng = OsRng::new().unwrap();

        for _ in 0..100 {
            let mut buf = [0; 13579];
            rng.fill_bytes(&mut buf[..]);
            test_roundtrip(&buf);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Also yield names from objects iter<commit_after><|endoftext|>