<commit_before>// Copyright 2012 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.

//! Semver parsing and logic

#[allow(missing_doc)];

use std::char;
use std::cmp;
use std::io::{ReaderUtil};
use std::io;
use std::option::{Option, Some, None};
use std::to_str::ToStr;
use std::uint;

#[deriving(Eq)]
pub enum Identifier {
    Numeric(uint),
    AlphaNumeric(~str)
}

impl cmp::Ord for Identifier {
    #[inline]
    fn lt(&self, other: &Identifier) -> bool {
        match (self, other) {
            (&Numeric(a), &Numeric(b)) => a < b,
            (&Numeric(_), _) => true,
            (&AlphaNumeric(ref a), &AlphaNumeric(ref b)) => *a < *b,
            (&AlphaNumeric(_), _) => false
        }
    }
    #[inline]
    fn le(&self, other: &Identifier) -> bool {
        ! (other < self)
    }
    #[inline]
    fn gt(&self, other: &Identifier) -> bool {
        other < self
    }
    #[inline]
    fn ge(&self, other: &Identifier) -> bool {
        ! (self < other)
    }
}

impl ToStr for Identifier {
    #[inline]
    fn to_str(&self) -> ~str {
        match self {
            &Numeric(n) => n.to_str(),
            &AlphaNumeric(ref s) => s.to_str()
        }
    }
}

#[deriving(Eq)]
pub struct Version {
    major: uint,
    minor: uint,
    patch: uint,
    pre: ~[Identifier],
    build: ~[Identifier],
}

impl ToStr for Version {
    #[inline]
    fn to_str(&self) -> ~str {
        let s = fmt!("%u.%u.%u", self.major, self.minor, self.patch);
        let s = if self.pre.is_empty() {
            s
        } else {
            fmt!("%s-%s", s, self.pre.map(|i| i.to_str()).connect("."))
        };
        if self.build.is_empty() {
            s
        } else {
            fmt!("%s+%s", s, self.build.map(|i| i.to_str()).connect("."))
        }
    }
}

impl cmp::Ord for Version {
    #[inline]
    fn lt(&self, other: &Version) -> bool {

        self.major < other.major ||

            (self.major == other.major &&
             self.minor < other.minor) ||

            (self.major == other.major &&
             self.minor == other.minor &&
             self.patch < other.patch) ||

            (self.major == other.major &&
             self.minor == other.minor &&
             self.patch == other.patch &&
             // NB: semver spec says 0.0.0-pre < 0.0.0
             // but the version of ord defined for vec
             // says that [] < [pre], so we alter it
             // here.
             (match (self.pre.len(), other.pre.len()) {
                 (0, 0) => false,
                 (0, _) => false,
                 (_, 0) => true,
                 (_, _) => self.pre < other.pre
             })) ||

            (self.major == other.major &&
             self.minor == other.minor &&
             self.patch == other.patch &&
             self.pre == other.pre &&
             self.build < other.build)
    }

    #[inline]
    fn le(&self, other: &Version) -> bool {
        ! (other < self)
    }
    #[inline]
    fn gt(&self, other: &Version) -> bool {
        other < self
    }
    #[inline]
    fn ge(&self, other: &Version) -> bool {
        ! (self < other)
    }
}

condition! {
    bad_parse: () -> ();
}

fn take_nonempty_prefix(rdr: @io::Reader,
                        ch: char,
                        pred: &fn(char) -> bool) -> (~str, char) {
    let mut buf = ~"";
    let mut ch = ch;
    while pred(ch) {
        buf.push_char(ch);
        ch = rdr.read_char();
    }
    if buf.is_empty() {
        bad_parse::cond.raise(())
    }
    debug!("extracted nonempty prefix: %s", buf);
    (buf, ch)
}

fn take_num(rdr: @io::Reader, ch: char) -> (uint, char) {
    let (s, ch) = take_nonempty_prefix(rdr, ch, char::is_digit);
    match uint::from_str(s) {
        None => { bad_parse::cond.raise(()); (0, ch) },
        Some(i) => (i, ch)
    }
}

fn take_ident(rdr: @io::Reader, ch: char) -> (Identifier, char) {
    let (s,ch) = take_nonempty_prefix(rdr, ch, char::is_alphanumeric);
    if s.iter().all(char::is_digit) {
        match uint::from_str(s) {
            None => { bad_parse::cond.raise(()); (Numeric(0), ch) },
            Some(i) => (Numeric(i), ch)
        }
    } else {
        (AlphaNumeric(s), ch)
    }
}

fn expect(ch: char, c: char) {
    if ch != c {
        bad_parse::cond.raise(())
    }
}

fn parse_reader(rdr: @io::Reader) -> Version {
    let (major, ch) = take_num(rdr, rdr.read_char());
    expect(ch, '.');
    let (minor, ch) = take_num(rdr, rdr.read_char());
    expect(ch, '.');
    let (patch, ch) = take_num(rdr, rdr.read_char());

    let mut pre = ~[];
    let mut build = ~[];

    let mut ch = ch;
    if ch == '-' {
        loop {
            let (id, c) = take_ident(rdr, rdr.read_char());
            pre.push(id);
            ch = c;
            if ch != '.' { break; }
        }
    }

    if ch == '+' {
        loop {
            let (id, c) = take_ident(rdr, rdr.read_char());
            build.push(id);
            ch = c;
            if ch != '.' { break; }
        }
    }

    Version {
        major: major,
        minor: minor,
        patch: patch,
        pre: pre,
        build: build,
    }
}

pub fn parse(s: &str) -> Option<Version> {
    if !s.is_ascii() {
        return None;
    }
    let s = s.trim();
    let mut bad = false;
    do bad_parse::cond.trap(|_| { debug!("bad"); bad = true }).in {
        do io::with_str_reader(s) |rdr| {
            let v = parse_reader(rdr);
            if bad || v.to_str() != s.to_owned() {
                None
            } else {
                Some(v)
            }
        }
    }
}

#[test]
fn test_parse() {
    assert_eq!(parse(""), None);
    assert_eq!(parse("  "), None);
    assert_eq!(parse("1"), None);
    assert_eq!(parse("1.2"), None);
    assert_eq!(parse("1.2"), None);
    assert_eq!(parse("1"), None);
    assert_eq!(parse("1.2"), None);
    assert_eq!(parse("1.2.3-"), None);
    assert_eq!(parse("a.b.c"), None);
    assert_eq!(parse("1.2.3 abc"), None);

    assert!(parse("1.2.3") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[],
        build: ~[],
    }));
    assert!(parse("  1.2.3  ") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[],
        build: ~[],
    }));
    assert!(parse("1.2.3-alpha1") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[AlphaNumeric(~"alpha1")],
        build: ~[]
    }));
    assert!(parse("  1.2.3-alpha1  ") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[AlphaNumeric(~"alpha1")],
        build: ~[]
    }));
    assert!(parse("1.2.3+build5") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[],
        build: ~[AlphaNumeric(~"build5")]
    }));
    assert!(parse("  1.2.3+build5  ") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[],
        build: ~[AlphaNumeric(~"build5")]
    }));
    assert!(parse("1.2.3-alpha1+build5") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[AlphaNumeric(~"alpha1")],
        build: ~[AlphaNumeric(~"build5")]
    }));
    assert!(parse("  1.2.3-alpha1+build5  ") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[AlphaNumeric(~"alpha1")],
        build: ~[AlphaNumeric(~"build5")]
    }));
    assert!(parse("1.2.3-1.alpha1.9+build5.7.3aedf  ") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[Numeric(1),AlphaNumeric(~"alpha1"),Numeric(9)],
        build: ~[AlphaNumeric(~"build5"),
                 Numeric(7),
                 AlphaNumeric(~"3aedf")]
    }));

}

#[test]
fn test_eq() {
    assert_eq!(parse("1.2.3"), parse("1.2.3"));
    assert_eq!(parse("1.2.3-alpha1"), parse("1.2.3-alpha1"));
}

#[test]
fn test_ne() {
    assert!(parse("0.0.0")       != parse("0.0.1"));
    assert!(parse("0.0.0")       != parse("0.1.0"));
    assert!(parse("0.0.0")       != parse("1.0.0"));
    assert!(parse("1.2.3-alpha") != parse("1.2.3-beta"));
}

#[test]
fn test_lt() {
    assert!(parse("0.0.0")        < parse("1.2.3-alpha2"));
    assert!(parse("1.0.0")        < parse("1.2.3-alpha2"));
    assert!(parse("1.2.0")        < parse("1.2.3-alpha2"));
    assert!(parse("1.2.3-alpha1") < parse("1.2.3"));
    assert!(parse("1.2.3-alpha1") < parse("1.2.3-alpha2"));
    assert!(!(parse("1.2.3-alpha2") < parse("1.2.3-alpha2")));
}

#[test]
fn test_le() {
    assert!(parse("0.0.0")        <= parse("1.2.3-alpha2"));
    assert!(parse("1.0.0")        <= parse("1.2.3-alpha2"));
    assert!(parse("1.2.0")        <= parse("1.2.3-alpha2"));
    assert!(parse("1.2.3-alpha1") <= parse("1.2.3-alpha2"));
    assert!(parse("1.2.3-alpha2") <= parse("1.2.3-alpha2"));
}

#[test]
fn test_gt() {
    assert!(parse("1.2.3-alpha2") > parse("0.0.0"));
    assert!(parse("1.2.3-alpha2") > parse("1.0.0"));
    assert!(parse("1.2.3-alpha2") > parse("1.2.0"));
    assert!(parse("1.2.3-alpha2") > parse("1.2.3-alpha1"));
    assert!(parse("1.2.3")        > parse("1.2.3-alpha2"));
    assert!(!(parse("1.2.3-alpha2") > parse("1.2.3-alpha2")));
}

#[test]
fn test_ge() {
    assert!(parse("1.2.3-alpha2") >= parse("0.0.0"));
    assert!(parse("1.2.3-alpha2") >= parse("1.0.0"));
    assert!(parse("1.2.3-alpha2") >= parse("1.2.0"));
    assert!(parse("1.2.3-alpha2") >= parse("1.2.3-alpha1"));
    assert!(parse("1.2.3-alpha2") >= parse("1.2.3-alpha2"));
}

#[test]
fn test_spec_order() {

    let vs = ["1.0.0-alpha",
              "1.0.0-alpha.1",
              "1.0.0-beta.2",
              "1.0.0-beta.11",
              "1.0.0-rc.1",
              "1.0.0-rc.1+build.1",
              "1.0.0",
              "1.0.0+0.3.7",
              "1.3.7+build",
              "1.3.7+build.2.b8f12d7",
              "1.3.7+build.11.e0f985a"];
    let mut i = 1;
    while i < vs.len() {
        let a = parse(vs[i-1]).get();
        let b = parse(vs[i]).get();
        assert!(a < b);
        i += 1;
    }
}
<commit_msg>auto merge of #7726 : omasanori/rust/semver-2.0.0, r=graydon<commit_after>// Copyright 2012 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.

//! Semver parsing and logic

#[allow(missing_doc)];

use std::char;
use std::cmp;
use std::io::{ReaderUtil};
use std::io;
use std::option::{Option, Some, None};
use std::to_str::ToStr;
use std::uint;

#[deriving(Eq)]
pub enum Identifier {
    Numeric(uint),
    AlphaNumeric(~str)
}

impl cmp::Ord for Identifier {
    #[inline]
    fn lt(&self, other: &Identifier) -> bool {
        match (self, other) {
            (&Numeric(a), &Numeric(b)) => a < b,
            (&Numeric(_), _) => true,
            (&AlphaNumeric(ref a), &AlphaNumeric(ref b)) => *a < *b,
            (&AlphaNumeric(_), _) => false
        }
    }
    #[inline]
    fn le(&self, other: &Identifier) -> bool {
        ! (other < self)
    }
    #[inline]
    fn gt(&self, other: &Identifier) -> bool {
        other < self
    }
    #[inline]
    fn ge(&self, other: &Identifier) -> bool {
        ! (self < other)
    }
}

impl ToStr for Identifier {
    #[inline]
    fn to_str(&self) -> ~str {
        match self {
            &Numeric(n) => n.to_str(),
            &AlphaNumeric(ref s) => s.to_str()
        }
    }
}

#[deriving(Eq)]
pub struct Version {
    major: uint,
    minor: uint,
    patch: uint,
    pre: ~[Identifier],
    build: ~[Identifier],
}

impl ToStr for Version {
    #[inline]
    fn to_str(&self) -> ~str {
        let s = fmt!("%u.%u.%u", self.major, self.minor, self.patch);
        let s = if self.pre.is_empty() {
            s
        } else {
            fmt!("%s-%s", s, self.pre.map(|i| i.to_str()).connect("."))
        };
        if self.build.is_empty() {
            s
        } else {
            fmt!("%s+%s", s, self.build.map(|i| i.to_str()).connect("."))
        }
    }
}

impl cmp::Ord for Version {
    #[inline]
    fn lt(&self, other: &Version) -> bool {

        self.major < other.major ||

            (self.major == other.major &&
             self.minor < other.minor) ||

            (self.major == other.major &&
             self.minor == other.minor &&
             self.patch < other.patch) ||

            (self.major == other.major &&
             self.minor == other.minor &&
             self.patch == other.patch &&
             // NB: semver spec says 0.0.0-pre < 0.0.0
             // but the version of ord defined for vec
             // says that [] < [pre], so we alter it
             // here.
             (match (self.pre.len(), other.pre.len()) {
                 (0, 0) => false,
                 (0, _) => false,
                 (_, 0) => true,
                 (_, _) => self.pre < other.pre
             }))
    }

    #[inline]
    fn le(&self, other: &Version) -> bool {
        ! (other < self)
    }
    #[inline]
    fn gt(&self, other: &Version) -> bool {
        other < self
    }
    #[inline]
    fn ge(&self, other: &Version) -> bool {
        ! (self < other)
    }
}

condition! {
    bad_parse: () -> ();
}

fn take_nonempty_prefix(rdr: @io::Reader,
                        ch: char,
                        pred: &fn(char) -> bool) -> (~str, char) {
    let mut buf = ~"";
    let mut ch = ch;
    while pred(ch) {
        buf.push_char(ch);
        ch = rdr.read_char();
    }
    if buf.is_empty() {
        bad_parse::cond.raise(())
    }
    debug!("extracted nonempty prefix: %s", buf);
    (buf, ch)
}

fn take_num(rdr: @io::Reader, ch: char) -> (uint, char) {
    let (s, ch) = take_nonempty_prefix(rdr, ch, char::is_digit);
    match uint::from_str(s) {
        None => { bad_parse::cond.raise(()); (0, ch) },
        Some(i) => (i, ch)
    }
}

fn take_ident(rdr: @io::Reader, ch: char) -> (Identifier, char) {
    let (s,ch) = take_nonempty_prefix(rdr, ch, char::is_alphanumeric);
    if s.iter().all(char::is_digit) {
        match uint::from_str(s) {
            None => { bad_parse::cond.raise(()); (Numeric(0), ch) },
            Some(i) => (Numeric(i), ch)
        }
    } else {
        (AlphaNumeric(s), ch)
    }
}

fn expect(ch: char, c: char) {
    if ch != c {
        bad_parse::cond.raise(())
    }
}

fn parse_reader(rdr: @io::Reader) -> Version {
    let (major, ch) = take_num(rdr, rdr.read_char());
    expect(ch, '.');
    let (minor, ch) = take_num(rdr, rdr.read_char());
    expect(ch, '.');
    let (patch, ch) = take_num(rdr, rdr.read_char());

    let mut pre = ~[];
    let mut build = ~[];

    let mut ch = ch;
    if ch == '-' {
        loop {
            let (id, c) = take_ident(rdr, rdr.read_char());
            pre.push(id);
            ch = c;
            if ch != '.' { break; }
        }
    }

    if ch == '+' {
        loop {
            let (id, c) = take_ident(rdr, rdr.read_char());
            build.push(id);
            ch = c;
            if ch != '.' { break; }
        }
    }

    Version {
        major: major,
        minor: minor,
        patch: patch,
        pre: pre,
        build: build,
    }
}

pub fn parse(s: &str) -> Option<Version> {
    if !s.is_ascii() {
        return None;
    }
    let s = s.trim();
    let mut bad = false;
    do bad_parse::cond.trap(|_| { debug!("bad"); bad = true }).in {
        do io::with_str_reader(s) |rdr| {
            let v = parse_reader(rdr);
            if bad || v.to_str() != s.to_owned() {
                None
            } else {
                Some(v)
            }
        }
    }
}

#[test]
fn test_parse() {
    assert_eq!(parse(""), None);
    assert_eq!(parse("  "), None);
    assert_eq!(parse("1"), None);
    assert_eq!(parse("1.2"), None);
    assert_eq!(parse("1.2"), None);
    assert_eq!(parse("1"), None);
    assert_eq!(parse("1.2"), None);
    assert_eq!(parse("1.2.3-"), None);
    assert_eq!(parse("a.b.c"), None);
    assert_eq!(parse("1.2.3 abc"), None);

    assert!(parse("1.2.3") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[],
        build: ~[],
    }));
    assert!(parse("  1.2.3  ") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[],
        build: ~[],
    }));
    assert!(parse("1.2.3-alpha1") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[AlphaNumeric(~"alpha1")],
        build: ~[]
    }));
    assert!(parse("  1.2.3-alpha1  ") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[AlphaNumeric(~"alpha1")],
        build: ~[]
    }));
    assert!(parse("1.2.3+build5") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[],
        build: ~[AlphaNumeric(~"build5")]
    }));
    assert!(parse("  1.2.3+build5  ") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[],
        build: ~[AlphaNumeric(~"build5")]
    }));
    assert!(parse("1.2.3-alpha1+build5") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[AlphaNumeric(~"alpha1")],
        build: ~[AlphaNumeric(~"build5")]
    }));
    assert!(parse("  1.2.3-alpha1+build5  ") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[AlphaNumeric(~"alpha1")],
        build: ~[AlphaNumeric(~"build5")]
    }));
    assert!(parse("1.2.3-1.alpha1.9+build5.7.3aedf  ") == Some(Version {
        major: 1u,
        minor: 2u,
        patch: 3u,
        pre: ~[Numeric(1),AlphaNumeric(~"alpha1"),Numeric(9)],
        build: ~[AlphaNumeric(~"build5"),
                 Numeric(7),
                 AlphaNumeric(~"3aedf")]
    }));

}

#[test]
fn test_eq() {
    assert_eq!(parse("1.2.3"), parse("1.2.3"));
    assert_eq!(parse("1.2.3-alpha1"), parse("1.2.3-alpha1"));
    assert_eq!(parse("1.2.3+build.42"), parse("1.2.3+build.42"));
    assert_eq!(parse("1.2.3-alpha1+42"), parse("1.2.3-alpha1+42"));
}

#[test]
fn test_ne() {
    assert!(parse("0.0.0")       != parse("0.0.1"));
    assert!(parse("0.0.0")       != parse("0.1.0"));
    assert!(parse("0.0.0")       != parse("1.0.0"));
    assert!(parse("1.2.3-alpha") != parse("1.2.3-beta"));
    assert!(parse("1.2.3+23")    != parse("1.2.3+42"));
}

#[test]
fn test_lt() {
    assert!(parse("0.0.0")        < parse("1.2.3-alpha2"));
    assert!(parse("1.0.0")        < parse("1.2.3-alpha2"));
    assert!(parse("1.2.0")        < parse("1.2.3-alpha2"));
    assert!(parse("1.2.3-alpha1") < parse("1.2.3"));
    assert!(parse("1.2.3-alpha1") < parse("1.2.3-alpha2"));
    assert!(!(parse("1.2.3-alpha2") < parse("1.2.3-alpha2")));
    assert!(!(parse("1.2.3+23")     < parse("1.2.3+42")));
}

#[test]
fn test_le() {
    assert!(parse("0.0.0")        <= parse("1.2.3-alpha2"));
    assert!(parse("1.0.0")        <= parse("1.2.3-alpha2"));
    assert!(parse("1.2.0")        <= parse("1.2.3-alpha2"));
    assert!(parse("1.2.3-alpha1") <= parse("1.2.3-alpha2"));
    assert!(parse("1.2.3-alpha2") <= parse("1.2.3-alpha2"));
    assert!(parse("1.2.3+23")     <= parse("1.2.3+42"));
}

#[test]
fn test_gt() {
    assert!(parse("1.2.3-alpha2") > parse("0.0.0"));
    assert!(parse("1.2.3-alpha2") > parse("1.0.0"));
    assert!(parse("1.2.3-alpha2") > parse("1.2.0"));
    assert!(parse("1.2.3-alpha2") > parse("1.2.3-alpha1"));
    assert!(parse("1.2.3")        > parse("1.2.3-alpha2"));
    assert!(!(parse("1.2.3-alpha2") > parse("1.2.3-alpha2")));
    assert!(!(parse("1.2.3+23")     > parse("1.2.3+42")));
}

#[test]
fn test_ge() {
    assert!(parse("1.2.3-alpha2") >= parse("0.0.0"));
    assert!(parse("1.2.3-alpha2") >= parse("1.0.0"));
    assert!(parse("1.2.3-alpha2") >= parse("1.2.0"));
    assert!(parse("1.2.3-alpha2") >= parse("1.2.3-alpha1"));
    assert!(parse("1.2.3-alpha2") >= parse("1.2.3-alpha2"));
    assert!(parse("1.2.3+23")     >= parse("1.2.3+42"));
}

#[test]
fn test_spec_order() {

    let vs = ["1.0.0-alpha",
              "1.0.0-alpha.1",
              "1.0.0-alpha.beta",
              "1.0.0-beta",
              "1.0.0-beta.2",
              "1.0.0-beta.11",
              "1.0.0-rc.1",
              "1.0.0"];
    let mut i = 1;
    while i < vs.len() {
        let a = parse(vs[i-1]).get();
        let b = parse(vs[i]).get();
        assert!(a < b);
        i += 1;
    }
}
<|endoftext|>


<commit_before>// Copyright 2012 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.

//! Temporary files and directories

#[forbid(deprecated_mode)];

use core::os;
use core::prelude::*;
use core::rand;
use core::str;

pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
    let r = rand::Rng();
    let mut i = 0u;
    while (i < 1000u) {
        let p = tmpdir.push(r.gen_str(16u) +
                            str::from_slice(suffix));
        if os::make_dir(&p, 0x1c0i32) {  // FIXME: u+rwx (#2349)
            return Some(p);
        }
        i += 1u;
    }
    return None;
}

#[test]
fn test_mkdtemp() {
    let r = mkdtemp(&Path("."), "foobar");
    match r {
        Some(ref p) => {
            os::remove_dir(p);
            assert(str::ends_with(p.to_str(), "foobar"));
        }
        _ => assert(false)
    }
}
<commit_msg>clean up tempfile module and rm FIXME<commit_after>// Copyright 2013 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.

//! Temporary files and directories

#[forbid(deprecated_mode)];

use core::os;
use core::prelude::*;
use core::rand;
use core::str;

pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
    let r = rand::Rng();
    for 1000.times {
        let p = tmpdir.push(r.gen_str(16) + suffix);
        if os::make_dir(&p, 0x1c0) { // 700
            return Some(p);
        }
    }
    None
}

#[test]
fn test_mkdtemp() {
    let p = mkdtemp(&Path("."), "foobar").unwrap();
    os::remove_dir(&p);
    assert str::ends_with(p.to_str(), "foobar");
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate git2;
extern crate yaml_rust;

use backend::Backend;
use cli::cli;
use conf::{Conf,get_configuration,create_default_config,Value,MonitoredRemote};
use constants::*;

use std::collections::HashMap;

use git2::Repository;

// util mod def needs to be first b/c of macro definitions and usage in other modules
#[macro_use]
mod util;
mod backend;
mod cli;
mod conf;
mod constants;

fn format_value(value: Value, data: String) -> String {
    format!("{}{}{}{}", value.pre_format, value.label, data, value.post_format)
}

fn substiute_special_values(s: String, values: &HashMap<String, String>) -> String {
    let mut r:String = s.clone();
    for (k, v) in values {
        r = r.replace(k, &v);
    }
    r
}

// struct for displaying all the data -- the actual program
struct Program {
    out: Vec<String>,
    backend: Backend,
    conf: Conf,
    debug: bool
}

impl Program {
    pub fn new(backend: Backend, conf: Conf, debug: bool) -> Program {
        let out: Vec<String> = Vec::new();
        Program { out: out, backend: backend, conf: conf, debug: debug }
    }

    // add repository state to output buffer
    fn add_repository_state(&mut self) {
        let repo_state = self.backend.get_repository_state();
        if !repo_state.is_empty() {
            self.out.push(repo_state);
        }
    }

    fn add_monitored_branches_state(&mut self) {
        let mut local_branch: String = self.backend.get_current_branch_name();
        let mr = match self.conf.get_remotes_monitoring() {
            Some(x) => x,
            None => return (),
        };
        for monitored_remote in mr {
            let b = match monitored_remote.branch {
                Some(x) => x,
                None => local_branch.clone()
            };
            let (ahead, behind) = match self.backend.get_remote_branch_ahead_behind(&monitored_remote.remote_name, &b) {
                Some(x) => x,
                None => (0, 0),
            };
            if monitored_remote.display_if_uptodate || ahead > 0 || behind > 0 {
                if let (Some(a_v), Some(b_v)) = (
                    self.conf.get_difference_ahead_value(),
                    self.conf.get_difference_behind_value()
                ) {
                    let mut special_values: HashMap<String, String> = HashMap::new();
                    special_values.insert("<BRANCH>".to_string(), b);
                    special_values.insert("<REMOTE>".to_string(), monitored_remote.remote_name);
                    let mut local: String = format!(
                        "{}{}",
                        substiute_special_values(monitored_remote.pre_format, &special_values),
                        substiute_special_values(monitored_remote.post_format, &special_values),
                    );
                    if ahead > 0 {
                        local += &format_value(a_v, ahead.to_string());
                    }
                    if behind > 0 {
                        local += &format_value(b_v, behind.to_string());
                    }
                    self.out.push(local);
                }
            }
        }
    }

    fn add_file_status(&mut self) {
        if let Some(s) = self.backend.get_file_status() {
            if !s.is_empty() {
                let mut o = String::from("");

                if let Some(x) = s.get(NEW_KEY) {
                    match self.conf.get_new_value() {
                        Some(y) => o += &format!("{}{}{}{}", y.pre_format, y.label, x, y.post_format),
                        None => (),
                    };
                }
                if let Some(x) = s.get(CHANGED_KEY) {
                    match self.conf.get_changed_value() {
                        Some(y) => o += &format!("{}{}{}{}", y.pre_format, y.label, x, y.post_format),
                        None => (),
                    };
                }
                if let Some(x) = s.get(STAGED_KEY) {
                    match self.conf.get_staged_value() {
                        Some(y) => o += &format!("{}{}{}{}", y.pre_format, y.label, x, y.post_format),
                        None => (),
                    };
                }
                if let Some(x) = s.get(CONFLICTS_KEY) {
                    match self.conf.get_conflicts_value() {
                        Some(y) => o += &format!("{}{}{}{}", y.pre_format, y.label, x, y.post_format),
                        None => (),
                    };
                }
                self.out.push(o);
            }
        }
    }

    fn populate(&mut self) {
        self.add_repository_state();
        self.add_monitored_branches_state();
        self.add_file_status();
    }

    // print output buffer
    fn output(&self) {
        log!(self, "# of blocks = {}", self.out.len());
        println!("{}", self.out.join("|"));
    }
}

fn main() {
    let app = cli();
    let matches = app.get_matches();

    let debug_enabled = matches.is_present("debug");
    if debug_enabled { println!("Debug messages are enabled."); }

    let repo = match Repository::open(".") {
        Ok(repo) => repo,
        // not a git repository, ignore
        Err(e) => {
            if debug_enabled { println!("This is not a git repository: {:?}", e); }
            return ();
        }
    };

    let mut conf_path: Option<String> = None;
    if matches.is_present("config") {
        conf_path = Some(String::from(matches.value_of("config").unwrap()));
    }

    let conf = get_configuration(conf_path);

    if matches.is_present(CLI_DEFAULT_CONFIG_SUBC_NAME) {
        let p = get_default_config_path();
        match create_default_config(p.clone()) {
            Ok(path) => {
                println!("Configuration file created at \"{}\"", path);
                return ();
            }
            Err(e) => {
                println!("Failed to create configuration file \"{}\": {}", p.to_str().unwrap(), e);
                return ();
            }
        };
    }

    let backend = Backend{ repo: repo, debug: debug_enabled };
    let mut output = Program::new(backend, conf, debug_enabled);

    output.populate();
    output.output();
}
<commit_msg>add fixme: can't find git repo if not in root<commit_after>extern crate clap;
extern crate git2;
extern crate yaml_rust;

use backend::Backend;
use cli::cli;
use conf::{Conf,get_configuration,create_default_config,Value,MonitoredRemote};
use constants::*;

use std::collections::HashMap;

use git2::Repository;

// util mod def needs to be first b/c of macro definitions and usage in other modules
#[macro_use]
mod util;
mod backend;
mod cli;
mod conf;
mod constants;

fn format_value(value: Value, data: String) -> String {
    format!("{}{}{}{}", value.pre_format, value.label, data, value.post_format)
}

fn substiute_special_values(s: String, values: &HashMap<String, String>) -> String {
    let mut r:String = s.clone();
    for (k, v) in values {
        r = r.replace(k, &v);
    }
    r
}

// struct for displaying all the data -- the actual program
struct Program {
    out: Vec<String>,
    backend: Backend,
    conf: Conf,
    debug: bool
}

impl Program {
    pub fn new(backend: Backend, conf: Conf, debug: bool) -> Program {
        let out: Vec<String> = Vec::new();
        Program { out: out, backend: backend, conf: conf, debug: debug }
    }

    // add repository state to output buffer
    fn add_repository_state(&mut self) {
        let repo_state = self.backend.get_repository_state();
        if !repo_state.is_empty() {
            self.out.push(repo_state);
        }
    }

    fn add_monitored_branches_state(&mut self) {
        let mut local_branch: String = self.backend.get_current_branch_name();
        let mr = match self.conf.get_remotes_monitoring() {
            Some(x) => x,
            None => return (),
        };
        for monitored_remote in mr {
            let b = match monitored_remote.branch {
                Some(x) => x,
                None => local_branch.clone()
            };
            let (ahead, behind) = match self.backend.get_remote_branch_ahead_behind(&monitored_remote.remote_name, &b) {
                Some(x) => x,
                None => (0, 0),
            };
            if monitored_remote.display_if_uptodate || ahead > 0 || behind > 0 {
                if let (Some(a_v), Some(b_v)) = (
                    self.conf.get_difference_ahead_value(),
                    self.conf.get_difference_behind_value()
                ) {
                    let mut special_values: HashMap<String, String> = HashMap::new();
                    special_values.insert("<BRANCH>".to_string(), b);
                    special_values.insert("<REMOTE>".to_string(), monitored_remote.remote_name);
                    let mut local: String = format!(
                        "{}{}",
                        substiute_special_values(monitored_remote.pre_format, &special_values),
                        substiute_special_values(monitored_remote.post_format, &special_values),
                    );
                    if ahead > 0 {
                        local += &format_value(a_v, ahead.to_string());
                    }
                    if behind > 0 {
                        local += &format_value(b_v, behind.to_string());
                    }
                    self.out.push(local);
                }
            }
        }
    }

    fn add_file_status(&mut self) {
        if let Some(s) = self.backend.get_file_status() {
            if !s.is_empty() {
                let mut o = String::from("");

                if let Some(x) = s.get(NEW_KEY) {
                    match self.conf.get_new_value() {
                        Some(y) => o += &format!("{}{}{}{}", y.pre_format, y.label, x, y.post_format),
                        None => (),
                    };
                }
                if let Some(x) = s.get(CHANGED_KEY) {
                    match self.conf.get_changed_value() {
                        Some(y) => o += &format!("{}{}{}{}", y.pre_format, y.label, x, y.post_format),
                        None => (),
                    };
                }
                if let Some(x) = s.get(STAGED_KEY) {
                    match self.conf.get_staged_value() {
                        Some(y) => o += &format!("{}{}{}{}", y.pre_format, y.label, x, y.post_format),
                        None => (),
                    };
                }
                if let Some(x) = s.get(CONFLICTS_KEY) {
                    match self.conf.get_conflicts_value() {
                        Some(y) => o += &format!("{}{}{}{}", y.pre_format, y.label, x, y.post_format),
                        None => (),
                    };
                }
                self.out.push(o);
            }
        }
    }

    fn populate(&mut self) {
        self.add_repository_state();
        self.add_monitored_branches_state();
        self.add_file_status();
    }

    // print output buffer
    fn output(&self) {
        log!(self, "# of blocks = {}", self.out.len());
        println!("{}", self.out.join("|"));
    }
}

fn main() {
    let app = cli();
    let matches = app.get_matches();

    let debug_enabled = matches.is_present("debug");
    if debug_enabled { println!("Debug messages are enabled."); }

    // FIXME: doesn't work when there is no .git inside .
    let repo = match Repository::open(".") {
        Ok(repo) => repo,
        // not a git repository, ignore
        Err(e) => {
            if debug_enabled { println!("This is not a git repository: {:?}", e); }
            return ();
        }
    };

    let mut conf_path: Option<String> = None;
    if matches.is_present("config") {
        conf_path = Some(String::from(matches.value_of("config").unwrap()));
    }

    let conf = get_configuration(conf_path);

    if matches.is_present(CLI_DEFAULT_CONFIG_SUBC_NAME) {
        let p = get_default_config_path();
        match create_default_config(p.clone()) {
            Ok(path) => {
                println!("Configuration file created at \"{}\"", path);
                return ();
            }
            Err(e) => {
                println!("Failed to create configuration file \"{}\": {}", p.to_str().unwrap(), e);
                return ();
            }
        };
    }

    let backend = Backend{ repo: repo, debug: debug_enabled };
    let mut output = Program::new(backend, conf, debug_enabled);

    output.populate();
    output.output();
}
<|endoftext|>


<commit_before>extern crate rustwlc;

struct Data {
    handle: rustwlc::WLCHandle,
    grab: rustwlc::Point,
    drag_edge: rustwlc::ResizeEdge
}

pub data: mut 'static Data;

fn start_interactive_action(view: rustwlc::WLCHandle, origin: rustwlc::Point) -> bool
{
    data.handle = view;
    data.grab = origin;
    view.bring_to_front();
    return true;
}

fn main() {
    println!("Hello, world!");

}
<commit_msg>Added uncompiling skeleton<commit_after>extern crate rustwlc;

struct Data {
    handle: rustwlc::WLCHandle,
    grab: rustwlc::Point,
    drag_edge: rustwlc::ResizeEdge
}

pub data: mut 'static Data;

fn start_interactive_action(view: rustwlc::WLCHandle, origin: rustwlc::Point) -> bool
{
    data.handle = view;
    data.grab = origin;
    view.bring_to_front();
    return true;
}

fn main() {
    let interface = {};
    println!("Hello, world!");
    if (!rustwlc::init(interface, 0, "")) {
        panic!("Unable to initialize wlc!");
    }
    rustwlc::run();
}
<|endoftext|>


<commit_before>#[derive(Clone, Copy, Debug)]
enum Const {
  Data,
  Codata,
}

impl ToString for Const {
  fn to_string(&self) -> String {
    use Const::*;
    match *self {
      Data => "data".to_string(),
      Codata => "codata".to_string(),
    }
  }
}

#[derive(Clone, Debug)]
struct Var {
  name: String,
  idx: i32,
}

impl Var {
  pub fn new(name: &str, idx: i32) -> Var {
    Var {
      name: name.to_string(),
      idx: idx,
    }
  }
}

fn vn(name: &str, idx: i32) -> Var {
  Var::new(name, idx)
}

fn v(name: &str) -> Var {
  vn(name, 0)
}

impl ToString for Var {
  fn to_string(&self) -> String {
    self.name.clone()
    // + "@" + &self.idx.to_string()
  }
}

#[derive(Clone, Debug)]
enum Expr {
  // Type system constants
  Const(Const),
  // Bound variables
  Var(Var),
  // Lambda
  Lam(Var, Box<Expr>, Box<Expr>),
  // "forall"
  Pi(Var, Box<Expr>, Box<Expr>),
  // Function application
  App(Box<Expr>, Box<Expr>),
}

impl Expr {
  pub fn constant(constant: Const) -> Expr {
    Expr::Const(constant)
  }
  pub fn var(v: &Var) -> Expr {
    Expr::Var(v.clone())
  }
  pub fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Lam(var, Box::new(ty), Box::new(body))
  }
  pub fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Pi(var, Box::new(ty), Box::new(body))
  }
  pub fn app(f: Expr, arg: Expr) -> Expr {
    Expr::App(Box::new(f), Box::new(arg))
  }

  pub fn is_constant(&self) -> bool {
    use Expr::*;
    match *self {
      Const(_) => true,
      _ => false,
    }
  }
  pub fn is_var(&self) -> bool {
    use Expr::*;
    match *self {
      Var(_) => true,
      _ => false,
    }
  }
  pub fn is_lam(&self) -> bool {
    use Expr::*;
    match *self {
      Lam(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_pi(&self) -> bool {
    use Expr::*;
    match *self {
      Pi(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_app(&self) -> bool {
    use Expr::*;
    match *self {
      App(_, _) => true,
      _ => false,
    }
  }
}

fn constant(c: Const) -> Expr {
  Expr::constant(c)
}
fn var(v: &Var) -> Expr {
  Expr::var(v)
}
fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
  Expr::lam(var, ty, body)
}
fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
  Expr::pi(var, ty, body)
}
fn app(f: Expr, arg: Expr) -> Expr {
  Expr::app(f, arg)
}

impl ToString for Expr {
  fn to_string(&self) -> String {
    use Expr::*;
    match *self {
      Const(ref constant) => constant.to_string(),
      Var(ref var) => var.to_string(),
      Lam(ref var, ref ty, ref body) => {
        var.to_string() + ":" + &ty.to_string() + " -> " + &body.to_string()
      }
      Pi(ref var, ref ty, ref body) => {
        "forall (".to_string() + &var.to_string() + ":" + &ty.to_string() +
        ") -> " + &body.to_string()
      }
      App(ref f, ref arg) => {
        if f.is_lam() || f.is_pi() {
          "(".to_string() + &f.to_string() + ") " + &arg.to_string()
        } else {
          f.to_string() + " " + &arg.to_string()
        }
      }
    }
  }
}

fn main() {
  println!("{}", Const::Data.to_string());
  let a = v("a");
  let x = v("x");
  let expra = var(&a);
  let exprx = var(&x);
  println!("{}", x.to_string());
  let id = pi(a.clone(), constant(Const::Data), lam(x, expra, exprx));
  println!("{}", id.to_string());
  let apply_id = app(app(id, var(&v("int"))), var(&v("1")));
  println!("{}", apply_id.to_string());
}
<commit_msg>Add index to printing var when index > 0.<commit_after>#[derive(Clone, Copy, Debug)]
enum Const {
  Data,
  Codata,
}

impl ToString for Const {
  fn to_string(&self) -> String {
    use Const::*;
    match *self {
      Data => "data".to_string(),
      Codata => "codata".to_string(),
    }
  }
}

#[derive(Clone, Debug)]
struct Var {
  name: String,
  idx: i32,
}

impl Var {
  pub fn new(name: &str, idx: i32) -> Var {
    Var {
      name: name.to_string(),
      idx: idx,
    }
  }
}

fn vn(name: &str, idx: i32) -> Var {
  Var::new(name, idx)
}

fn v(name: &str) -> Var {
  vn(name, 0)
}

impl ToString for Var {
  fn to_string(&self) -> String {
    if self.idx == 0 {
      self.name.clone()
    } else {
      self.name.clone() + "@" + &self.idx.to_string()
    }
  }
}

#[derive(Clone, Debug)]
enum Expr {
  // Type system constants
  Const(Const),
  // Bound variables
  Var(Var),
  // Lambda
  Lam(Var, Box<Expr>, Box<Expr>),
  // "forall"
  Pi(Var, Box<Expr>, Box<Expr>),
  // Function application
  App(Box<Expr>, Box<Expr>),
}

impl Expr {
  pub fn constant(constant: Const) -> Expr {
    Expr::Const(constant)
  }
  pub fn var(v: &Var) -> Expr {
    Expr::Var(v.clone())
  }
  pub fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Lam(var, Box::new(ty), Box::new(body))
  }
  pub fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
    Expr::Pi(var, Box::new(ty), Box::new(body))
  }
  pub fn app(f: Expr, arg: Expr) -> Expr {
    Expr::App(Box::new(f), Box::new(arg))
  }

  pub fn is_constant(&self) -> bool {
    use Expr::*;
    match *self {
      Const(_) => true,
      _ => false,
    }
  }
  pub fn is_var(&self) -> bool {
    use Expr::*;
    match *self {
      Var(_) => true,
      _ => false,
    }
  }
  pub fn is_lam(&self) -> bool {
    use Expr::*;
    match *self {
      Lam(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_pi(&self) -> bool {
    use Expr::*;
    match *self {
      Pi(_, _, _) => true,
      _ => false,
    }
  }
  pub fn is_app(&self) -> bool {
    use Expr::*;
    match *self {
      App(_, _) => true,
      _ => false,
    }
  }
}

fn constant(c: Const) -> Expr {
  Expr::constant(c)
}
fn var(v: &Var) -> Expr {
  Expr::var(v)
}
fn lam(var: Var, ty: Expr, body: Expr) -> Expr {
  Expr::lam(var, ty, body)
}
fn pi(var: Var, ty: Expr, body: Expr) -> Expr {
  Expr::pi(var, ty, body)
}
fn app(f: Expr, arg: Expr) -> Expr {
  Expr::app(f, arg)
}

impl ToString for Expr {
  fn to_string(&self) -> String {
    use Expr::*;
    match *self {
      Const(ref constant) => constant.to_string(),
      Var(ref var) => var.to_string(),
      Lam(ref var, ref ty, ref body) => {
        var.to_string() + ":" + &ty.to_string() + " -> " + &body.to_string()
      }
      Pi(ref var, ref ty, ref body) => {
        "forall (".to_string() + &var.to_string() + ":" + &ty.to_string() +
        ") -> " + &body.to_string()
      }
      App(ref f, ref arg) => {
        if f.is_lam() || f.is_pi() {
          "(".to_string() + &f.to_string() + ") " + &arg.to_string()
        } else {
          f.to_string() + " " + &arg.to_string()
        }
      }
    }
  }
}

fn main() {
  println!("{}", Const::Data.to_string());
  let a = v("a");
  let x = v("x");
  let expra = var(&a);
  let exprx = var(&x);
  println!("{}", x.to_string());
  let id = pi(a.clone(), constant(Const::Data), lam(x, expra, exprx));
  println!("{}", id.to_string());
  let apply_id = app(app(id, var(&v("int"))), var(&v("1")));
  println!("{}", apply_id.to_string());
}
<|endoftext|>


<commit_before>extern crate piston_window;
extern crate rand;
extern crate find_folder;

use piston_window::*;
use rand::Rng;

#[derive(Debug,Copy,Clone,PartialEq)]
struct Candidate {
    coordinates: [f64; 4],
    color: [f32; 4],
}

fn generate_candidates(difficulty: f32) -> Vec<Candidate> {
    let mut candidate_positions = vec![
        (100.0, 100.0), (100.0, 250.0), (100.0, 400.0),
        (250.0, 100.0), (250.0, 250.0), (250.0, 400.0),
        (400.0, 100.0), (400.0, 250.0), (400.0, 400.0),
    ];
    let num_candidates = 5;
    let mut candidates = vec![];
    let random_component = rand::thread_rng().gen_range(450, 900) as f32 / 1000.0;
    let random_index = rand::thread_rng().gen_range(0, 3);
    let mut random_color = [
        0.3,
        0.3,
        0.3,
        1.0,
    ];
    random_color[random_index] = random_component;
    let variance = ::std::f32::consts::PI / difficulty;
    for i in 0..num_candidates {
        let which_position = rand::thread_rng().gen_range(0, candidate_positions.len());
        let pos = candidate_positions.remove(which_position);
        candidates.push(Candidate {
            coordinates: [pos.0, pos.1, 100.0, 100.0],
            color: restrict_color(math::hsv(random_color, variance * i as f32, 1.0, 1.0)),
        });
    }
    candidates
}

fn restrict_color(mut color: [f32; 4]) -> [f32; 4] {
    for c in color.iter_mut() {
        *c = 0.0f32.max(1.0f32.min(*c))
    }
    color
}

fn main() {
    let window: PistonWindow = WindowSettings::new(
            "colors",
            [600, 600]
        )
        .exit_on_esc(true)
        .build()
        .unwrap();

    let assets = find_folder::Search::ParentsThenKids(3, 3)
        .for_folder("assets").unwrap();
    let ref font = assets.join("FiraSans-Regular.ttf");
    let factory = window.factory.borrow().clone();
    let mut glyphs = Glyphs::new(font, factory).unwrap();

    let mut mouse_position = (0.0, 0.0);
    let mut difficulty = 3.0;
    let mut candidates = generate_candidates(difficulty);

    for e in window {
        if candidates.is_empty() {
            difficulty += 1.0;
            candidates = generate_candidates(difficulty);
        }
        let target_color = candidates[0].color;
        e.draw_2d(|c, g| {
           clear(target_color, g);

           let playing_surface = Rectangle::new([1.0, 1.0, 1.0, 1.0]);
           playing_surface.draw([50.0, 50.0, 500.0, 500.0], &c.draw_state, c.transform, g);

           let transform = c.transform.trans(10.0, 35.0);
           text::Text::new_color([1.0, 1.0, 1.0, 1.0], 32).draw(
               &format!("Level {}", difficulty - 2.0),
               &mut glyphs,
               &c.draw_state,
               transform, g
           );

           for candidate in &candidates {
               let r = Rectangle::new(candidate.color);
               r.draw(candidate.coordinates, &c.draw_state, c.transform, g);
           }
        });
        e.mouse_cursor(|x, y| {
            mouse_position = (x, y);
        });
        if let Some(button) = e.press_args() {
            if button == Button::Mouse(MouseButton::Left) {
                if let Some(clicked_on) = candidates.iter().filter(|candidate| {
                    mouse_position.0 > candidate.coordinates[0] &&
                       mouse_position.0 < (candidate.coordinates[0] + candidate.coordinates[2]) &&
                       mouse_position.1 > candidate.coordinates[1] &&
                       mouse_position.1 < (candidate.coordinates[1] + candidate.coordinates[3])
                }).next().cloned() {
                    if clicked_on.color == target_color {
                        candidates.retain(|&r| r != clicked_on);
                    } else {
                        break;
                    }
                }
            }
        };

    }
}
<commit_msg>Fix messed up whitespace<commit_after>extern crate piston_window;
extern crate rand;
extern crate find_folder;

use piston_window::*;
use rand::Rng;

#[derive(Debug,Copy,Clone,PartialEq)]
struct Candidate {
    coordinates: [f64; 4],
    color: [f32; 4],
}

fn generate_candidates(difficulty: f32) -> Vec<Candidate> {
    let mut candidate_positions = vec![
        (100.0, 100.0), (100.0, 250.0), (100.0, 400.0),
        (250.0, 100.0), (250.0, 250.0), (250.0, 400.0),
        (400.0, 100.0), (400.0, 250.0), (400.0, 400.0),
    ];
    let num_candidates = 5;
    let mut candidates = vec![];
    let random_component = rand::thread_rng().gen_range(450, 900) as f32 / 1000.0;
    let random_index = rand::thread_rng().gen_range(0, 3);
    let mut random_color = [
        0.3,
        0.3,
        0.3,
        1.0,
    ];
    random_color[random_index] = random_component;
    let variance = ::std::f32::consts::PI / difficulty;
    for i in 0..num_candidates {
        let which_position = rand::thread_rng().gen_range(0, candidate_positions.len());
        let pos = candidate_positions.remove(which_position);
        candidates.push(Candidate {
            coordinates: [pos.0, pos.1, 100.0, 100.0],
            color: restrict_color(math::hsv(random_color, variance * i as f32, 1.0, 1.0)),
        });
    }
    candidates
}

fn restrict_color(mut color: [f32; 4]) -> [f32; 4] {
    for c in color.iter_mut() {
        *c = 0.0f32.max(1.0f32.min(*c))
    }
    color
}

fn main() {
    let window: PistonWindow = WindowSettings::new(
            "colors",
            [600, 600]
        )
        .exit_on_esc(true)
        .build()
        .unwrap();

    let assets = find_folder::Search::ParentsThenKids(3, 3)
        .for_folder("assets").unwrap();
    let ref font = assets.join("FiraSans-Regular.ttf");
    let factory = window.factory.borrow().clone();
    let mut glyphs = Glyphs::new(font, factory).unwrap();

    let mut mouse_position = (0.0, 0.0);
    let mut difficulty = 3.0;
    let mut candidates = generate_candidates(difficulty);

    for e in window {
        if candidates.is_empty() {
            difficulty += 1.0;
            candidates = generate_candidates(difficulty);
        }
        let target_color = candidates[0].color;
        e.draw_2d(|c, g| {
            clear(target_color, g);

            let playing_surface = Rectangle::new([1.0, 1.0, 1.0, 1.0]);
            playing_surface.draw([50.0, 50.0, 500.0, 500.0], &c.draw_state, c.transform, g);

            let transform = c.transform.trans(10.0, 35.0);
            text::Text::new_color([1.0, 1.0, 1.0, 1.0], 32).draw(
                &format!("Level {}", difficulty - 2.0),
                &mut glyphs,
                &c.draw_state,
                transform, g
            );

            for candidate in &candidates {
                let r = Rectangle::new(candidate.color);
                r.draw(candidate.coordinates, &c.draw_state, c.transform, g);
            }
        });
        e.mouse_cursor(|x, y| {
            mouse_position = (x, y);
        });
        if let Some(button) = e.press_args() {
            if button == Button::Mouse(MouseButton::Left) {
                if let Some(clicked_on) = candidates.iter().filter(|candidate| {
                    mouse_position.0 > candidate.coordinates[0] &&
                        mouse_position.0 < (candidate.coordinates[0] + candidate.coordinates[2]) &&
                        mouse_position.1 > candidate.coordinates[1] &&
                        mouse_position.1 < (candidate.coordinates[1] + candidate.coordinates[3])
                }).next().cloned() {
                    if clicked_on.color == target_color {
                        candidates.retain(|&r| r != clicked_on);
                    } else {
                        break;
                    }
                }
            }
        };

    }
}
<|endoftext|>


<commit_before>use std::collections::{HashSet, HashMap};
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;

fn print_arg_error() {
    println!("incorrect arguments passed");
}

struct CsvDescriptor<'a> {
    file_path: &'a  Path,
    delimiter:      char,
    quote:          Option<char>,
}

impl<'a> std::fmt::Display for CsvDescriptor<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{} {} {:?}", self.file_path.display(), self.delimiter, self.quote)
    }
}

fn parse_args<'a>(path_arg:         &'a String,
                  delimiter_arg:    &'a String,
                  quote_arg:        &'a String) -> Result<CsvDescriptor<'a>, &'static str>
{

    let csv_file_path = Path::new(path_arg);

    let csv_delimiter = match delimiter_arg.chars().next() {
                            Some(result) => result,
                            None         => return Err("incorrect delimiter"),
                        };

    let csv_quote     = quote_arg.chars().next();

    Ok(CsvDescriptor {file_path: &csv_file_path, delimiter: csv_delimiter, quote: csv_quote})
}

fn get_csv_cols(csv_desc: &CsvDescriptor) -> Result<Vec<String>, String> {

    let csv_file = match File::open(csv_desc.file_path) {
        Err(why) => panic!("couldn't open csv @ {}: {}", csv_desc.file_path.display(), why),
        Ok(file) => file,
    };

    let csv_reader = BufReader::new(csv_file);

    let mut csv_line_iter = csv_reader.lines();

    let csv_header: String = match csv_line_iter.next() {
        Some(result) => match result {
                            Err(why) => return Err(format!("error getting csv header: {}", why)),
                            Ok(header) => header,
                        },
        None         => return Err("csv header reading failed".to_string()),
    };

    let csv_cols: Vec<String> = {
        let cols_iter = csv_header.split(csv_desc.delimiter);
        match csv_desc.quote {
            Some(q) => cols_iter.map(|s| {s.trim_matches(q).to_string()}).collect(),
            None    => cols_iter.map(|s| {s.to_string()}).collect(),
        }
    };

    Ok(csv_cols)
}

fn build_index(csv_desc: &CsvDescriptor) -> Result<HashMap<String, usize>, String> {
    // TODO it would probably be better to keep a File in the csv descriptor instead of a Path
    let mut csv_index = HashMap::new();
    let csv_file = match File::open(csv_desc.file_path) {
        Err(why) => panic!("couldn't open csv @ {}: {}", csv_desc.file_path.display(), why),
        Ok(file) => file,
    };

    let csv_reader = BufReader::new(csv_file);

    let mut csv_line_iter = csv_reader.lines().skip(1);

    let mut line_index = 0;
    loop {

        let csv_row: String = match csv_line_iter.next() {
            Some(result) => match result {
                                Err(why) => return Err(format!("error getting csv row: {}", why)),
                                Ok(header) => header,
                            },
            None         => break,
        };

        let csv_cols: Vec<String> = {
            let cols_iter = csv_row.split(csv_desc.delimiter);
            match csv_desc.quote {
                Some(q) => cols_iter.map(|s| {s.trim_matches(q).to_string()}).collect(),
                None    => cols_iter.map(|s| {s.to_string()}).collect(),
            }
        };

        // TODO: check if all lines have the same number of columns
        let key = format!("{}{}", csv_cols[0], csv_cols[1]);
        csv_index.insert(key, line_index);

        line_index += 1;
    }

    Ok(csv_index)
}

fn get_csv_row(csv_desc: &CsvDescriptor, line_num: usize) -> Result<Vec<String>, String> {

    let csv_file = match File::open(csv_desc.file_path) {
        Err(why) => panic!("couldn't open csv @ {}: {}", csv_desc.file_path.display(), why),
        Ok(file) => file,
    };

    let csv_reader = BufReader::new(csv_file);

    let mut csv_line_iter = csv_reader.lines().skip(line_num);

    let csv_row: String = match csv_line_iter.next() {
        Some(result) => match result {
                            Err(why) => return Err(format!("error getting csv row: {}", why)),
                            Ok(row) => row,
                        },
        None         => return Err("csv row reading failed".to_string()),
    };

    let result: Vec<String> = {
        let cols_iter = csv_row.split(csv_desc.delimiter);
        match csv_desc.quote {
            Some(q) => cols_iter.map(|s| {s.trim_matches(q).to_string()}).collect(),
            None    => cols_iter.map(|s| {s.to_string()}).collect(),
        }
    };

    Ok(result)
}

fn main() {

/*

1. Parse arguments
2. Open CSV files
3. Get columns (cols_N)
4. Get intersection of those two sets of columns(cols_to_compare)
5. Create {column name : column index in cols_N} dicts
6. Create {CSV_col_value : CSV row index in file} dicts, where CSV_col_value is a unique key made of the value of several CSV columns.
   For example, {Alex38 : 76}. In this example a name and age form a unique key for the 76th CSV row.
7. Get intersection of key sets of dicts from step 6 (row_keys_to_compare)
8. Loop through row_keys_to_compare, use dicts from step 6 to get line numbers for CSV files
    8.1 Loop through cols_to_compare, use dicts from step 5 to extract column values from CSV rows(step 8)
    8.2 Compare values

Input parameters: CSV paths, delimiters, quotes

For example, ./main file_1.csv "," "'" file_2.csv " " ""

*/

    /*** 1 ***/
    let args: Vec<String> = env::args().collect();
    if args.len() != 7 {
        print_arg_error();
        return;
    };

    let csv_desc_1: CsvDescriptor = match parse_args(&args[1], &args[2], &args[3]) {
        Err(why)    => panic!("error parsing arguments for CSV #1: {}", why),
        Ok(result)  => result,
    };

    let csv_desc_2: CsvDescriptor = match parse_args(&args[4], &args[5], &args[6]) {
        Err(why)    => panic!("error parsing arguments for CSV #2: {}", why),
        Ok(result)  => result,
    };

    /*** 2&3 ***/
    let csv_cols_1: Vec<String> = match get_csv_cols(&csv_desc_1) {
        Err(why) => panic!("couldn't get columns: {}", why),
        Ok(cols) => cols,
    };

    let csv_cols_2: Vec<String> = match get_csv_cols(&csv_desc_2) {
        Err(why) => panic!("couldn't get columns: {}", why),
        Ok(cols) => cols,
    };

    /*** 5 ***/
    let mut csv_col_index_1 = HashMap::new();
    for i in 0..csv_cols_1.len() {
        let key = csv_cols_1[i].clone();
        if csv_col_index_1.contains_key(&key) {
            panic!("duplicate column found in CSV #1: {}", key);
        };
        csv_col_index_1.insert(key, i);
    }

    let mut csv_col_index_2 = HashMap::new();
    for i in 0..csv_cols_2.len() {
        let key = csv_cols_2[i].clone();
        if csv_col_index_2.contains_key(&key) {
            panic!("duplicate column found in CSV #1: {}", key);
        };
        csv_col_index_2.insert(key, i);
    }

    /*** 4 ***/
    let mut cols_to_compare = HashSet::new();
    for col_1 in csv_col_index_1.keys() {
        if csv_col_index_2.contains_key(col_1) {
            cols_to_compare.insert(col_1);
        };
    }
    println!("{:?}", cols_to_compare);

    /*** 6 ***/
    // let's assume that the unique key is (col_0 + col_1)
    let csv_index_1 = match build_index(&csv_desc_1) {
        Err(why)  => panic!("failed building index #1: {}", why),
        Ok(index) => index,
    };

    let csv_index_2 = match build_index(&csv_desc_2) {
        Err(why)  => panic!("failed building index #2: {}", why),
        Ok(index) => index,
    };

    /*** 7 ***/
    let mut row_keys_to_compare = HashSet::new();
    for key_1 in csv_index_1.keys() {
        if csv_index_2.contains_key(key_1) {
            row_keys_to_compare.insert(key_1);
        };
    }
    println!("{:?}", row_keys_to_compare);

    /*** 8 ***/
    for row_key in row_keys_to_compare {

        let index_1 = *csv_index_1.get(row_key).unwrap(); // TODO: handle me
        let index_2 = *csv_index_2.get(row_key).unwrap();

        let row_1 = get_csv_row(&csv_desc_1, index_1).unwrap(); // TODO: handle me
        let row_2 = get_csv_row(&csv_desc_2, index_2).unwrap();

        for col in &cols_to_compare {
            let col_index_1 = *csv_col_index_1.get(*col).unwrap(); // TODO: handle me
            let col_index_2 = *csv_col_index_2.get(*col).unwrap();
            if row_1[col_index_1] != row_2[col_index_2] {
                println!("found a difference for {}, {}: {} / {}", row_key, col, row_1[col_index_1], row_2[col_index_2]);
            }
        }

    }

}
<commit_msg>Fix the wrong number of lines to skip in the get_csv_row_funciton<commit_after>use std::collections::{HashSet, HashMap};
use std::env;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::path::Path;

fn print_arg_error() {
    println!("incorrect arguments passed");
}

struct CsvDescriptor<'a> {
    file_path: &'a  Path,
    delimiter:      char,
    quote:          Option<char>,
}

impl<'a> std::fmt::Display for CsvDescriptor<'a> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{} {} {:?}", self.file_path.display(), self.delimiter, self.quote)
    }
}

fn parse_args<'a>(path_arg:         &'a String,
                  delimiter_arg:    &'a String,
                  quote_arg:        &'a String) -> Result<CsvDescriptor<'a>, &'static str>
{

    let csv_file_path = Path::new(path_arg);

    let csv_delimiter = match delimiter_arg.chars().next() {
                            Some(result) => result,
                            None         => return Err("incorrect delimiter"),
                        };

    let csv_quote     = quote_arg.chars().next();

    Ok(CsvDescriptor {file_path: &csv_file_path, delimiter: csv_delimiter, quote: csv_quote})
}

fn get_csv_cols(csv_desc: &CsvDescriptor) -> Result<Vec<String>, String> {

    let csv_file = match File::open(csv_desc.file_path) {
        Err(why) => panic!("couldn't open csv @ {}: {}", csv_desc.file_path.display(), why),
        Ok(file) => file,
    };

    let csv_reader = BufReader::new(csv_file);

    let mut csv_line_iter = csv_reader.lines();

    let csv_header: String = match csv_line_iter.next() {
        Some(result) => match result {
                            Err(why) => return Err(format!("error getting csv header: {}", why)),
                            Ok(header) => header,
                        },
        None         => return Err("csv header reading failed".to_string()),
    };

    let csv_cols: Vec<String> = {
        let cols_iter = csv_header.split(csv_desc.delimiter);
        match csv_desc.quote {
            Some(q) => cols_iter.map(|s| {s.trim_matches(q).to_string()}).collect(),
            None    => cols_iter.map(|s| {s.to_string()}).collect(),
        }
    };

    Ok(csv_cols)
}

fn build_index(csv_desc: &CsvDescriptor) -> Result<HashMap<String, usize>, String> {
    // TODO it would probably be better to keep a File in the csv descriptor instead of a Path
    let mut csv_index = HashMap::new();
    let csv_file = match File::open(csv_desc.file_path) {
        Err(why) => panic!("couldn't open csv @ {}: {}", csv_desc.file_path.display(), why),
        Ok(file) => file,
    };

    let csv_reader = BufReader::new(csv_file);

    let mut csv_line_iter = csv_reader.lines().skip(1);

    let mut line_index = 0;
    loop {

        let csv_row: String = match csv_line_iter.next() {
            Some(result) => match result {
                                Err(why) => return Err(format!("error getting csv row: {}", why)),
                                Ok(header) => header,
                            },
            None         => break,
        };

        let csv_cols: Vec<String> = {
            let cols_iter = csv_row.split(csv_desc.delimiter);
            match csv_desc.quote {
                Some(q) => cols_iter.map(|s| {s.trim_matches(q).to_string()}).collect(),
                None    => cols_iter.map(|s| {s.to_string()}).collect(),
            }
        };

        // TODO: check if all lines have the same number of columns
        let key = format!("{}{}", csv_cols[0], csv_cols[1]);
        csv_index.insert(key, line_index);

        line_index += 1;
    }

    Ok(csv_index)
}

fn get_csv_row(csv_desc: &CsvDescriptor, line_num: usize) -> Result<Vec<String>, String> {

    let csv_file = match File::open(csv_desc.file_path) {
        Err(why) => panic!("couldn't open csv @ {}: {}", csv_desc.file_path.display(), why),
        Ok(file) => file,
    };

    let csv_reader = BufReader::new(csv_file);

    let mut csv_line_iter = csv_reader.lines().skip(line_num + 1);

    let csv_row: String = match csv_line_iter.next() {
        Some(result) => match result {
                            Err(why) => return Err(format!("error getting csv row: {}", why)),
                            Ok(row) => row,
                        },
        None         => return Err("csv row reading failed".to_string()),
    };

    let result: Vec<String> = {
        let cols_iter = csv_row.split(csv_desc.delimiter);
        match csv_desc.quote {
            Some(q) => cols_iter.map(|s| {s.trim_matches(q).to_string()}).collect(),
            None    => cols_iter.map(|s| {s.to_string()}).collect(),
        }
    };

    Ok(result)
}

fn main() {

/*

1. Parse arguments
2. Open CSV files
3. Get columns (cols_N)
4. Get intersection of those two sets of columns(cols_to_compare)
5. Create {column name : column index in cols_N} dicts
6. Create {CSV_col_value : CSV row index in file} dicts, where CSV_col_value is a unique key made of the value of several CSV columns.
   For example, {Alex38 : 76}. In this example a name and age form a unique key for the 76th CSV row.
7. Get intersection of key sets of dicts from step 6 (row_keys_to_compare)
8. Loop through row_keys_to_compare, use dicts from step 6 to get line numbers for CSV files
    8.1 Loop through cols_to_compare, use dicts from step 5 to extract column values from CSV rows(step 8)
    8.2 Compare values

Input parameters: CSV paths, delimiters, quotes

For example, ./main file_1.csv "," "'" file_2.csv " " ""

*/

    /*** 1 ***/
    let args: Vec<String> = env::args().collect();
    if args.len() != 7 {
        print_arg_error();
        return;
    };

    let csv_desc_1: CsvDescriptor = match parse_args(&args[1], &args[2], &args[3]) {
        Err(why)    => panic!("error parsing arguments for CSV #1: {}", why),
        Ok(result)  => result,
    };

    let csv_desc_2: CsvDescriptor = match parse_args(&args[4], &args[5], &args[6]) {
        Err(why)    => panic!("error parsing arguments for CSV #2: {}", why),
        Ok(result)  => result,
    };

    /*** 2&3 ***/
    let csv_cols_1: Vec<String> = match get_csv_cols(&csv_desc_1) {
        Err(why) => panic!("couldn't get columns: {}", why),
        Ok(cols) => cols,
    };

    let csv_cols_2: Vec<String> = match get_csv_cols(&csv_desc_2) {
        Err(why) => panic!("couldn't get columns: {}", why),
        Ok(cols) => cols,
    };

    /*** 5 ***/
    let mut csv_col_index_1 = HashMap::new();
    for i in 0..csv_cols_1.len() {
        let key = csv_cols_1[i].clone();
        if csv_col_index_1.contains_key(&key) {
            panic!("duplicate column found in CSV #1: {}", key);
        };
        csv_col_index_1.insert(key, i);
    }
    println!("{:?}", csv_col_index_1);

    let mut csv_col_index_2 = HashMap::new();
    for i in 0..csv_cols_2.len() {
        let key = csv_cols_2[i].clone();
        if csv_col_index_2.contains_key(&key) {
            panic!("duplicate column found in CSV #1: {}", key);
        };
        csv_col_index_2.insert(key, i);
    }
    println!("{:?}", csv_col_index_2);

    /*** 4 ***/
    let mut cols_to_compare = HashSet::new();
    for col_1 in csv_col_index_1.keys() {
        if csv_col_index_2.contains_key(col_1) {
            cols_to_compare.insert(col_1);
        };
    }
    println!("{:?}", cols_to_compare);

    /*** 6 ***/
    // let's assume that the unique key is (col_0 + col_1)
    let csv_index_1 = match build_index(&csv_desc_1) {
        Err(why)  => panic!("failed building index #1: {}", why),
        Ok(index) => index,
    };

    let csv_index_2 = match build_index(&csv_desc_2) {
        Err(why)  => panic!("failed building index #2: {}", why),
        Ok(index) => index,
    };

    /*** 7 ***/
    let mut row_keys_to_compare = HashSet::new();
    for key_1 in csv_index_1.keys() {
        if csv_index_2.contains_key(key_1) {
            row_keys_to_compare.insert(key_1);
        };
    }
    println!("{:?}", row_keys_to_compare);

    /*** 8 ***/
    for row_key in row_keys_to_compare {

        let index_1 = *csv_index_1.get(row_key).unwrap(); // TODO: handle me
        let index_2 = *csv_index_2.get(row_key).unwrap();

        let row_1 = get_csv_row(&csv_desc_1, index_1).unwrap(); // TODO: handle me
        let row_2 = get_csv_row(&csv_desc_2, index_2).unwrap();

        println!("comparing {}:", row_key);
        println!("line #1: {:?}", row_1);
        println!("line #2: {:?}", row_2);

        for col in &cols_to_compare {

            let col_index_1 = *csv_col_index_1.get(*col).unwrap(); // TODO: handle me
            let col_index_2 = *csv_col_index_2.get(*col).unwrap();

            println!("column {}, index_1={}, index_2={}", col, col_index_1, col_index_2);

            if row_1[col_index_1] != row_2[col_index_2] {
                println!("found a difference for {}, {}: {} / {}", row_key, col, row_1[col_index_1], row_2[col_index_2]);
            }
        }

    }

}
<|endoftext|>


<commit_before>#![feature(advanced_slice_patterns, slice_patterns)]

extern crate git_together;

use std::env;
use std::process::Command;
use git_together::GitTogether;
use git_together::config::GitConfig;

fn main() {
  let config = GitConfig { namespace: "git-together".into() };
  let gt = GitTogether { config: config };

  let all_args: Vec<_> = env::args().skip(1).collect();
  let args: Vec<&str> = all_args.iter().map(String::as_ref).collect();

  match &args[..] {
    &["with", ref inits..] => {
      gt.set_authors(inits).unwrap();
    }
    &[sub_cmd, ref rest..] if sub_cmd == "commit" => {
      let mut git_cmd = Command::new("git");
      let cmd = git_cmd.arg(sub_cmd).args(rest);
      let signoff = gt.add_signoff(cmd).unwrap();
      signoff.status().unwrap();
    }
    x => {
      println!("{:?}", x);
    }
  }
}
<commit_msg>pass through other subcommands to git<commit_after>#![feature(advanced_slice_patterns, slice_patterns)]

extern crate git_together;

use std::env;
use std::process::Command;
use git_together::GitTogether;
use git_together::config::GitConfig;

fn main() {
  let config = GitConfig { namespace: "git-together".into() };
  let gt = GitTogether { config: config };

  let all_args: Vec<_> = env::args().skip(1).collect();
  let args: Vec<&str> = all_args.iter().map(String::as_ref).collect();

  match &args[..] {
    &["with", ref inits..] => {
      gt.set_authors(inits).unwrap();
    }
    &[sub_cmd, ref rest..] if sub_cmd == "commit" => {
      let mut git_cmd = Command::new("git");
      let cmd = git_cmd.arg(sub_cmd).args(rest);
      let signoff = gt.add_signoff(cmd).unwrap();
      signoff.status().unwrap();
    }
    args => {
      Command::new("git").args(args).status().unwrap();
    }
  }
}
<|endoftext|>


<commit_before>extern crate app_dirs;
#[macro_use]
extern crate clap;
//extern crate indicatif;
extern crate num_cpus;
extern crate term_painter;
extern crate threadpool;

extern crate gitlib;
extern crate util;

use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::mpsc::{channel, Receiver};

use app_dirs::{AppInfo, AppDataType};
//use indicatif::{ProgressBar, ProgressStyle};
use term_painter::Color::{BrightCyan, BrightYellow};
use term_painter::ToStyle;
use threadpool::ThreadPool;

use gitlib::{GitError, GitRepo};
use util::{GitRepositories, Manifest};

mod cli;
mod status;

const THREAD_SIGNAL: &str = "Could not signal main thread";

#[derive(Debug, Clone)]
enum RunOption {
    Checkout(String),
    Manifest(ManifestOption),
    Reset,
    Status,
}

#[derive(Debug, Clone)]
enum ManifestOption {
    Clean,
    Preview,
    Update,
}

fn main() {
    let working_dir = env::current_dir().expect("Could not get working directory");
    let matches = cli::build_cli().get_matches();

    let option = match matches.subcommand_name() {
        Some(cli::CMD_CHECKOUT) => {
            let branch_match = matches.subcommand_matches(cli::CMD_CHECKOUT).unwrap();
            let branch = value_t!(branch_match, cli::BRANCH, String).unwrap();
            RunOption::Checkout(branch)
        }
        Some(cli::CMD_MANIFEST) => {
            let matches = matches.subcommand_matches(cli::CMD_MANIFEST).unwrap();

            match matches.subcommand_name() {
                Some(cli::CMD_CLEAN) => RunOption::Manifest(ManifestOption::Clean),
                Some(cli::CMD_UPDATE) => RunOption::Manifest(ManifestOption::Update),
                _ => RunOption::Manifest(ManifestOption::Preview),
            }
        }
        Some(cli::CMD_COMPLETIONS) => {
            if let Some(ref matches) = matches.subcommand_matches(cli::CMD_COMPLETIONS) {
                let shell = value_t!(matches, cli::SHELL, clap::Shell).unwrap();
                cli::build_cli().gen_completions_to(cli::APP_NAME, shell, &mut std::io::stdout());
            }

            return;
        }
        Some(cli::CMD_RESET) => RunOption::Reset,

        // By default, just show status.
        _ => RunOption::Status,
    };

    process(option, &working_dir);
}

fn process(option: RunOption, path: &Path) {
    let manifest_path = build_manifest_path();
    let mut manifest = Manifest::open(&manifest_path, &path);

    if let RunOption::Manifest(ref m) = option {
        match *m {
            ManifestOption::Clean => manifest_clean(&manifest_path),
            ManifestOption::Preview => manifest_preview(path),
            ManifestOption::Update => manifest_update(path, &mut manifest),
        }

        return;
    }

    let repos = match manifest.is_empty() {
        true => GitRepositories::new(path),
        false => GitRepositories::from_manifest(&manifest),
    };

    let pool = {
        let thread_count = num_cpus::get();
        ThreadPool::new(thread_count)
    };

    match option {
        RunOption::Reset => {
            let rx = reset(repos, &pool);

            while let Ok((path, head)) = rx.recv() {
                let branch = BrightCyan.paint(head);
                let l_brace = BrightYellow.paint("[");
                let r_brace = BrightYellow.paint("]");

                println!("  {}{}{}  {}", l_brace, branch, r_brace, path.display());
            }
        }
        RunOption::Status => status::process_status(repos, &pool),
        _ => panic!("Unhandled run option"),
    }

    pool.join();
}

fn build_manifest_path() -> PathBuf {
    const APP_INFO: AppInfo = AppInfo {
        name: "git-plz",
        author: "devnought",
    };

    let root = app_dirs::get_app_root(AppDataType::UserCache, &APP_INFO)
        .expect("Could not locate app settings directory");
    let mut path = PathBuf::from(root);
    path.push("manifest.json");

    path
}

fn manifest_update<P>(path: P, manifest: &mut Manifest)
    where P: AsRef<Path>
{
    let repos = GitRepositories::new(path);

    manifest.add_repositories(repos);

    println!("{:#?}", &manifest);
}

fn manifest_preview<P>(path: P)
    where P: AsRef<Path>
{
    let repos = GitRepositories::new(path);

    for repo in repos {
        println!("{}", repo.path().display());
    }
}

fn manifest_clean<P>(manifest_path: P)
    where P: AsRef<Path>
{
    let manifest_path = manifest_path.as_ref();
    println!("Attempting to delete: {}", manifest_path.display());

    if manifest_path.exists() {
        fs::remove_file(manifest_path).expect("Could not delete manifest");
    }
}

fn checkout(repo: &GitRepo, branch: &str) -> Result<(), GitError> {
    repo.checkout(branch)?;

    println!("{}", repo.path().display());
    println!("    {}", BrightCyan.paint(branch));

    Ok(())
}

fn reset(repos: GitRepositories, pool: &ThreadPool) -> Receiver<(PathBuf, String)> {
    let (tx, rx) = channel();

    for repo in repos {
        let tx = tx.clone();

        pool.execute(move || {
            match repo.statuses() {
                Ok(s) => {
                    if s.len() == 0 {
                        return;
                    }
                }
                _ => (),
            }

            match repo.remove_untracked() {
                Err(_) => return,
                _ => (),
            }

            let head = match repo.reset() {
                Ok(r) => r,
                _ => return,
            };

            let tuple = (repo.path().to_path_buf(), head.name().to_string());
            tx.send(tuple).expect(THREAD_SIGNAL);
        });
    }

    rx
}
<commit_msg>Removed unnecessary join<commit_after>extern crate app_dirs;
#[macro_use]
extern crate clap;
//extern crate indicatif;
extern crate num_cpus;
extern crate term_painter;
extern crate threadpool;

extern crate gitlib;
extern crate util;

use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::sync::mpsc::{channel, Receiver};

use app_dirs::{AppInfo, AppDataType};
//use indicatif::{ProgressBar, ProgressStyle};
use term_painter::Color::{BrightCyan, BrightYellow};
use term_painter::ToStyle;
use threadpool::ThreadPool;

use gitlib::{GitError, GitRepo};
use util::{GitRepositories, Manifest};

mod cli;
mod status;

const THREAD_SIGNAL: &str = "Could not signal main thread";

#[derive(Debug, Clone)]
enum RunOption {
    Checkout(String),
    Manifest(ManifestOption),
    Reset,
    Status,
}

#[derive(Debug, Clone)]
enum ManifestOption {
    Clean,
    Preview,
    Update,
}

fn main() {
    let working_dir = env::current_dir().expect("Could not get working directory");
    let matches = cli::build_cli().get_matches();

    let option = match matches.subcommand_name() {
        Some(cli::CMD_CHECKOUT) => {
            let branch_match = matches.subcommand_matches(cli::CMD_CHECKOUT).unwrap();
            let branch = value_t!(branch_match, cli::BRANCH, String).unwrap();
            RunOption::Checkout(branch)
        }
        Some(cli::CMD_MANIFEST) => {
            let matches = matches.subcommand_matches(cli::CMD_MANIFEST).unwrap();

            match matches.subcommand_name() {
                Some(cli::CMD_CLEAN) => RunOption::Manifest(ManifestOption::Clean),
                Some(cli::CMD_UPDATE) => RunOption::Manifest(ManifestOption::Update),
                _ => RunOption::Manifest(ManifestOption::Preview),
            }
        }
        Some(cli::CMD_COMPLETIONS) => {
            if let Some(ref matches) = matches.subcommand_matches(cli::CMD_COMPLETIONS) {
                let shell = value_t!(matches, cli::SHELL, clap::Shell).unwrap();
                cli::build_cli().gen_completions_to(cli::APP_NAME, shell, &mut std::io::stdout());
            }

            return;
        }
        Some(cli::CMD_RESET) => RunOption::Reset,

        // By default, just show status.
        _ => RunOption::Status,
    };

    process(option, &working_dir);
}

fn process(option: RunOption, path: &Path) {
    let manifest_path = build_manifest_path();
    let mut manifest = Manifest::open(&manifest_path, &path);

    if let RunOption::Manifest(ref m) = option {
        match *m {
            ManifestOption::Clean => manifest_clean(&manifest_path),
            ManifestOption::Preview => manifest_preview(path),
            ManifestOption::Update => manifest_update(path, &mut manifest),
        }

        return;
    }

    let repos = match manifest.is_empty() {
        true => GitRepositories::new(path),
        false => GitRepositories::from_manifest(&manifest),
    };

    let pool = {
        let thread_count = num_cpus::get();
        ThreadPool::new(thread_count)
    };

    match option {
        RunOption::Reset => {
            let rx = reset(repos, &pool);

            while let Ok((path, head)) = rx.recv() {
                let branch = BrightCyan.paint(head);
                let l_brace = BrightYellow.paint("[");
                let r_brace = BrightYellow.paint("]");

                println!("  {}{}{}  {}", l_brace, branch, r_brace, path.display());
            }
        }
        RunOption::Status => status::process_status(repos, &pool),
        _ => panic!("Unhandled run option"),
    }
}

fn build_manifest_path() -> PathBuf {
    const APP_INFO: AppInfo = AppInfo {
        name: "git-plz",
        author: "devnought",
    };

    let root = app_dirs::get_app_root(AppDataType::UserCache, &APP_INFO)
        .expect("Could not locate app settings directory");
    let mut path = PathBuf::from(root);
    path.push("manifest.json");

    path
}

fn manifest_update<P>(path: P, manifest: &mut Manifest)
    where P: AsRef<Path>
{
    let repos = GitRepositories::new(path);

    manifest.add_repositories(repos);

    println!("{:#?}", &manifest);
}

fn manifest_preview<P>(path: P)
    where P: AsRef<Path>
{
    let repos = GitRepositories::new(path);

    for repo in repos {
        println!("{}", repo.path().display());
    }
}

fn manifest_clean<P>(manifest_path: P)
    where P: AsRef<Path>
{
    let manifest_path = manifest_path.as_ref();
    println!("Attempting to delete: {}", manifest_path.display());

    if manifest_path.exists() {
        fs::remove_file(manifest_path).expect("Could not delete manifest");
    }
}

fn checkout(repo: &GitRepo, branch: &str) -> Result<(), GitError> {
    repo.checkout(branch)?;

    println!("{}", repo.path().display());
    println!("    {}", BrightCyan.paint(branch));

    Ok(())
}

fn reset(repos: GitRepositories, pool: &ThreadPool) -> Receiver<(PathBuf, String)> {
    let (tx, rx) = channel();

    for repo in repos {
        let tx = tx.clone();

        pool.execute(move || {
            match repo.statuses() {
                Ok(s) => {
                    if s.len() == 0 {
                        return;
                    }
                }
                _ => (),
            }

            match repo.remove_untracked() {
                Err(_) => return,
                _ => (),
            }

            let head = match repo.reset() {
                Ok(r) => r,
                _ => return,
            };

            let tuple = (repo.path().to_path_buf(), head.name().to_string());
            tx.send(tuple).expect(THREAD_SIGNAL);
        });
    }

    rx
}
<|endoftext|>


<commit_before>use std::cell::Cell;
mod memory;

fn main() {
    let mut memory = memory::Memory::new();
    let mut cpu = Cpu::new(memory);

    let mut vec: [u8, ..65535] = [0 as u8, ..65535];
    vec[3] = 5;
    println!("{}", vec[3])

    while (true)
    {
        let clock_cycle = cpu.tick();
    }
}

struct Cpu {
    reg: Registers,
    mem: memory::Memory
}

impl Cpu {
    fn new(memory: memory::Memory) -> Cpu {
        return Cpu{reg: Registers::new(), mem: memory}
    }

    fn tick(&mut self) {
        let op_code = self.mem.read_byte(self.reg.pc.get());
        match memory::high_nibble(op_code) {
            0x0 => self.zero(op_code),
            _ => return
        }
    }

    fn zero(&mut self, op_code: u8) {
        let reg = &mut self.reg;
        match memory::low_nibble(op_code) {
            0x0 => nop(),
            0x1 => ld_immediate(reg.b, reg.c),
            _ => return
        }
    }
}

// Loads the memory pointed to by the next two bytes into a register
fn ld_immediate(high_byte: Cell<u8>, low_byte: Cell<u8>)
{
}

fn nop() {
    println!("nop");
}

struct Registers {
    a: Cell<u8>, b: Cell<u8>, c: Cell<u8>, d: Cell<u8>, e: Cell<u8>, f: Cell<u8>, h: Cell<u8>, l: Cell<u8>, // 8-bit registers
    pc: Cell<u16>, sp: Cell<u16>, // 16-bit registers
    m: Cell<u16>, t: Cell<u16> // clock
}

impl Registers {
    fn new() -> Registers {
        return Registers{
            a: Cell::new(0), b: Cell::new(0), c: Cell::new(0), d: Cell::new(0), e: Cell::new(0), f: Cell::new(0), h: Cell::new(0), l: Cell::new(0),
            pc: Cell::new(0), sp: Cell::new(0),
            m: Cell::new(0), t: Cell::new(0)
        }
    }
}

<commit_msg>Use 'use' syntax<commit_after>use std::cell::Cell;
use memory::Memory;
use memory::low_nibble;
use memory::high_nibble;

mod memory;

fn main() {
    let mut memory = Memory::new();
    let mut cpu = Cpu::new(memory);

    let mut vec: [u8, ..65535] = [0 as u8, ..65535];
    vec[3] = 5;
    println!("{}", vec[3])

    while (true)
    {
        let clock_cycle = cpu.tick();
    }
}

struct Cpu {
    reg: Registers,
    mem: memory::Memory
}

impl Cpu {
    fn new(memory: Memory) -> Cpu {
        return Cpu{reg: Registers::new(), mem: memory}
    }

    fn tick(&mut self) {
        let op_code = self.mem.read_byte(self.reg.pc.get());
        match high_nibble(op_code) {
            0x0 => self.zero(op_code),
            _ => return
        }
    }

    fn zero(&self, op_code: u8) {
        match low_nibble(op_code) {
            0x0 => nop(),
            0x1 => ld_immediate(self.mem, self.reg.b, self.reg.c),
            _ => return
        }
    }
}

// Loads the memory pointed to by the next two bytes into a register
fn ld_immediate(mem: Memory, high_byte: Cell<u8>, low_byte: Cell<u8>)
{
}

fn nop() {
    println!("nop");
}

struct Registers {
    a: Cell<u8>, b: Cell<u8>, c: Cell<u8>, d: Cell<u8>, e: Cell<u8>, f: Cell<u8>, h: Cell<u8>, l: Cell<u8>, // 8-bit registers
    pc: Cell<u16>, sp: Cell<u16>, // 16-bit registers
    m: Cell<u16>, t: Cell<u16> // clock
}

impl Registers {
    fn new() -> Registers {
        return Registers{
            a: Cell::new(0), b: Cell::new(0), c: Cell::new(0), d: Cell::new(0), e: Cell::new(0), f: Cell::new(0), h: Cell::new(0), l: Cell::new(0),
            pc: Cell::new(0), sp: Cell::new(0),
            m: Cell::new(0), t: Cell::new(0)
        }
    }
}

<|endoftext|>