<commit_before>extern crate piston_window;
extern crate rand;

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

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

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

    let mut mouse_position = (0.0, 0.0);
    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![];
    for _ in 0..num_candidates {
        let which_position = rand::thread_rng().gen_range(0, candidate_positions.len());
        let pos = candidate_positions.remove(which_position);
        let candidate = Candidate { coordinates: [pos.0, pos.1, 100.0, 100.0], color: [1.0, 0.0, 0.0, 1.0] };
        candidates.push(candidate);
    }

    for e in window {
        let target_color = match candidates.get(0) {
            Some(candidate) => candidate.color,
            None => break,
        };
        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);

           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>Use random colors BUT NOT RANDOM ALPHAAAAAAS<commit_after>extern crate piston_window;
extern crate rand;

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

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

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

    let mut mouse_position = (0.0, 0.0);
    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![];
    for _ 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: [
              rand::random(),
              rand::random(),
              rand::random(),
              1.0,
             ],
        });
    }

    for e in window {
        let target_color = match candidates.get(0) {
            Some(candidate) => candidate.color,
            None => break,
        };
        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);

           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>// main.rs
#![feature(plugin)]
#![plugin(docopt_macros)]

extern crate rustc_serialize;
extern crate docopt;
extern crate regex;

use std::fmt::{ Display, Formatter };
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::OpenOptions;
use std::io::BufWriter;
use std::path::Path;
// https://github.com/docopt/docopt.rs
use docopt::Docopt;

// https://doc.rust-lang.org/regex/regex/index.html
use regex::Regex;

docopt!(Args derive Debug, "
Alexey Mekhanoshin

Usage:
	rus_fritz -e <engfile>  -r <rusfile> ( -o <outfile> | --stdout )
	rus_fritz (-h | --help)
	rus_fritz --version
Options:
  -h --help		Show this screen.
  --version		Show version.
");

struct EnglishName {
    name: String,
    opis: String,
}

struct RussianName {
    name: String,
    opis: String,
    using: bool,
}

impl EnglishName {
    fn new<S: Into<String>>(name: S, opis: S) -> EnglishName {
        EnglishName {
            name: name.into(),
            opis: opis.into(),
        }
    }
}

impl RussianName {
    fn new<S: Into<String>>(name: S, opis: S) -> RussianName {
        RussianName {
            name: name.into(),
            opis: opis.into(),
            using: false,
        }
    }
}

impl std::fmt::Display for EnglishName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        write!(f, "Display Eng: {},\t\t\t{}", self.name, self.opis)
    }
}

impl std::fmt::Display for RussianName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        write!(f, "Display Rus: {},\t\t\t{}", self.name, self.opis)
    }
}

fn open_eng_file(engvec: &mut Vec<EnglishName>, file_name: &String) {
    let path = Path::new(file_name);
    let display = path.display();
    let file = match File::open(path) {
        Ok(f) => f,
        Err(why) => panic!("Not open file {}: {}", display, Error::description(&why) ),
    };
    let re = Regex::new(r"(.*)(,)(.*)(\x22.*\x22)").unwrap();
    for line in BufReader::new(file).lines() {
        let s = line.unwrap();
        for cap in re.captures_iter(&s) {
            let ubs = EnglishName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
            engvec.push(ubs);
    }
    }
}

fn open_rus_file(rusvec: &mut Vec<RussianName>, file_name: &String) {
    let path = Path::new(file_name);
    let display = path.display();
    let file = match File::open(path) {
        Ok(f) => f,
        Err(why) => panic!("Not open file: {}: {}", display, Error::description(&why) ),
    };
    let re = Regex::new(r"(.*)(,)(.*)(\x22.*\x22)").unwrap();
    for line in BufReader::new(file).lines() {
        let s = line.unwrap();
        for cap in re.captures_iter(&s) {
            let ubs = RussianName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
            rusvec.push(ubs);
        }
    }
}

fn open_any_file(file_name: &String) -> BufReader<File> {
    let path = Path::new(file_name);
    let display = path.display();
    let file = match File::open(path) {
        Ok(f) => f,
        Err(why) => panic!("Not open file {}: {}", display, Error::description(&why) ),
    };
    let reader = BufReader::new(file);
    return reader;
}

fn create_out_file(file_name: &String) -> BufWriter<File> {
    let path = Path::new(file_name);
    let display = path.display();
    let mut options = OpenOptions::new();
    let file = match options.create(true).write(true).open(path) {
	    Ok(file) => file,
	    Err(why) => panic!("Not create/open file {}: {}", display, Error::description(&why)),
	};
    let writer = BufWriter::new(file);
    return writer;
}

fn main() {

    let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
    if args.flag_stdout {
        println!("{:?}", args);
        if args.flag_h { println!("Print Help coming soon ..." ); return; }
        if args.flag_version { println!("Print Version coming soon ..." ); return; }
    }

    let mut engvec: Vec<EnglishName> = Vec::new();
    let mut rusvec: Vec<RussianName> = Vec::new();
/*
    open_eng_file(&mut engvec, &args.arg_engfile.to_string());
    assert!( !engvec.is_empty() );
    open_rus_file(&mut rusvec, &args.arg_rusfile.to_string());
    assert!( !rusvec.is_empty() );
*/
    let re = Regex::new(r"(.*)(,)(.*)(\x22.*\x22)").unwrap();
    // Create English Vector
    for line in open_any_file(&args.arg_engfile.to_string()).lines() {
        let s = line.unwrap();
        for cap in re.captures_iter(&s) {
            let ubs = EnglishName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
            engvec.push(ubs);
        }
    }
    assert!( !engvec.is_empty() );
    // Create Russian Vector
    for line in open_any_file(&args.arg_rusfile.to_string()).lines() {
        let s = line.unwrap();
        for cap in re.captures_iter(&s) {
            let ubs = RussianName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
            rusvec.push(ubs);
        }
    }
    assert!( !rusvec.is_empty() );

	//  Подготовка закончилась, начинаем работу.

    if args.flag_stdout {
        println!("/*\n\tRecreated by RusFritz project\n*/");
    } else {
		// Write to file
    }

    let mut i=0;
    let mut found = false;
    let mut outstr = String::new();

    for e in &mut engvec {
        i = i+1;
        for r in &mut rusvec {
            if e.name == r.name {
                e.opis = r.opis.clone();
                found = true;
                r.using = true;
                if args.flag_stdout {
                    println!("{},\t\t{};", r.name, r.opis);
                } else {
                    let s = String::from( format!("{},\t\t{};\n", r.name, r.opis) );
                    outstr.push_str(&s);
                }
            }
        }
        if !found {
            //println!("ERR: {} - не найдено соответствие", e.name );
            if args.flag_stdout {
                println!("{},\t\t{};",e.name, e.opis);
            } else {
                // Wite output to file
            }
        }
        found = false;
    }
    // Print if not using from Russian Names
    println!("------ Not using Found from Russian File --------");
    for r in rusvec {
        if r.using == false {
            println!("{},\t\t{}",r.name,r.opis);
        }
    }

    // File write, if needed
    if args.flag_stdout == false {
        let mut wr = create_out_file(&args.arg_outfile.to_string());
        if outstr.len() > 0 {
            match wr.write_all(&outstr.as_bytes()) {
                Err(why) => {
                    panic!("couldn't write to{}: {}",
                        &args.arg_outfile.to_string(),
                        Error::description(&why))
                },
                Ok(_) => println!("Good write file"),
            };
            wr.flush();
        }
    }
    //println!("Обработано {} строк из {}",i, engvec.len());
    //let writer = std::io::file_writer(&Path(std::os::args()[2]), [io::Append, io::Create]).unwrap();
}
<commit_msg>Clean output file<commit_after>// main.rs
#![feature(plugin)]
#![plugin(docopt_macros)]

extern crate rustc_serialize;
extern crate docopt;
extern crate regex;

use std::fmt::{ Display, Formatter };
use std::error::Error;
use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::fs::OpenOptions;
use std::io::BufWriter;
use std::path::Path;
// https://github.com/docopt/docopt.rs
use docopt::Docopt;

// https://doc.rust-lang.org/regex/regex/index.html
use regex::Regex;

docopt!(Args derive Debug, "
Alexey Mekhanoshin

Usage:
	rus_fritz -e <engfile>  -r <rusfile> ( -o <outfile> | --stdout )
	rus_fritz (-h | --help)
	rus_fritz --version
Options:
  -h --help		Show this screen.
  --version		Show version.
");

struct EnglishName {
    name: String,
    opis: String,
}

struct RussianName {
    name: String,
    opis: String,
    using: bool,
}

impl EnglishName {
    fn new<S: Into<String>>(name: S, opis: S) -> EnglishName {
        EnglishName {
            name: name.into(),
            opis: opis.into(),
        }
    }
}

impl RussianName {
    fn new<S: Into<String>>(name: S, opis: S) -> RussianName {
        RussianName {
            name: name.into(),
            opis: opis.into(),
            using: false,
        }
    }
}

impl std::fmt::Display for EnglishName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        write!(f, "Display Eng: {},\t\t\t{}", self.name, self.opis)
    }
}

impl std::fmt::Display for RussianName {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        write!(f, "Display Rus: {},\t\t\t{}", self.name, self.opis)
    }
}

fn open_any_file(file_name: &String) -> BufReader<File> {
    let path = Path::new(file_name);
    let display = path.display();
    let file = match File::open(path) {
        Ok(f) => f,
        Err(why) => panic!("Not open file {}: {}", display, Error::description(&why) ),
    };
    let reader = BufReader::new(file);
    return reader;
}

fn create_out_file(file_name: &String) -> BufWriter<File> {
    let path = Path::new(file_name);
    let display = path.display();
    let mut options = OpenOptions::new();
    let file = match options.create(true).write(true).truncate(true).open(path) {
	    Ok(file) => file,
	    Err(why) => panic!("Not create/open file {}: {}", display, Error::description(&why)),
	};
    let writer = BufWriter::new(file);
    return writer;
}

fn main() {

    let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
    if args.flag_stdout {
        println!("{:?}", args);
        if args.flag_h { println!("Print Help coming soon ..." ); return; }
        if args.flag_version { println!("Print Version coming soon ..." ); return; }
    }

    let mut engvec: Vec<EnglishName> = Vec::new();
    let mut rusvec: Vec<RussianName> = Vec::new();
/*
    open_eng_file(&mut engvec, &args.arg_engfile.to_string());
    assert!( !engvec.is_empty() );
    open_rus_file(&mut rusvec, &args.arg_rusfile.to_string());
    assert!( !rusvec.is_empty() );
*/
    let re = Regex::new(r"(.*)(,)(.*)(\x22.*\x22)").unwrap();
    // Create English Vector
    for line in open_any_file(&args.arg_engfile.to_string()).lines() {
        let s = line.unwrap();
        for cap in re.captures_iter(&s) {
            let ubs = EnglishName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
            engvec.push(ubs);
        }
    }
    assert!( !engvec.is_empty() );
    // Create Russian Vector
    for line in open_any_file(&args.arg_rusfile.to_string()).lines() {
        let s = line.unwrap();
        for cap in re.captures_iter(&s) {
            let ubs = RussianName::new( cap.at(1).unwrap(), cap.at(4).unwrap() );
            rusvec.push(ubs);
        }
    }
    assert!( !rusvec.is_empty() );

	//  Подготовка закончилась, начинаем работу.

    if args.flag_stdout {
        println!("/*\n\tRecreated by RusFritz project\n*/");
    } else {
		// Write to file
    }

    let mut i=0;
    let mut found = false;
    let mut outstr = String::new();

    for e in &mut engvec {
        i = i+1;
        for r in &mut rusvec {
            if e.name == r.name {
                e.opis = r.opis.clone();
                found = true;
                r.using = true;
                if args.flag_stdout {
                    println!("{},\t\t{};", r.name, r.opis);
                } else {
                    let s = String::from( format!("{},\t\t{};\n", r.name, r.opis) );
                    outstr.push_str(&s);
                }
            }
        }
        if !found {
            //println!("ERR: {} - не найдено соответствие", e.name );
            if args.flag_stdout {
                println!("{},\t\t{};",e.name, e.opis);
            } else {
                // Wite output to file
            }
        }
        found = false;
    }
    // Print if not using from Russian Names
    println!("------ Not using Found from Russian File --------");
    for r in rusvec {
        if r.using == false {
            println!("{},\t\t{}",r.name,r.opis);
        }
    }

    // File write, if needed
    if args.flag_stdout == false {
        let mut wr = create_out_file(&args.arg_outfile.to_string());
        if outstr.len() > 0 {
            match wr.write_all(&outstr.as_bytes()) {
                Err(why) => {
                    panic!("couldn't write to{}: {}",
                        &args.arg_outfile.to_string(),
                        Error::description(&why))
                },
                Ok(_) => println!("Good write file"),
            };
            wr.flush();
        }
    }
    //println!("Обработано {} строк из {}",i, engvec.len());
    //let writer = std::io::file_writer(&Path(std::os::args()[2]), [io::Append, io::Create]).unwrap();
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#![feature(result_expect)]

extern crate melvin;

use std::path;
use std::io::Result;
use std::io::Error;
use std::io::ErrorKind::Other;
use std::str::FromStr;
use std::path::Path;

use melvin::parser;
use melvin::parser::LvmTextMap;
use melvin::parser::TextMapOps;
use melvin::lvmetad;
use melvin::pvlabel;
use melvin::pvlabel::PvHeader;
use melvin::pv::Device;
use melvin::dm;

fn print_pvheaders() -> Result<()> {
    let dirs = vec![path::Path::new("/dev")];

    for path in try!(pvlabel::scan_for_pvs(&dirs)) {
        let pvheader = try!(PvHeader::find_in_dev(&path));
        println!("pvheader {:#?}", pvheader);
    }

    Ok(())
}

fn get_first_vg_meta() -> Result<(String, LvmTextMap)> {
    let dirs = vec![path::Path::new("/dev")];

    for path in try!(pvlabel::scan_for_pvs(&dirs)) {
        let pvheader = try!(PvHeader::find_in_dev(&path));
        println!("pvheader {:#?}", pvheader);
        let map = try!(pvheader.read_metadata());

        for (key, value) in map {
            match value {
                parser::Entry::TextMap(x) => return Ok((key, *x)),
                _ => {}
            }
        }
    }

    Err(Error::new(Other, "dude"))
}

fn get_conf() -> Result<LvmTextMap> {
    use std::fs;
    use std::io::Read;

    let mut f = try!(fs::File::open("/etc/lvm/lvm.conf"));

    let mut buf = Vec::new();
    try!(f.read_to_end(&mut buf));

    parser::buf_to_textmap(&buf)
}

fn main() {
    println!("{:?}", PvHeader::initialize(Path::new("/dev/vdc1")));
    print_pvheaders();
    // let (name, map) = get_first_vg_meta().unwrap();
    // let vg = parser::vg_from_textmap(&name, &map).expect("didn't get vg!");
    // println!("heyo {} {}", vg.extents(), vg.extent_size);
    // println!("output {:?}", vg);

    // {
    //     let dm = dm::DM::new(&vg).unwrap();
    //     match dm.list_devices() {
    //         Ok(x) => println!("{:?}", x),
    //         Err(x) => println!("error {}", x),
    //     }
    // }

    // let mut vgs = lvmetad::vgs_from_lvmetad().expect("could not get vgs from lvmetad");
    // let mut vg = vgs.pop().expect("no vgs in vgs");

    // vg.new_linear_lv("grover125", 100);
    // vg.new_linear_lv("grover126", 200);

    // for (lvname, lv) in &vg.lvs {
    //     println!("lv2 {:?}", lv);
    // }

    // let tm = get_conf().expect("could not read lvm.conf");
    // let locking_type = tm.textmap_from_textmap("global")
    //     .and_then(|g| g.i64_from_textmap("locking_type")).unwrap();

    // println!("locking_type = {}", locking_type);

    // let vgtm = vg.into();
    // let s = parser::textmap_to_buf(&vgtm);
}
<commit_msg>Add comment to describe better what main::get_first_vg_meta() is doing<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#![feature(result_expect)]

extern crate melvin;

use std::path;
use std::io::Result;
use std::io::Error;
use std::io::ErrorKind::Other;
use std::str::FromStr;
use std::path::Path;

use melvin::parser;
use melvin::parser::LvmTextMap;
use melvin::parser::TextMapOps;
use melvin::lvmetad;
use melvin::pvlabel;
use melvin::pvlabel::PvHeader;
use melvin::pv::Device;
use melvin::dm;

fn print_pvheaders() -> Result<()> {
    let dirs = vec![path::Path::new("/dev")];

    for path in try!(pvlabel::scan_for_pvs(&dirs)) {
        let pvheader = try!(PvHeader::find_in_dev(&path));
        println!("pvheader {:#?}", pvheader);
    }

    Ok(())
}

fn get_first_vg_meta() -> Result<(String, LvmTextMap)> {
    let dirs = vec![path::Path::new("/dev")];

    for path in try!(pvlabel::scan_for_pvs(&dirs)) {
        let pvheader = try!(PvHeader::find_in_dev(&path));
        println!("pvheader {:#?}", pvheader);
        let map = try!(pvheader.read_metadata());

        // Find the textmap for the vg, among all the other stuff.
        // (It's the only textmap.)
        for (key, value) in map {
            match value {
                parser::Entry::TextMap(x) => return Ok((key, *x)),
                _ => {}
            }
        }
    }

    Err(Error::new(Other, "dude"))
}

fn get_conf() -> Result<LvmTextMap> {
    use std::fs;
    use std::io::Read;

    let mut f = try!(fs::File::open("/etc/lvm/lvm.conf"));

    let mut buf = Vec::new();
    try!(f.read_to_end(&mut buf));

    parser::buf_to_textmap(&buf)
}

fn main() {
    println!("{:?}", PvHeader::initialize(Path::new("/dev/vdc1")));
    print_pvheaders();
    // let (name, map) = get_first_vg_meta().unwrap();
    // let vg = parser::vg_from_textmap(&name, &map).expect("didn't get vg!");
    // println!("heyo {} {}", vg.extents(), vg.extent_size);
    // println!("output {:?}", vg);

    // {
    //     let dm = dm::DM::new(&vg).unwrap();
    //     match dm.list_devices() {
    //         Ok(x) => println!("{:?}", x),
    //         Err(x) => println!("error {}", x),
    //     }
    // }

    // let mut vgs = lvmetad::vgs_from_lvmetad().expect("could not get vgs from lvmetad");
    // let mut vg = vgs.pop().expect("no vgs in vgs");

    // vg.new_linear_lv("grover125", 100);
    // vg.new_linear_lv("grover126", 200);

    // for (lvname, lv) in &vg.lvs {
    //     println!("lv2 {:?}", lv);
    // }

    // let tm = get_conf().expect("could not read lvm.conf");
    // let locking_type = tm.textmap_from_textmap("global")
    //     .and_then(|g| g.i64_from_textmap("locking_type")).unwrap();

    // println!("locking_type = {}", locking_type);

    // let vgtm = vg.into();
    // let s = parser::textmap_to_buf(&vgtm);
}
<|endoftext|>


<commit_before>use std::io;
use std::io::prelude::*;
use std::net::TcpStream;
use std::fs::File;
use std::env;
use std::process;

extern crate chrono;
use chrono::*;

extern crate aggregated_stats;

#[macro_use]
extern crate clap;

extern crate env_logger;
#[macro_use]
extern crate log;

extern crate prometheus;
extern crate hyper;

extern crate failure;
use failure::{Error, err_msg};

mod analyzer;
mod args;
mod filter;
mod log_parser;
mod render;
mod request_response_matcher;
mod http_handler;
mod result;

fn main() {
    env_logger::init();

    let args = match args::parse_args(env::args()) {
        Ok(args) => args,
        Err(err) => {
            eprintln!("Failed to parse arguments: {}", err);
            process::exit(1);
        }
    };

    if args.prometheus_listen.is_some() {
        let binding_address = args.prometheus_listen.clone().unwrap();
        http_handler::listen_http(args, &binding_address);
    } else {
        let result = run(&args);

        let mut stream;
        let mut stdout;

        let mut renderers: Vec<Box<render::Renderer>>;
        renderers = vec![];

        if !args.quiet {
            stdout = io::stdout();
            renderers.push(Box::new(
                render::terminal::TerminalRenderer::new(&mut stdout),
            ));
        }

        if args.graphite_server.is_some() {
            stream = match TcpStream::connect((
                args.graphite_server.as_ref().unwrap().as_str(),
                args.graphite_port.unwrap(),
            )) {
                Ok(stream) => stream,
                Err(err) => {
                    eprintln!("Could not connect to the Graphite server: {}", err);
                    process::exit(1);
                }
            };

            renderers.push(Box::new(render::graphite::GraphiteRenderer::new(
                Utc::now(),
                args.graphite_prefix.clone(),
                &mut stream,
            )));
        }

        if args.influxdb_write_url.is_some() {
            renderers.push(Box::new(render::influxdb::InfluxDbRenderer::new(
                &args.influxdb_write_url.clone().unwrap(),
                args.influxdb_tags.clone(),
            )));
        }

        for mut renderer in renderers {
            renderer.render(result.clone());
        }
    }
}

fn get_input(args: &args::RequestLogAnalyzerArgs) -> Result<Box<io::Read>, Error> {
    let input: Box<io::Read> = match args.filenames[0].as_ref() {
        "-" => Box::new(io::stdin()),
        _ => Box::new(match File::open(&args.filenames[0]) {
            Ok(file) => file,
            Err(err) => {
                return Err(err_msg(format!(
                    "Failed to open file {}: {}",
                    &args.filenames[0],
                    err
                )))
            }
        }),
    };
    Ok(input)
}

fn run(args: &args::RequestLogAnalyzerArgs) -> result::RequestLogAnalyzerResult {
    let input = match get_input(&args) {
        Ok(input) => input,
        Err(err) => {
            eprintln!("{}", err);
            process::exit(1);
        }
    };

    let reader = io::BufReader::new(input);

    let mut events_iterator = reader
        .lines()
        .map(log_parser::parse_line)
        .filter(|event| event.is_ok())
        .map(|event| event.unwrap());

    let pairs_iterator = request_response_matcher::RequestResponsePairIterator::new(
        &mut events_iterator,
    ).filter(|pair| filter::matches_filter(pair, &args.conditions));

    analyzer::analyze_iterator(pairs_iterator)
}

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

    #[test]
    fn test_run() {
        let args = args::RequestLogAnalyzerArgs {
            filenames: vec![String::from("src/test/simple-1.log")],
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
            influxdb_write_url: None,
            influxdb_tags: None,
            quiet: false,
        };

        let result = run(&args);
        assert_eq!(result.count, 2);

        let timing = result.timing.unwrap();
        assert_eq!(timing.min, 7);
        assert_eq!(timing.max, 10);

        assert!(result.error.is_some());
    }

    #[test]
    fn test_get_input_file() {
        let args = args::RequestLogAnalyzerArgs {
            filenames: vec![String::from("src/test/simple-1.log")],
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
            influxdb_write_url: None,
            influxdb_tags: None,
            quiet: false,
        };

        let result = get_input(&args);
        assert!(result.is_ok());
    }

    #[test]
    fn test_get_input_non_existent_file() {
        let args = args::RequestLogAnalyzerArgs {
            filenames: vec![String::from("src/test/non-existent.log")],
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
            influxdb_write_url: None,
            influxdb_tags: None,
            quiet: false,
        };

        let result = get_input(&args);
        assert!(result.is_err());
        let error_message = format!("{}", result.err().unwrap());
        assert!(error_message.contains(
            "Failed to open file src/test/non-existent.log",
        ));
    }

    #[test]
    fn test_get_input_stdin() {
        let args = args::RequestLogAnalyzerArgs {
            filenames: vec![String::from("-")],
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
            influxdb_write_url: None,
            influxdb_tags: None,
            quiet: false,
        };

        let result = get_input(&args);
        assert!(result.is_ok());
    }

    #[test]
    fn test_run_ignore_broken_lines() {
        let args = args::RequestLogAnalyzerArgs {
            filenames: vec![String::from("src/test/broken.log")],
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
            influxdb_write_url: None,
            influxdb_tags: None,
            quiet: false,
        };

        let result = run(&args);
        assert_eq!(result.count, 1);
    }
}
<commit_msg>Support two(!) input files<commit_after>use std::io;
use std::io::prelude::*;
use std::net::TcpStream;
use std::fs::File;
use std::env;
use std::process;

extern crate chrono;
use chrono::*;

extern crate aggregated_stats;

#[macro_use]
extern crate clap;

extern crate env_logger;
#[macro_use]
extern crate log;

extern crate prometheus;
extern crate hyper;

extern crate failure;
use failure::{Error, err_msg};

mod analyzer;
mod args;
mod filter;
mod log_parser;
mod render;
mod request_response_matcher;
mod http_handler;
mod result;

fn main() {
    env_logger::init();

    let args = match args::parse_args(env::args()) {
        Ok(args) => args,
        Err(err) => {
            eprintln!("Failed to parse arguments: {}", err);
            process::exit(1);
        }
    };

    if args.prometheus_listen.is_some() {
        let binding_address = args.prometheus_listen.clone().unwrap();
        http_handler::listen_http(args, &binding_address);
    } else {
        let result = run(&args);

        let mut stream;
        let mut stdout;

        let mut renderers: Vec<Box<render::Renderer>>;
        renderers = vec![];

        if !args.quiet {
            stdout = io::stdout();
            renderers.push(Box::new(
                render::terminal::TerminalRenderer::new(&mut stdout),
            ));
        }

        if args.graphite_server.is_some() {
            stream = match TcpStream::connect((
                args.graphite_server.as_ref().unwrap().as_str(),
                args.graphite_port.unwrap(),
            )) {
                Ok(stream) => stream,
                Err(err) => {
                    eprintln!("Could not connect to the Graphite server: {}", err);
                    process::exit(1);
                }
            };

            renderers.push(Box::new(render::graphite::GraphiteRenderer::new(
                Utc::now(),
                args.graphite_prefix.clone(),
                &mut stream,
            )));
        }

        if args.influxdb_write_url.is_some() {
            renderers.push(Box::new(render::influxdb::InfluxDbRenderer::new(
                &args.influxdb_write_url.clone().unwrap(),
                args.influxdb_tags.clone(),
            )));
        }

        for mut renderer in renderers {
            renderer.render(result.clone());
        }
    }
}

fn get_input(args: &args::RequestLogAnalyzerArgs) -> Result<Box<io::Read>, Error> {
    let input: Box<io::Read> = match args.filenames[0].as_ref() {
        "-" => Box::new(io::stdin()),
        // _ => Box::new(match File::open(&args.filenames[0]) {
        //     Ok(file) => file,
        //     Err(err) => {
        //         return Err(err_msg(format!(
        //             "Failed to open file {}: {}",
        //             &args.filenames[0],
        //             err
        //         )))
        //     }
        // }),
        _ => {
            if args.filenames.len() == 1 {
                Box::new(match File::open(&args.filenames[0]) {
                    Ok(file) => file,
                    Err(err) => {
                        return Err(err_msg(format!(
                            "Failed to open file {}: {}",
                            &args.filenames[0],
                            err
                        )))
                    }
                })
            } else {
                let file1 = match File::open(&args.filenames[0]) {
                    Ok(file) => file,
                    Err(err) => {
                        return Err(err_msg(format!(
                            "Failed to open file {}: {}",
                            &args.filenames[0],
                            err
                        )))
                    }
                };
                let file2 = match File::open(&args.filenames[1]) {
                    Ok(file) => file,
                    Err(err) => {
                        return Err(err_msg(format!(
                            "Failed to open file {}: {}",
                            &args.filenames[0],
                            err
                        )))
                    }
                };
                Box::new(file1.chain(file2))
            }
        }
    };
    Ok(input)
}

fn run(args: &args::RequestLogAnalyzerArgs) -> result::RequestLogAnalyzerResult {
    let input = match get_input(&args) {
        Ok(input) => input,
        Err(err) => {
            eprintln!("{}", err);
            process::exit(1);
        }
    };

    let reader = io::BufReader::new(input);

    let mut events_iterator = reader
        .lines()
        .map(log_parser::parse_line)
        .filter(|event| event.is_ok())
        .map(|event| event.unwrap());

    let pairs_iterator = request_response_matcher::RequestResponsePairIterator::new(
        &mut events_iterator,
    ).filter(|pair| filter::matches_filter(pair, &args.conditions));

    analyzer::analyze_iterator(pairs_iterator)
}

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

    #[test]
    fn test_run() {
        let args = args::RequestLogAnalyzerArgs {
            filenames: vec![String::from("src/test/simple-1.log")],
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
            influxdb_write_url: None,
            influxdb_tags: None,
            quiet: false,
        };

        let result = run(&args);
        assert_eq!(result.count, 2);

        let timing = result.timing.unwrap();
        assert_eq!(timing.min, 7);
        assert_eq!(timing.max, 10);

        assert!(result.error.is_some());
    }

    #[test]
    fn test_get_input_file() {
        let args = args::RequestLogAnalyzerArgs {
            filenames: vec![String::from("src/test/simple-1.log")],
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
            influxdb_write_url: None,
            influxdb_tags: None,
            quiet: false,
        };

        let result = get_input(&args);
        assert!(result.is_ok());
    }

    #[test]
    fn test_get_input_non_existent_file() {
        let args = args::RequestLogAnalyzerArgs {
            filenames: vec![String::from("src/test/non-existent.log")],
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
            influxdb_write_url: None,
            influxdb_tags: None,
            quiet: false,
        };

        let result = get_input(&args);
        assert!(result.is_err());
        let error_message = format!("{}", result.err().unwrap());
        assert!(error_message.contains(
            "Failed to open file src/test/non-existent.log",
        ));
    }

    #[test]
    fn test_get_input_stdin() {
        let args = args::RequestLogAnalyzerArgs {
            filenames: vec![String::from("-")],
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
            influxdb_write_url: None,
            influxdb_tags: None,
            quiet: false,
        };

        let result = get_input(&args);
        assert!(result.is_ok());
    }

    #[test]
    fn test_run_ignore_broken_lines() {
        let args = args::RequestLogAnalyzerArgs {
            filenames: vec![String::from("src/test/broken.log")],
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
            influxdb_write_url: None,
            influxdb_tags: None,
            quiet: false,
        };

        let result = run(&args);
        assert_eq!(result.count, 1);
    }

    #[test]
    fn test_run_multiple_files() {
        let args = args::RequestLogAnalyzerArgs {
            filenames: vec![
                String::from("src/test/simple-1.log"),
                String::from("src/test/simple-2.log"),
            ],
            conditions: filter::FilterConditions {
                include_terms: None,
                exclude_terms: None,
                latest_time: None,
            },
            graphite_server: None,
            graphite_port: Some(2003),
            graphite_prefix: None,
            prometheus_listen: None,
            influxdb_write_url: None,
            influxdb_tags: None,
            quiet: false,
        };

        let result = run(&args);
        assert_eq!(result.count, 4);
    }
}
<|endoftext|>


<commit_before>extern crate txtpic_lib;
extern crate image;
extern crate clap;
use clap::{App, Arg};
use std::path::Path;
use txtpic_lib::character_set::CharacterSet;
use txtpic_lib::text_image::TextImage;

fn main() {
    let additional_help = "\
Note: the --width option attempts find a width close to the target width that preserves the \
aspect ratio of the original image. For certain images, there may be only one or two valid \
widths within a reasonable range, so the --width option may not appear to have an effect. In this \
case, try extremely high or extremely low width values to affect the output.
";
    let matches = App::new("txtpic")
                        .version(env!("CARGO_PKG_VERSION"))
                        .author("Jeremy Dormitzer <jeremy.dormitzer@gmail.com>")
                        .about("Generates text representations of images")
                        .arg(Arg::with_name("IMAGE")
                             .help("The input image")
                             .required(true)
                             .index(1))
                        .arg(Arg::with_name("width")
                             .short("w")
                             .long("width")
                             .takes_value(true)
                             .value_name("WIDTH")
                             .default_value("80")
                             .help("An approximate width value for the result")
                             .validator(|arg: String| {
                                 match arg.parse::<u32>() {
                                     Err(_) => Err("Width must be a positive number".to_string()),
                                     Ok(_) => Ok(())
                                 }
                             }))
                        .arg(Arg::with_name("char_set")
                             .short("c")
                             .long("character-set")
                             .use_delimiter(false)
                             .takes_value(true)
                             .value_name("CHARACTERS")
                             .help("An alternate character set to use"))
                        .arg(Arg::with_name("invert")
                             .short("i")
                             .long("invert")
                             .help("Invert the result to make it suitable for black text on a white background"))
                        .arg(Arg::with_name("preset")
                             .short("p")
                             .long("preset")
                             .value_name("PRESET NAME")
                             .conflicts_with("char_set")
                             .possible_values(&["small", "medium", "large"])
                             .default_value("small")
                             .help("A preset character set to use"))
                        .after_help(additional_help)
                        .get_matches();

    let img_path = matches.value_of("IMAGE").unwrap();
    let img = match image::open(Path::new(img_path)) {
        Ok(img) => img,
        Err(e) => {
            println!("Unable to read image: {}", e);
            std::process::exit(1);
        }
    };

    let mut char_set = match matches.value_of("char_set") {
        Some(chars) => CharacterSet::from(&chars),
        None => match matches.value_of("preset").unwrap() {
            "small" => CharacterSet::preset_small(),
            "medium" => CharacterSet::preset_medium(),
            "large" => CharacterSet::preset_large(),
            &_ => panic!("Unknown preset: {}", matches.value_of("preset").unwrap())
        }
    };

    if matches.is_present("invert") { char_set = char_set.invert(); };

    let width = matches.value_of("width").unwrap().parse::<u32>().unwrap();

    let txt_img = TextImage::from(img, char_set, width);
    println!("{}", txt_img);
}
<commit_msg>Do not print extra newline<commit_after>extern crate txtpic_lib;
extern crate image;
extern crate clap;
use clap::{App, Arg};
use std::path::Path;
use txtpic_lib::character_set::CharacterSet;
use txtpic_lib::text_image::TextImage;

fn main() {
    let additional_help = "\
Note: the --width option attempts find a width close to the target width that preserves the \
aspect ratio of the original image. For certain images, there may be only one or two valid \
widths within a reasonable range, so the --width option may not appear to have an effect. In this \
case, try extremely high or extremely low width values to affect the output.
";
    let matches = App::new("txtpic")
                        .version(env!("CARGO_PKG_VERSION"))
                        .author("Jeremy Dormitzer <jeremy.dormitzer@gmail.com>")
                        .about("Generates text representations of images")
                        .arg(Arg::with_name("IMAGE")
                             .help("The input image")
                             .required(true)
                             .index(1))
                        .arg(Arg::with_name("width")
                             .short("w")
                             .long("width")
                             .takes_value(true)
                             .value_name("WIDTH")
                             .default_value("80")
                             .help("An approximate width value for the result")
                             .validator(|arg: String| {
                                 match arg.parse::<u32>() {
                                     Err(_) => Err("Width must be a positive number".to_string()),
                                     Ok(_) => Ok(())
                                 }
                             }))
                        .arg(Arg::with_name("char_set")
                             .short("c")
                             .long("character-set")
                             .use_delimiter(false)
                             .takes_value(true)
                             .value_name("CHARACTERS")
                             .help("An alternate character set to use"))
                        .arg(Arg::with_name("invert")
                             .short("i")
                             .long("invert")
                             .help("Invert the result to make it suitable for black text on a white background"))
                        .arg(Arg::with_name("preset")
                             .short("p")
                             .long("preset")
                             .value_name("PRESET NAME")
                             .conflicts_with("char_set")
                             .possible_values(&["small", "medium", "large"])
                             .default_value("small")
                             .help("A preset character set to use"))
                        .after_help(additional_help)
                        .get_matches();

    let img_path = matches.value_of("IMAGE").unwrap();
    let img = match image::open(Path::new(img_path)) {
        Ok(img) => img,
        Err(e) => {
            println!("Unable to read image: {}", e);
            std::process::exit(1);
        }
    };

    let mut char_set = match matches.value_of("char_set") {
        Some(chars) => CharacterSet::from(&chars),
        None => match matches.value_of("preset").unwrap() {
            "small" => CharacterSet::preset_small(),
            "medium" => CharacterSet::preset_medium(),
            "large" => CharacterSet::preset_large(),
            &_ => panic!("Unknown preset: {}", matches.value_of("preset").unwrap())
        }
    };

    if matches.is_present("invert") { char_set = char_set.invert(); };

    let width = matches.value_of("width").unwrap().parse::<u32>().unwrap();

    let txt_img = TextImage::from(img, char_set, width);
    print!("{}", txt_img);
}
<|endoftext|>


<commit_before>extern crate docopt;
extern crate xml;

mod library;
mod parser;

use docopt::Docopt;
use library::*;

static USAGE: &'static str = "
Usage: spore -d <dir> <lib>
";

fn main() {
    let args = Docopt::new(USAGE).unwrap()
        .parse().unwrap_or_else(|e| e.exit());
    let mut library = Library::new();
    library.read_file(args.get_str("<dir>"), args.get_str("<lib>"));
    library.check_resolved();
    show(&library);
}

#[allow(dead_code)]
fn show(library: &Library) {
    for namespace in &library.namespaces {
        println!("Namespace: {}", namespace);
        let prefix = format!("{}.", namespace);
        for (ref name, ref typ) in &library.types {
            if !name.starts_with(&prefix) {
                continue;
            }
            match *typ.borrow() {
                Type::Class(ref x) => println!("\tclass {}", x.name),
                Type::Record(ref x) => println!("\trecord {}", x.name),
                Type::Union(ref x) => println!("\tunion {}", x.name),
                Type::Interface(ref x) => println!("\tinterface {}", x.name),
                Type::Callback(ref x) => println!("\trecord {}", x.name),
                Type::Bitfield(ref x) => println!("\tbitfield {}", x.name),
                Type::Enumeration(ref x) => println!("\tenumeration {}", x.name),
                _ => println!("\t{} ???", name),
            }
        }
        for (ref name, ref c) in &library.constants {
            if !name.starts_with(&prefix) {
                continue;
            }
            println!("\tconst {} = {}", c.name, c.value);
        }
        for (ref name, ref f) in &library.functions {
            if !name.starts_with(&prefix) {
                continue;
            }
            println!("\tfunction {}", f.name);
        }
    }
}
<commit_msg>Fix misprint<commit_after>extern crate docopt;
extern crate xml;

mod library;
mod parser;

use docopt::Docopt;
use library::*;

static USAGE: &'static str = "
Usage: spore -d <dir> <lib>
";

fn main() {
    let args = Docopt::new(USAGE).unwrap()
        .parse().unwrap_or_else(|e| e.exit());
    let mut library = Library::new();
    library.read_file(args.get_str("<dir>"), args.get_str("<lib>"));
    library.check_resolved();
    show(&library);
}

#[allow(dead_code)]
fn show(library: &Library) {
    for namespace in &library.namespaces {
        println!("Namespace: {}", namespace);
        let prefix = format!("{}.", namespace);
        for (ref name, ref typ) in &library.types {
            if !name.starts_with(&prefix) {
                continue;
            }
            match *typ.borrow() {
                Type::Class(ref x) => println!("\tclass {}", x.name),
                Type::Record(ref x) => println!("\trecord {}", x.name),
                Type::Union(ref x) => println!("\tunion {}", x.name),
                Type::Interface(ref x) => println!("\tinterface {}", x.name),
                Type::Callback(ref x) => println!("\tcallback {}", x.name),
                Type::Bitfield(ref x) => println!("\tbitfield {}", x.name),
                Type::Enumeration(ref x) => println!("\tenumeration {}", x.name),
                _ => println!("\t{} ???", name),
            }
        }
        for (ref name, ref c) in &library.constants {
            if !name.starts_with(&prefix) {
                continue;
            }
            println!("\tconst {} = {}", c.name, c.value);
        }
        for (ref name, ref f) in &library.functions {
            if !name.starts_with(&prefix) {
                continue;
            }
            println!("\tfunction {}", f.name);
        }
    }
}
<|endoftext|>


<commit_before>extern crate clipboard_win;
extern crate docopt;
extern crate rustc_serialize;
extern crate winapi;
extern crate user32;
extern crate kernel32;

use clipboard_win::WindowsError;
use clipboard_win::wrapper::{get_last_error, open_clipboard, close_clipboard};
use clipboard_win::clipboard_formats::CF_UNICODETEXT;
use docopt::Docopt;
use kernel32::{GlobalLock, GlobalUnlock};
use winapi::winnt::HANDLE;
use user32::GetClipboardData;
use std::io;
use std::io::Read;

const USAGE: &'static str = "
win32yank

Usage:
    win32yank -o [--lf]
    win32yank -i [--crlf]

Options:
    -o          Print clipboard contents to stdout
    -i          Set clipboard from stdin
    --lf        Replace CRLF with LF before printing to stdout
    --crlf      Replace lone LF bytes with CRLF before setting the clipboard
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_o: bool,
    flag_i: bool,
    flag_lf: bool,
    flag_crlf: bool,
}

fn from_wide_ptr(ptr: *const u16) -> String {
    use std::ffi::OsString;
    use std::os::windows::ffi::OsStringExt;

    if ptr.is_null() {
        return String::new();
    }

    unsafe {
        assert!(!ptr.is_null());
        let len = (0..std::isize::MAX).position(|i| *ptr.offset(i) == 0).unwrap();
        let slice = std::slice::from_raw_parts(ptr, len);
        OsString::from_wide(slice).to_string_lossy().into_owned()
    }
}

fn get_clipboard(replace_crlf: bool) -> Result<String, WindowsError> {
    let result: Result<String, WindowsError>;
    try!(open_clipboard());
    unsafe {
        let text_handler: HANDLE = GetClipboardData(CF_UNICODETEXT as u32);

        if text_handler.is_null() {
            result = Err(get_last_error());
        } else {
            let text_p = GlobalLock(text_handler) as *const u16;
            result = Ok(from_wide_ptr(text_p));
            GlobalUnlock(text_handler);
        }
    }
    try!(close_clipboard());

    if replace_crlf {
        result.map(|data| data.replace("\r\n", "\n"))
    } else {
        result
    }
}

fn set_clipboard(content: &str, replace_lf: bool) -> Result<(), WindowsError> {
    // clipboard_win::wrapper::set_clipboard uses CF_UNICODETEXT,
    // which is what we want

    if replace_lf {
        let chunks = content.split("\r\n")
            .map(|item| item.replace("\n", "\r\n"));
        let mut first = true;
        let mut out = String::with_capacity(content.len());
        for chunk in chunks {
            if first {
                first = false;
            } else {
                out.push_str("\r\n");
            }
            out.push_str(&chunk);
        }
        clipboard_win::set_clipboard(&out)
    } else {
        clipboard_win::set_clipboard(content)
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());

    if args.flag_o {
        let content = get_clipboard(args.flag_lf).unwrap();
        println!("{}", content);
    } else if args.flag_i {
        let mut stdin = io::stdin();
        let mut content = String::new();
        stdin.read_to_string(&mut content).unwrap();
        set_clipboard(&content, args.flag_crlf).unwrap();
    }
}

#[test]
fn test() {
    // Windows dislikes if we lock the clipboard too long
    // sleep for bit
    use std::thread::sleep;
    use std::time::Duration;
    let sleep_time = 300;

    let v = "Hello\nfrom\nwin32yank";
    set_clipboard(v, false).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "Hello\rfrom\rwin32yank";
    set_clipboard(v, false).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "Hello\r\nfrom\r\nwin32yank";
    set_clipboard(v, false).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "\r\nfrom\r\nwin32yank\r\n\n...\\r\n";
    set_clipboard(v, false).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    //
    // set_clipboard(true)
    set_clipboard("", true).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), "");
    sleep(Duration::from_millis(sleep_time));

    set_clipboard("\n", true).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), "\r\n");
    sleep(Duration::from_millis(sleep_time));

    set_clipboard("\r\n", true).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), "\r\n");
    sleep(Duration::from_millis(sleep_time));

    let v = "\r\nfrom\r\nwin32yank\r\n\n...\\r\n";
    set_clipboard(v, true).unwrap();
    assert_eq!(get_clipboard(false).unwrap(),
               "\r\nfrom\r\nwin32yank\r\n\r\n...\\r\r\n");
}
<commit_msg>Avoid trailing newline when getting clipboard<commit_after>extern crate clipboard_win;
extern crate docopt;
extern crate rustc_serialize;
extern crate winapi;
extern crate user32;
extern crate kernel32;

use clipboard_win::WindowsError;
use clipboard_win::wrapper::{get_last_error, open_clipboard, close_clipboard};
use clipboard_win::clipboard_formats::CF_UNICODETEXT;
use docopt::Docopt;
use kernel32::{GlobalLock, GlobalUnlock};
use winapi::winnt::HANDLE;
use user32::GetClipboardData;
use std::io;
use std::io::Read;

const USAGE: &'static str = "
win32yank

Usage:
    win32yank -o [--lf]
    win32yank -i [--crlf]

Options:
    -o          Print clipboard contents to stdout
    -i          Set clipboard from stdin
    --lf        Replace CRLF with LF before printing to stdout
    --crlf      Replace lone LF bytes with CRLF before setting the clipboard
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_o: bool,
    flag_i: bool,
    flag_lf: bool,
    flag_crlf: bool,
}

fn from_wide_ptr(ptr: *const u16) -> String {
    use std::ffi::OsString;
    use std::os::windows::ffi::OsStringExt;

    if ptr.is_null() {
        return String::new();
    }

    unsafe {
        assert!(!ptr.is_null());
        let len = (0..std::isize::MAX).position(|i| *ptr.offset(i) == 0).unwrap();
        let slice = std::slice::from_raw_parts(ptr, len);
        OsString::from_wide(slice).to_string_lossy().into_owned()
    }
}

fn get_clipboard(replace_crlf: bool) -> Result<String, WindowsError> {
    let result: Result<String, WindowsError>;
    try!(open_clipboard());
    unsafe {
        let text_handler: HANDLE = GetClipboardData(CF_UNICODETEXT as u32);

        if text_handler.is_null() {
            result = Err(get_last_error());
        } else {
            let text_p = GlobalLock(text_handler) as *const u16;
            result = Ok(from_wide_ptr(text_p));
            GlobalUnlock(text_handler);
        }
    }
    try!(close_clipboard());

    if replace_crlf {
        result.map(|data| data.replace("\r\n", "\n"))
    } else {
        result
    }
}

fn set_clipboard(content: &str, replace_lf: bool) -> Result<(), WindowsError> {
    // clipboard_win::wrapper::set_clipboard uses CF_UNICODETEXT,
    // which is what we want

    if replace_lf {
        let chunks = content.split("\r\n")
            .map(|item| item.replace("\n", "\r\n"));
        let mut first = true;
        let mut out = String::with_capacity(content.len());
        for chunk in chunks {
            if first {
                first = false;
            } else {
                out.push_str("\r\n");
            }
            out.push_str(&chunk);
        }
        clipboard_win::set_clipboard(&out)
    } else {
        clipboard_win::set_clipboard(content)
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.decode())
                            .unwrap_or_else(|e| e.exit());

    if args.flag_o {
        let content = get_clipboard(args.flag_lf).unwrap();
        print!("{}", content);
    } else if args.flag_i {
        let mut stdin = io::stdin();
        let mut content = String::new();
        stdin.read_to_string(&mut content).unwrap();
        set_clipboard(&content, args.flag_crlf).unwrap();
    }
}

#[test]
fn test() {
    // Windows dislikes if we lock the clipboard too long
    // sleep for bit
    use std::thread::sleep;
    use std::time::Duration;
    let sleep_time = 300;

    let v = "Hello\nfrom\nwin32yank";
    set_clipboard(v, false).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "Hello\rfrom\rwin32yank";
    set_clipboard(v, false).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "Hello\r\nfrom\r\nwin32yank";
    set_clipboard(v, false).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    let v = "\r\nfrom\r\nwin32yank\r\n\n...\\r\n";
    set_clipboard(v, false).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), v);
    sleep(Duration::from_millis(sleep_time));

    //
    // set_clipboard(true)
    set_clipboard("", true).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), "");
    sleep(Duration::from_millis(sleep_time));

    set_clipboard("\n", true).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), "\r\n");
    sleep(Duration::from_millis(sleep_time));

    set_clipboard("\r\n", true).unwrap();
    assert_eq!(get_clipboard(false).unwrap(), "\r\n");
    sleep(Duration::from_millis(sleep_time));

    let v = "\r\nfrom\r\nwin32yank\r\n\n...\\r\n";
    set_clipboard(v, true).unwrap();
    assert_eq!(get_clipboard(false).unwrap(),
               "\r\nfrom\r\nwin32yank\r\n\r\n...\\r\r\n");
}
<|endoftext|>


<commit_before>// Copyright 2017 Jeremy Wall <jeremy@marzhillstudios.com>
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
#[macro_use]
extern crate clap;
extern crate ucglib;

use std::cell::RefCell;
use std::error::Error;
use std::fs::File;
use std::io;
use std::path::{Path, PathBuf};
use std::process;
use std::rc::Rc;

use ucglib::build;
use ucglib::build::assets::{Cache, MemoryCache};
use ucglib::build::Val;
use ucglib::convert::traits;
use ucglib::convert::ConverterRunner;

// TODO(jwall): List the target output types automatically.
fn do_flags<'a>() -> clap::ArgMatches<'a> {
    clap_app!(
        ucg =>
            (version: crate_version!())
            (author: crate_authors!())
            (about: "Universal Configuration Grammar compiler.")
            (@subcommand inspect =>
             (about: "Inspect a specific symbol in a ucg file.")
             (@arg sym: --sym +takes_value +required "Specify a specific binding in the ucg file to output.")
             (@arg target: --format +required +takes_value "Inspect output type. (flags, json, env, exec)")
             (@arg INPUT: +required "Input ucg file to inspect symbol from.")
            )
            (@subcommand build =>
             (about: "Build a list of ucg files.")
             (@arg recurse: -r +required conflicts_with[INPUT] "Whether we should recurse in directories or not.")
             (@arg INPUT: ... "Input ucg files or directories to build. If not provided then build the contents of the current directory.")
            )
            (@subcommand validate =>
             (about: "Check a list of ucg files for errors and run assertions.")
             (@arg recurse: -r +required conflicts_with[INPUT] "Whether we should recurse or not.")
             (@arg INPUT: ... "Input ucg files or directories to validate. If not provided scan the director for files with _test.ucg")
            )
            (@subcommand converters =>
             (about: "list the available converters")
             (@arg name: -c --converter-name +takes_value "Optionally print help for the provided converter")
            )
    ).get_matches()
}

fn run_converter(c: ConverterRunner, v: Rc<Val>, f: Option<&str>) -> traits::Result {
    let file: Box<std::io::Write> = match f {
        Some(f) => {
            let mut path_buf = PathBuf::from(f);
            path_buf.set_extension(c.ext());
            let new_path = path_buf.to_str().unwrap();
            Box::new(try!(File::create(&new_path)))
        }
        None => Box::new(io::stdout()),
    };
    c.convert(v, file)
}

fn build_file(
    file: &str,
    validate: bool,
    cache: Rc<RefCell<Cache>>,
) -> Result<build::Builder, Box<Error>> {
    let root = PathBuf::from(file);
    let mut builder = build::Builder::new(root.parent().unwrap(), cache);
    if validate {
        builder.enable_validate_mode();
    }
    try!(builder.build_file(file));
    if validate {
        println!("{}", builder.assert_collector.summary);
    }
    Ok(builder)
}

fn do_validate(file: &str, cache: Rc<RefCell<Cache>>) -> bool {
    match build_file(file, true, cache) {
        Ok(_) => println!("File {} validates", file),
        Err(msg) => {
            eprintln!("Err 2: {}", msg);
            return false;
        }
    }
    return true;
}

fn do_compile(file: &str, cache: Rc<RefCell<Cache>>) -> bool {
    println!("Building {}", file);
    let builder = match build_file(file, false, cache.clone()) {
        Ok(builder) => builder,
        Err(err) => {
            eprintln!("{:?}", err);
            return false;
        }
    };
    let (typ, val) = match builder.out_lock {
        Some((ref typ, ref val)) => (typ, val.clone()),
        None => {
            eprintln!("Build results in no value.");
            return false;
        }
    };
    match ConverterRunner::new(typ) {
        Ok(converter) => {
            run_converter(converter, val, Some(file)).unwrap();
            eprintln!("Build successful");
            process::exit(0);
        }
        Err(msg) => {
            eprintln!("{}", msg);
            return false;
        }
    }
}

fn visit_ucg_files(
    path: &Path,
    recurse: bool,
    validate: bool,
    cache: Rc<RefCell<Cache>>,
) -> Result<bool, Box<Error>> {
    let our_path = String::from(path.to_string_lossy());
    let mut result = true;
    if path.is_dir() {
        for entry in try!(std::fs::read_dir(path)) {
            let next_item = try!(entry);
            let next_path = next_item.path();
            let path_as_string = String::from(next_path.to_string_lossy());
            if next_path.is_dir() && recurse {
                if let Err(msg) = visit_ucg_files(&next_path, recurse, validate, cache.clone()) {
                    eprintln!("Err 1: {}", msg);
                    result = false;
                }
            } else {
                if validate && path_as_string.ends_with("_test.ucg") {
                    if !do_validate(&path_as_string, cache.clone()) {
                        result = false;
                    }
                } else {
                    if !do_compile(&path_as_string, cache.clone()) {
                        result = false;
                    }
                }
            }
        }
    } else if validate && our_path.ends_with("_test.ucg") {
        if !do_validate(&our_path, cache) {
            result = false;
        }
    } else {
        if !do_compile(&our_path, cache) {
            result = false;
        }
    }
    Ok(result)
}

fn main() {
    let app = do_flags();
    let cache: Rc<RefCell<Cache>> = Rc::new(RefCell::new(MemoryCache::new()));
    if let Some(matches) = app.subcommand_matches("inspect") {
        let file = matches.value_of("INPUT").unwrap();
        let sym = matches.value_of("sym");
        let target = matches.value_of("target").unwrap();
        let root = PathBuf::from(file);
        let mut builder = build::Builder::new(root.parent().unwrap(), cache);
        match ConverterRunner::new(target) {
            Ok(converter) => {
                // TODO(jwall): We should warn if this is a test file.
                let result = builder.build_file(file);
                if !result.is_ok() {
                    eprintln!("{:?}", result.err().unwrap());
                    process::exit(1);
                }
                let val = match sym {
                    Some(sym_name) => builder.get_out_by_name(sym_name),
                    None => builder.last,
                };
                match val {
                    Some(value) => {
                        // We use None here because we always output to stdout for an inspect.
                        run_converter(converter, value, None).unwrap();
                        eprintln!("Build successful");
                        process::exit(0);
                    }
                    None => {
                        eprintln!("Build results in no value.");
                        process::exit(1);
                    }
                }
            }
            Err(msg) => {
                eprintln!("{}", msg);
                process::exit(1);
            }
        }
    } else if let Some(matches) = app.subcommand_matches("build") {
        let files = matches.values_of("INPUT");
        let recurse = matches.is_present("recurse");
        let mut ok = true;
        if files.is_none() {
            let curr_dir = std::env::current_dir().unwrap();
            let ok = visit_ucg_files(curr_dir.as_path(), recurse, false, cache.clone());
            if let Ok(false) = ok {
                process::exit(1)
            }
        }
        for file in files.unwrap() {
            let pb = PathBuf::from(file);
            if let Ok(false) = visit_ucg_files(&pb, recurse, false, cache.clone()) {
                ok = false;
            }
        }
        if !ok {
            process::exit(1)
        }
    } else if let Some(matches) = app.subcommand_matches("validate") {
        let files = matches.values_of("INPUT");
        let recurse = matches.is_present("recurse");
        if files.is_none() {
            let curr_dir = std::env::current_dir().unwrap();
            let ok = visit_ucg_files(curr_dir.as_path(), recurse, true, cache.clone());
            if let Ok(false) = ok {
                process::exit(1)
            }
        } else {
            let mut ok = true;
            for file in files.unwrap() {
                let pb = PathBuf::from(file);
                if pb.is_dir() {
                    if let Ok(false) = visit_ucg_files(pb.as_path(), recurse, true, cache.clone()) {
                        ok = false;
                    }
                } else {
                    match build_file(file, true, cache.clone()) {
                        Ok(b) => {
                            if b.assert_collector.success {
                                println!("File {} Validates", file);
                            } else {
                                println!("File {} Fails", file);
                                ok = false;
                            }
                        }
                        Err(msg) => {
                            // We continue to process the other files despite this failure.
                            eprintln!("{}", msg);
                            ok = false;
                        }
                    }
                }
            }
            if !ok {
                process::exit(1)
            }
        }
        process::exit(0);
    } else if let Some(_todo) = app.subcommand_matches("converters") {
    }
}
<commit_msg>MAINT: Improved wording in our build messages.<commit_after>// Copyright 2017 Jeremy Wall <jeremy@marzhillstudios.com>
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
#[macro_use]
extern crate clap;
extern crate ucglib;

use std::cell::RefCell;
use std::error::Error;
use std::fs::File;
use std::io;
use std::path::{Path, PathBuf};
use std::process;
use std::rc::Rc;

use ucglib::build;
use ucglib::build::assets::{Cache, MemoryCache};
use ucglib::build::Val;
use ucglib::convert::traits;
use ucglib::convert::ConverterRunner;

// TODO(jwall): List the target output types automatically.
fn do_flags<'a>() -> clap::ArgMatches<'a> {
    clap_app!(
        ucg =>
            (version: crate_version!())
            (author: crate_authors!())
            (about: "Universal Configuration Grammar compiler.")
            (@subcommand inspect =>
             (about: "Inspect a specific symbol in a ucg file.")
             (@arg sym: --sym +takes_value +required "Specify a specific binding in the ucg file to output.")
             (@arg target: --format +required +takes_value "Inspect output type. (flags, json, env, exec)")
             (@arg INPUT: +required "Input ucg file to inspect symbol from.")
            )
            (@subcommand build =>
             (about: "Build a list of ucg files.")
             (@arg recurse: -r +required conflicts_with[INPUT] "Whether we should recurse in directories or not.")
             (@arg INPUT: ... "Input ucg files or directories to build. If not provided then build the contents of the current directory.")
            )
            (@subcommand validate =>
             (about: "Check a list of ucg files for errors and run assertions.")
             (@arg recurse: -r +required conflicts_with[INPUT] "Whether we should recurse or not.")
             (@arg INPUT: ... "Input ucg files or directories to validate. If not provided scan the director for files with _test.ucg")
            )
            (@subcommand converters =>
             (about: "list the available converters")
             (@arg name: -c --converter-name +takes_value "Optionally print help for the provided converter")
            )
    ).get_matches()
}

fn run_converter(c: ConverterRunner, v: Rc<Val>, f: Option<&str>) -> traits::Result {
    let file: Box<std::io::Write> = match f {
        Some(f) => {
            let mut path_buf = PathBuf::from(f);
            path_buf.set_extension(c.ext());
            let new_path = path_buf.to_str().unwrap();
            Box::new(try!(File::create(&new_path)))
        }
        None => Box::new(io::stdout()),
    };
    c.convert(v, file)
}

fn build_file(
    file: &str,
    validate: bool,
    cache: Rc<RefCell<Cache>>,
) -> Result<build::Builder, Box<Error>> {
    let root = PathBuf::from(file);
    let mut builder = build::Builder::new(root.parent().unwrap(), cache);
    if validate {
        builder.enable_validate_mode();
    }
    try!(builder.build_file(file));
    if validate {
        println!("{}", builder.assert_collector.summary);
    }
    Ok(builder)
}

fn do_validate(file: &str, cache: Rc<RefCell<Cache>>) -> bool {
    println!("Validating {}", file);
    match build_file(file, true, cache) {
        Ok(_) => println!("{} validates\n\n", file),
        Err(msg) => {
            eprintln!("Err: {}", msg);
            return false;
        }
    }
    return true;
}

fn do_compile(file: &str, cache: Rc<RefCell<Cache>>) -> bool {
    println!("Building {}", file);
    let builder = match build_file(file, false, cache.clone()) {
        Ok(builder) => builder,
        Err(err) => {
            eprintln!("{:?}", err);
            return false;
        }
    };
    let (typ, val) = match builder.out_lock {
        Some((ref typ, ref val)) => (typ, val.clone()),
        None => {
            eprintln!("Build results in no artifacts.");
            return false;
        }
    };
    match ConverterRunner::new(typ) {
        Ok(converter) => {
            run_converter(converter, val, Some(file)).unwrap();
            eprintln!("Build successful");
            process::exit(0);
        }
        Err(msg) => {
            eprintln!("{}", msg);
            return false;
        }
    }
}

fn visit_ucg_files(
    path: &Path,
    recurse: bool,
    validate: bool,
    cache: Rc<RefCell<Cache>>,
) -> Result<bool, Box<Error>> {
    let our_path = String::from(path.to_string_lossy());
    let mut result = true;
    if path.is_dir() {
        for entry in try!(std::fs::read_dir(path)) {
            let next_item = try!(entry);
            let next_path = next_item.path();
            let path_as_string = String::from(next_path.to_string_lossy());
            if next_path.is_dir() && recurse {
                if let Err(msg) = visit_ucg_files(&next_path, recurse, validate, cache.clone()) {
                    eprintln!("Err 1: {}", msg);
                    result = false;
                }
            } else {
                if validate && path_as_string.ends_with("_test.ucg") {
                    if !do_validate(&path_as_string, cache.clone()) {
                        result = false;
                    }
                } else {
                    if !do_compile(&path_as_string, cache.clone()) {
                        result = false;
                    }
                }
            }
        }
    } else if validate && our_path.ends_with("_test.ucg") {
        if !do_validate(&our_path, cache) {
            result = false;
        }
    } else {
        if !do_compile(&our_path, cache) {
            result = false;
        }
    }
    Ok(result)
}

fn main() {
    let app = do_flags();
    let cache: Rc<RefCell<Cache>> = Rc::new(RefCell::new(MemoryCache::new()));
    if let Some(matches) = app.subcommand_matches("inspect") {
        let file = matches.value_of("INPUT").unwrap();
        let sym = matches.value_of("sym");
        let target = matches.value_of("target").unwrap();
        let root = PathBuf::from(file);
        let mut builder = build::Builder::new(root.parent().unwrap(), cache);
        match ConverterRunner::new(target) {
            Ok(converter) => {
                // TODO(jwall): We should warn if this is a test file.
                let result = builder.build_file(file);
                if !result.is_ok() {
                    eprintln!("{:?}", result.err().unwrap());
                    process::exit(1);
                }
                let val = match sym {
                    Some(sym_name) => builder.get_out_by_name(sym_name),
                    None => builder.last,
                };
                match val {
                    Some(value) => {
                        // We use None here because we always output to stdout for an inspect.
                        run_converter(converter, value, None).unwrap();
                        eprintln!("Build successful");
                        process::exit(0);
                    }
                    None => {
                        eprintln!("Build results in no value.");
                        process::exit(1);
                    }
                }
            }
            Err(msg) => {
                eprintln!("{}", msg);
                process::exit(1);
            }
        }
    } else if let Some(matches) = app.subcommand_matches("build") {
        let files = matches.values_of("INPUT");
        let recurse = matches.is_present("recurse");
        let mut ok = true;
        if files.is_none() {
            let curr_dir = std::env::current_dir().unwrap();
            let ok = visit_ucg_files(curr_dir.as_path(), recurse, false, cache.clone());
            if let Ok(false) = ok {
                process::exit(1)
            }
        }
        for file in files.unwrap() {
            let pb = PathBuf::from(file);
            if let Ok(false) = visit_ucg_files(&pb, recurse, false, cache.clone()) {
                ok = false;
            }
        }
        if !ok {
            process::exit(1)
        }
    } else if let Some(matches) = app.subcommand_matches("validate") {
        let files = matches.values_of("INPUT");
        let recurse = matches.is_present("recurse");
        if files.is_none() {
            let curr_dir = std::env::current_dir().unwrap();
            let ok = visit_ucg_files(curr_dir.as_path(), recurse, true, cache.clone());
            if let Ok(false) = ok {
                process::exit(1)
            }
        } else {
            let mut ok = true;
            for file in files.unwrap() {
                let pb = PathBuf::from(file);
                if pb.is_dir() {
                    if let Ok(false) = visit_ucg_files(pb.as_path(), recurse, true, cache.clone()) {
                        ok = false;
                    }
                } else {
                    match build_file(file, true, cache.clone()) {
                        Ok(b) => {
                            if b.assert_collector.success {
                                println!("File {} Validates", file);
                            } else {
                                println!("File {} Fails", file);
                                ok = false;
                            }
                        }
                        Err(msg) => {
                            // We continue to process the other files despite this failure.
                            eprintln!("{}", msg);
                            ok = false;
                        }
                    }
                }
            }
            if !ok {
                process::exit(1)
            }
        }
        process::exit(0);
    } else if let Some(_todo) = app.subcommand_matches("converters") {
    }
}
<|endoftext|>


<commit_before>extern crate nix;
extern crate colored;

mod util;
mod stats;

use std::cmp;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use std::collections::HashSet;
use nix::sys::statvfs::vfs::Statvfs;
use colored::*;

use util::{iec, bargraph};
use stats::Stats;

fn main() {
    let file = File::open("/proc/mounts").unwrap();
    let reader = BufReader::new(&file);

    let mut excludes = HashSet::new();
    let exclude_types = "cgroup autofs securityfs configfs pstore binfmt_misc debugfs \
                         hugetlbfs devpts mqueue proc sysfs";
    for t in exclude_types.split_whitespace() {
        excludes.insert(t);
    }

    let mut stats: Vec<Stats> = Vec::new();
    let mut max_width = 0;

    for line in reader.lines() {
        match line {
            Ok(line) => {
                let fields: Vec<&str> = line.split_whitespace().collect();
                if excludes.contains(fields[2]) {
                    continue;
                }
                let statvfs = Statvfs::for_path(fields[1]).unwrap();
                let size = statvfs.f_blocks * statvfs.f_bsize;
                let avail = statvfs.f_bavail * statvfs.f_bsize;

                let s = Stats::new(fields[0], size, avail, fields[1]);

                max_width = cmp::max(max_width, s.filesystem.len());
                stats.push(s);
            },
            Err(_) => panic!(),
        }
    }

    let headers = ["Filesystem", "Size", "Used", "Avail", "Use%", "", "Mounted on"];
    let headers: Vec<ColoredString> = headers.into_iter().map(|x| x.yellow()).collect();
    println!("{:width$} {:>5} {:>5} {:>5} {:>5} {:20} {:16}",
             headers[0], headers[1], headers[2], headers[3],
             headers[4], headers[5], headers[6], width = max_width);

    for stat in stats {
        println!("{:width$} {:>5} {:>5} {:>5} {:>5.1} {:20} {:16}",
                 stat.filesystem, iec(stat.size), iec(stat.used), iec(stat.avail),
                 stat.percent, bargraph(stat.percent), stat.mount, width = max_width);
    }

}
<commit_msg>Magic numbers are bad.<commit_after>extern crate nix;
extern crate colored;

mod util;
mod stats;

use std::cmp;
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
use std::collections::HashSet;
use nix::sys::statvfs::vfs::Statvfs;
use colored::*;

use util::{iec, bargraph};
use stats::Stats;

const FS_SPEC: usize = 0;
const FS_FILE: usize = 1;
const FS_VFSTYPE: usize = 2;

fn main() {
    let file = File::open("/proc/mounts").unwrap();
    let reader = BufReader::new(&file);

    let mut excludes = HashSet::new();
    let exclude_types = "cgroup autofs securityfs configfs pstore binfmt_misc debugfs \
                         hugetlbfs devpts mqueue proc sysfs";
    for t in exclude_types.split_whitespace() {
        excludes.insert(t);
    }

    let mut stats: Vec<Stats> = Vec::new();
    let mut max_width = 0;

    for line in reader.lines() {
        match line {
            Ok(line) => {
                let fields: Vec<&str> = line.split_whitespace().collect();
                if excludes.contains(fields[FS_VFSTYPE]) {
                    continue;
                }
                let statvfs = Statvfs::for_path(fields[FS_FILE]).unwrap();
                let size = statvfs.f_blocks * statvfs.f_bsize;
                let avail = statvfs.f_bavail * statvfs.f_bsize;

                let s = Stats::new(fields[FS_SPEC], size, avail, fields[FS_FILE]);

                max_width = cmp::max(max_width, s.filesystem.len());
                stats.push(s);
            },
            Err(_) => panic!(),
        }
    }

    let headers = ["Filesystem", "Size", "Used", "Avail", "Use%", "", "Mounted on"];
    let headers: Vec<ColoredString> = headers.into_iter().map(|x| x.yellow()).collect();
    println!("{:width$} {:>5} {:>5} {:>5} {:>5} {:20} {:16}",
             headers[0], headers[1], headers[2], headers[3],
             headers[4], headers[5], headers[6], width = max_width);

    for stat in stats {
        println!("{:width$} {:>5} {:>5} {:>5} {:>5.1} {:20} {:16}",
                 stat.filesystem, iec(stat.size), iec(stat.used), iec(stat.avail),
                 stat.percent, bargraph(stat.percent), stat.mount, width = max_width);
    }

}
<|endoftext|>


<commit_before>#![allow(unused_imports)]
#![allow(dead_code)]
#[allow(unused)]

mod api;
mod server;
mod config;
mod consul;

#[cfg(test)]
mod config_test;

#[macro_use]
extern crate log;
#[macro_use]
extern crate clap;
extern crate grpcio;
extern crate futures;
extern crate protobuf;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate toml;
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate reqwest;
extern crate serde;
extern crate url;

use clap::{Arg, App, SubCommand};
use std::process::exit;
use std::sync::Arc;
use consul::Client as ConsulClient;
use consul::catalog::Catalog;
use std::borrow::Borrow;

fn main() {
    let app = App::new("diplomat")
        .version(crate_version!())
        .about(
            "Provides the Envoy v2 API as a gRPC service and CLI application.",
        )
        .author("Timothy Perrett")
        .arg(
            Arg::with_name("c")
                .long("config")
                .value_name("config")
                .help("Path to the configuration for diplomat")
                .required(false)
                .takes_value(true),
        )
        .subcommand(
            SubCommand::with_name("eds")
                .about(
                    "given a service name, resolve the IPs providing that service",
                )
                .arg(
                    Arg::with_name("service-name")
                        .long("service-name")
                        .value_name("service-name")
                        .required(true)
                        .takes_value(true),
                ),
        );

    // TIM: Not sure if cloning here is going to cause problems,
    // but given this is once at the edge of the world it probally isn't
    // too much of a big deal.
    let matches = app.clone().get_matches();

    let config_path: &str = matches.value_of("consul-addr").unwrap_or("diplomat.toml");
    info!(
        "==>> attempting to load configuration from '{}'",
        config_path
    );

    let config = config::load(config_path.to_string());
    if config.is_err() {
        error!("==>> failed loading the specified configuration file... exiting.")
    }

    match matches.subcommand() {
        ("eds", Some(_)) => {
            let ccc = consul::Config::new().unwrap();
            let xxx = ConsulClient::new(ccc);

            let nodes = xxx.list_nodes_for("consul", None);

            println!("{:?}", nodes);
        }
        ("serve", Some(_)) => {
            ::server::start(config.unwrap());
        }
        _ => {
            let _ = app.clone().print_help();
            println!("");
        }
    }
}
<commit_msg>fixing config arg, adding client subcommand<commit_after>#![allow(unused_imports)]
#![allow(dead_code)]
#[allow(unused)]

mod api;
mod server;
mod config;
mod consul;

#[cfg(test)]
mod config_test;

#[macro_use]
extern crate log;
#[macro_use]
extern crate clap;
extern crate grpcio;
extern crate futures;
extern crate protobuf;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
extern crate toml;
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate reqwest;
extern crate serde;
extern crate url;

use clap::{Arg, App, SubCommand};
use std::process::exit;
use std::sync::Arc;
use consul::Client as ConsulClient;
use consul::catalog::Catalog;
use std::borrow::Borrow;

fn main() {
    let app = App::new("diplomat")
        .version(crate_version!())
        .about(
            "Provides the Envoy v2 API as a gRPC service and CLI application.",
        )
        .author("Timothy Perrett")
        .arg(
            Arg::with_name("config")
                .long("config")
                .value_name("config")
                .help("Path to the configuration for diplomat")
                .required(false)
                .takes_value(true),
        )
        .subcommand(
            SubCommand::with_name("client")
                .about("Interact with diplomat using the cli",)
                .subcommand(
                    SubCommand::with_name("eds")
                        .about("given a service name, resolve the IPs providing that service",)
                        .arg(
                            Arg::with_name("service-name")
                                .long("service-name")
                                .value_name("service-name")
                                .required(true)
                                .takes_value(true),
                        )
                )
                .subcommand(
                    SubCommand::with_name("cds")
                        .about("cds",)
                        .arg(
                            Arg::with_name("service-name")
                                .long("service-name")
                                .value_name("service-name")
                                .required(true)
                                .takes_value(true),
                        ),
                ),
        )
        .subcommand(
            SubCommand::with_name("serve")
                .about("Starts the diplomat server",)
        );

    // TIM: Not sure if cloning here is going to cause problems,
    // but given this is once at the edge of the world it probally isn't
    // too much of a big deal.
    let matches = app.clone().get_matches();

    let config_path: &str = matches.value_of("config").unwrap_or("diplomat.toml");
    info!(
        "==>> attempting to load configuration from '{}'",
        config_path
    );

    let config = config::load(config_path.to_string());
    if config.is_err() {
        error!("==>> failed loading the specified configuration file... exiting.")
    }

    match matches.subcommand() {
        ("client", Some(sub_m)) => {
            match sub_m.subcommand_name() {
                Some("eds") => {
                    let ccc = consul::Config::new().unwrap();
                    let xxx = ConsulClient::new(ccc);
                    let nodes = xxx.list_nodes_for("consul", None);
                    println!("{:?}", nodes);
                }
                Some("cds") => {
                    println!("cds is currently not implemented")
                }
                _ => {
                    let _ = app.clone().print_help();
                    println!("");
                }
            }
        }
        ("serve", Some(_)) => {
            ::server::start(config.unwrap());
        }
        _ => {
            let _ = app.clone().print_help();
            println!("");
        }
    }
}

<|endoftext|>


<commit_before>// TODO: Fix unwraps

extern crate git2;
extern crate term_painter;

use std::error::Error;
use std::io;
use std::env;
use std::path::{Path, PathBuf};

use term_painter::{ToStyle, Color};

fn main() {
    let working_dir = match env::current_dir() {
        Ok(path) => path,
        Err(err) => {
            println!("Error getting working directory: {}", err.description());
            return;
        }
    };

    println!("{:?}", walk_dirs(&working_dir));
}

fn walk_dirs(path: &Path) -> io::Result<()> {
    let mut pending: Vec<PathBuf> = Vec::new();

    loop {
        let current_dir = if pending.len() == 0 {
            path.to_path_buf()
        } else {
            pending.pop().unwrap()
        };

        let read_result = current_dir.read_dir();

        if read_result.is_ok() {
            let iter = read_result.unwrap()
                .filter(|x| x.is_ok())
                .map(|x| x.unwrap())
                .filter(|x| match x.file_type() {
                    Ok(t) => t.is_dir(),
                    Err(_) => false,
                })
                .filter(|x| match x.path().file_name() {
                    Some(name) => {
                        let name_str = name.to_str().unwrap();

                        !name_str.starts_with(".") && !name_str.starts_with("$")
                    }
                    None => false,
                });

            for entry in iter {
                if git_changes(&entry.path()).is_err() {
                    pending.push(entry.path().to_path_buf());
                }
            }
        }

        if pending.len() == 0 {
            break;
        }
    }

    Ok(())
}

enum GitError {
    OpenRepo,
}

impl From<git2::Error> for GitError {
    fn from(_: git2::Error) -> Self {
        GitError::OpenRepo
    }
}

fn git_changes(path: &Path) -> Result<(), GitError> {
    let repo = git2::Repository::open(path)?;
    let mut opts = git2::StatusOptions::new();

    opts.include_ignored(false)
        .include_untracked(true)
        .recurse_untracked_dirs(true)
        .include_unreadable_as_untracked(true)
        .disable_pathspec_match(true)
        .exclude_submodules(true);

    let statuses = repo.statuses(Some(&mut opts)).unwrap();
    let mut statuses_iter = statuses.iter()
        .filter(|x| {
            if x.status() != git2::STATUS_WT_DELETED {
                return true;
            }

            // For some reason, some files with the deleted
            // status actually still exist, so ignore these.
            let mut del_path = path.to_path_buf();
            del_path.push(x.path().unwrap());

            !del_path.exists()
        })
        .peekable();

    if statuses_iter.peek().is_none() {
        return Ok(());
    }

    println!("{}", path.to_str().unwrap());

    for entry in statuses_iter {
        let pre = match entry.status() {
            git2::STATUS_WT_DELETED => Color::BrightRed.paint("    Deleted"),
            git2::STATUS_WT_MODIFIED => Color::BrightCyan.paint("   Modified"),
            git2::STATUS_WT_NEW => Color::BrightGreen.paint("        New"),
            git2::STATUS_WT_RENAMED => Color::BrightCyan.paint("    Renamed"),
            git2::STATUS_WT_TYPECHANGE => Color::BrightCyan.paint("Typechanged"),
            _ => Color::BrightMagenta.paint("    Unknown"),
        };

        println!("  {} {}", pre, entry.path().unwrap());
    }

    Ok(())
}
<commit_msg>Filter out bare repos again<commit_after>// TODO: Fix unwraps

extern crate git2;
extern crate term_painter;

use std::error::Error;
use std::io;
use std::env;
use std::path::{Path, PathBuf};

use term_painter::{ToStyle, Color};

fn main() {
    let working_dir = match env::current_dir() {
        Ok(path) => path,
        Err(err) => {
            println!("Error getting working directory: {}", err.description());
            return;
        }
    };

    println!("{:?}", walk_dirs(&working_dir));
}

fn walk_dirs(path: &Path) -> io::Result<()> {
    let mut pending: Vec<PathBuf> = Vec::new();

    loop {
        let current_dir = if pending.len() == 0 {
            path.to_path_buf()
        } else {
            pending.pop().unwrap()
        };

        let read_result = current_dir.read_dir();

        if read_result.is_ok() {
            let iter = read_result.unwrap()
                .filter(|x| x.is_ok())
                .map(|x| x.unwrap())
                .filter(|x| match x.file_type() {
                    Ok(t) => t.is_dir(),
                    Err(_) => false,
                })
                .filter(|x| match x.path().file_name() {
                    Some(name) => {
                        let name_str = name.to_str().unwrap();

                        !name_str.starts_with(".") && !name_str.starts_with("$")
                    }
                    None => false,
                });

            for entry in iter {
                if git_changes(&entry.path()).is_err() {
                    pending.push(entry.path().to_path_buf());
                }
            }
        }

        if pending.len() == 0 {
            break;
        }
    }

    Ok(())
}

enum GitError {
    OpenRepo,
}

impl From<git2::Error> for GitError {
    fn from(_: git2::Error) -> Self {
        GitError::OpenRepo
    }
}

fn git_changes(path: &Path) -> Result<(), GitError> {
    let repo = git2::Repository::open(path)?;

    if repo.is_bare() {
        return Ok(())
    }

    let mut opts = git2::StatusOptions::new();

    opts.include_ignored(false)
        .include_untracked(true)
        .recurse_untracked_dirs(true)
        .include_unreadable_as_untracked(true)
        .disable_pathspec_match(true)
        .exclude_submodules(true);

    let statuses = repo.statuses(Some(&mut opts)).unwrap();
    let mut statuses_iter = statuses.iter()
        .filter(|x| {
            if x.status() != git2::STATUS_WT_DELETED {
                return true;
            }

            // For some reason, some files with the deleted
            // status actually still exist, so ignore these.
            let mut del_path = path.to_path_buf();
            del_path.push(x.path().unwrap());

            !del_path.exists()
        })
        .peekable();

    if statuses_iter.peek().is_none() {
        return Ok(());
    }

    println!("{}", path.to_str().unwrap());

    for entry in statuses_iter {
        let pre = match entry.status() {
            git2::STATUS_WT_DELETED => Color::BrightRed.paint("    Deleted"),
            git2::STATUS_WT_MODIFIED => Color::BrightCyan.paint("   Modified"),
            git2::STATUS_WT_NEW => Color::BrightGreen.paint("        New"),
            git2::STATUS_WT_RENAMED => Color::BrightCyan.paint("    Renamed"),
            git2::STATUS_WT_TYPECHANGE => Color::BrightCyan.paint("Typechanged"),
            _ => Color::BrightMagenta.paint("    Unknown"),
        };

        println!("  {} {}", pre, entry.path().unwrap());
    }

    Ok(())
}
<|endoftext|>