<commit_before>use std::env;
use std::error::Error;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::path::Path;

fn main() {
    // skip the first element as it is the program name
    let args = env::args();
    if args.len() == 1 {
        println!("args.len() == 1");
        cat_stdin();
    } else {
        println!("args.len() != 1");
        for arg in args.skip(1) {
            let path = Path::new(&arg);
            cat(&path);
        }
    }
}

fn cat_stdin() {
    let stdin = io::stdin();
    let mut s = String::new();
    loop {
        match stdin.read_line(&mut s) {
            Err(why) => panic!("cat: failed to read from stdin: {}", why),
            Ok(n) => if n == 0 {
                break;
            } else {
                print!("{}", s);
                s.clear();
            },
        };
    }
}

fn cat(path: &Path) {
    let display = path.display();
    let mut file = match File::open(path) {
        Err(why) => panic!("cat: failed to open {}: {}", display, why.description()),
        Ok(file) => file,
    };
    let mut s = String::new();
    match file.read_to_string(&mut s) {
        Err(why) => panic!("cat: failed to read {}: {}", display, why.description()),
        Ok(_) => print!("{}", s),
    };
}
<commit_msg>Added ability to specify stdin as '-' on cli<commit_after>use std::env;
use std::error::Error;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::path::Path;

fn main() {
    // skip the first element as it is the program name
    let args = env::args();
    if args.len() == 1 {
        println!("args.len() == 1");
        cat_stdin();
    } else {
        println!("args.len() != 1");
        for arg in args.skip(1) {
            if arg.eq("-") {
                cat_stdin();
            } else {
                let path = Path::new(&arg);
                cat(&path);
            }
        }
    }
}

fn cat_stdin() {
    let stdin = io::stdin();
    let mut s = String::new();
    loop {
        match stdin.read_line(&mut s) {
            Err(why) => panic!("cat: failed to read from stdin: {}", why),
            Ok(n) => if n == 0 {
                break;
            } else {
                print!("{}", s);
                s.clear();
            },
        };
    }
}

fn cat(path: &Path) {
    let display = path.display();
    let mut file = match File::open(path) {
        Err(why) => panic!("cat: failed to open {}: {}", display, why.description()),
        Ok(file) => file,
    };
    let mut s = String::new();
    match file.read_to_string(&mut s) {
        Err(why) => panic!("cat: failed to read {}: {}", display, why.description()),
        Ok(_) => print!("{}", s),
    };
}
<|endoftext|>


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

struct Coordinates {
    x: Cell<i32>,
    y: Cell<i32>,
}

fn main() {
    let origin = Coordinates { x: Cell::new(0), y: Cell::new(0) };

    println!("X is {:?} and Y is {:?}", origin.x, origin.y);

    println!("X is {:?} and Y is {:?}", origin.x, move_up(origin.y));
}

fn move_up(y_cord: Cell<i32>) -> Cell<i32> {
    let new_val = y_cord.get();
    y_cord.set(&new_val + 1);
    y_cord // no semicolong here because it is the return value
}
<commit_msg>figured it out - pretty complex the first time:<commit_after>use std::cell::Cell;

struct Coordinates {
    x: Cell<i32>,
    y: Cell<i32>,
}

fn main() {
    let origin = Coordinates { x: Cell::new(0), y: Cell::new(0) };

    println!("X is {:?} and Y is {:?}", origin.x, origin.y);

    move_up(&origin.y);
    move_up(&origin.y);

    println!("X is {:?} and Y is {:?}", origin.x, origin.y);
}

fn move_up(y_cord: &Cell<i32>) -> &Cell<i32> {
    let new_val = y_cord.get();
    y_cord.set(new_val + 1);
    y_cord // no semicolon here because it is the return value
}
<|endoftext|>


<commit_before>#![feature(duration_span, drain)]

extern crate image;
extern crate rand;
extern crate docopt;
extern crate rustc_serialize;
extern crate num_cpus;
extern crate scoped_threadpool;
extern crate tray_rust;

use std::vec::Vec;
use std::iter;
use std::sync::mpsc::{self, Sender};
use std::path::Path;
use std::time::Duration;

use rand::StdRng;
use docopt::Docopt;

use tray_rust::film::{self, filter, ImageSample};
use tray_rust::geometry::{Geometry, Instance, Emitter};
use tray_rust::sampler::{self, Sampler};
use tray_rust::scene;
use tray_rust::integrator::Integrator;

static USAGE: &'static str = "
Usage: tray_rust <scenefile> [options]

Options:
  -o <file>     Specify the output file to save the image. Supported formats are
                PNG, JPG and PPM. Default is 'out.png'.
  -n <number>   Specify the number of threads to use for rendering. Defaults to the number of cores
                on the system.
  -h, --help    Show this message.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_scenefile: String,
    flag_o: Option<String>,
    flag_n: Option<u32>,
}

/// Threads are each sent a sender end of the channel that is
/// read from by the render target thread which then saves the
/// values recieved to the render target
fn thread_work(tx: Sender<Vec<ImageSample>>, spp: usize, queue: &sampler::BlockQueue,
               scene: &scene::Scene, target: &film::RenderTarget, light_list: &Vec<&Emitter>) {
    let mut sampler = sampler::LowDiscrepancy::new(queue.block_dim(), spp);
    let mut sample_pos = Vec::with_capacity(sampler.max_spp());
    let mut time_samples: Vec<_> = iter::repeat(0.0).take(sampler.max_spp()).collect();
    let block_dim = queue.block_dim();
    let mut block_samples = Vec::with_capacity(sampler.max_spp() * (block_dim.0 * block_dim.1) as usize);
    let mut rng = match StdRng::new() {
        Ok(r) => r,
        Err(e) => { println!("Failed to get StdRng, {}", e); return }
    };
    // Grab a block from the queue and start working on it, submitting samples
    // to the render target thread after each pixel
    for b in queue.iter() {
        sampler.select_block(b);
        while sampler.has_samples() {
            // Get samples for a pixel and render them
            sampler.get_samples(&mut sample_pos, &mut rng);
            sampler.get_samples_1d(&mut time_samples[..], &mut rng);
            let mut samples = Vec::with_capacity(sampler.max_spp());
            for (s, t) in sample_pos.iter().zip(time_samples.iter()) {
                let mut ray = scene.camera.generate_ray(s, *t);
                if let Some(hit) = scene.intersect(&mut ray) {
                    let c = scene.integrator.illumination(scene, light_list, &ray,
                                                          &hit, &mut sampler, &mut rng).clamp();
                    samples.push(ImageSample::new(s.0, s.1, c));
                    block_samples.push(ImageSample::new(s.0, s.1, c));
                }
            }
            if let Err(e) = tx.send(samples) {
                println!("Worker thread exiting with send error {:?}", e);
                return;
            }
        }
        target.write_block(&block_samples, sampler.get_region());
    }
}

/// Render the scene in parallel using `n` threads and write the result to the render target
fn render_parallel(rt: &mut film::RenderTarget, scene: &scene::Scene, n: u32, spp: usize){
    let mut pool = scoped_threadpool::Pool::new(n);
    println!("Rendering using {} threads", n);
    pool.scoped(|scope| {
        let dim = rt.dimensions();
        let block_queue = sampler::BlockQueue::new((dim.0 as u32, dim.1 as u32), (8, 8));
        let light_list: Vec<_> = scene.bvh.into_iter().filter_map(|x| {
            match x {
                &Instance::Emitter(ref e) => Some(e),
                _ => None,
            }
        }).collect();
        assert!(!light_list.is_empty(), "At least one light is required");

        let rx = {
            let (tx, rx) = mpsc::channel();
            for _ in 0..n {
                let t = tx.clone();
                let b = &block_queue;
                let r = &*rt;
                let l = &light_list;
                scope.execute(move || {
                    thread_work(t, spp, b, scene, r, l);
                });
            }
            rx
        };

        for mut v in rx.iter() {
            for s in v.drain(..) {
                rt.write(s.x, s.y, &s.color);
            }
        }
    });
}

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

    let (mut scene, spp, (width, height)) = scene::Scene::load_file(&args.arg_scenefile[..]);
    let mut rt = film::RenderTarget::new(width, height,
                    Box::new(filter::MitchellNetravali::new(2.0, 2.0, 1.0 / 3.0, 1.0 / 3.0))
                    as Box<filter::Filter + Send + Sync>);
    let n = match args.flag_n {
        Some(n) => n,
        None => num_cpus::get() as u32,
    };

    // Render 5 frames. TODO: This should be read from scene file
    let scene_time = 0.0;
    let frames = 1;
    let time_step = scene_time / (frames as f32);
    for i in 0..frames {
        scene.camera.update_shutter(i as f32 * time_step, (i as f32 + 1.0) * time_step);
        let d = Duration::span(|| render_parallel(&mut rt, &scene, n, spp));
        let time = d.as_secs() as f64 + (d.subsec_nanos() as f64) / 1_000_000_000.0;
        println!("Rendering took {}s", time);

        let img = rt.get_render();
        let out_file = match &args.flag_o {
            &Some(ref f) => f.to_string(),
            &None => format!("out_frame{:03}.png", i).to_string(),
        };

        match image::save_buffer(&Path::new(&out_file), &img[..], width as u32, height as u32, image::RGB(8)) {
            Ok(_) => {},
            Err(e) => println!("Error saving image, {}", e),
        };
        let img = rt.get_block_render();
        match image::save_buffer(&Path::new("block_out.png"), &img[..], width as u32, height as u32, image::RGB(8)) {
            Ok(_) => {},
            Err(e) => println!("Error saving image, {}", e),
        };
        rt.clear();
    }
}

<commit_msg>Forgot to clear the list of samples after each block<commit_after>#![feature(duration_span, drain)]

extern crate image;
extern crate rand;
extern crate docopt;
extern crate rustc_serialize;
extern crate num_cpus;
extern crate scoped_threadpool;
extern crate tray_rust;

use std::vec::Vec;
use std::iter;
use std::sync::mpsc::{self, Sender};
use std::path::Path;
use std::time::Duration;

use rand::StdRng;
use docopt::Docopt;

use tray_rust::film::{self, filter, ImageSample};
use tray_rust::geometry::{Geometry, Instance, Emitter};
use tray_rust::sampler::{self, Sampler};
use tray_rust::scene;
use tray_rust::integrator::Integrator;

static USAGE: &'static str = "
Usage: tray_rust <scenefile> [options]

Options:
  -o <file>     Specify the output file to save the image. Supported formats are
                PNG, JPG and PPM. Default is 'out.png'.
  -n <number>   Specify the number of threads to use for rendering. Defaults to the number of cores
                on the system.
  -h, --help    Show this message.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_scenefile: String,
    flag_o: Option<String>,
    flag_n: Option<u32>,
}

/// Threads are each sent a sender end of the channel that is
/// read from by the render target thread which then saves the
/// values recieved to the render target
fn thread_work(tx: Sender<Vec<ImageSample>>, spp: usize, queue: &sampler::BlockQueue,
               scene: &scene::Scene, target: &film::RenderTarget, light_list: &Vec<&Emitter>) {
    let mut sampler = sampler::LowDiscrepancy::new(queue.block_dim(), spp);
    let mut sample_pos = Vec::with_capacity(sampler.max_spp());
    let mut time_samples: Vec<_> = iter::repeat(0.0).take(sampler.max_spp()).collect();
    let block_dim = queue.block_dim();
    let mut block_samples = Vec::with_capacity(sampler.max_spp() * (block_dim.0 * block_dim.1) as usize);
    let mut rng = match StdRng::new() {
        Ok(r) => r,
        Err(e) => { println!("Failed to get StdRng, {}", e); return }
    };
    // Grab a block from the queue and start working on it, submitting samples
    // to the render target thread after each pixel
    for b in queue.iter() {
        sampler.select_block(b);
        while sampler.has_samples() {
            // Get samples for a pixel and render them
            sampler.get_samples(&mut sample_pos, &mut rng);
            sampler.get_samples_1d(&mut time_samples[..], &mut rng);
            let mut samples = Vec::with_capacity(sampler.max_spp());
            for (s, t) in sample_pos.iter().zip(time_samples.iter()) {
                let mut ray = scene.camera.generate_ray(s, *t);
                if let Some(hit) = scene.intersect(&mut ray) {
                    let c = scene.integrator.illumination(scene, light_list, &ray,
                                                          &hit, &mut sampler, &mut rng).clamp();
                    samples.push(ImageSample::new(s.0, s.1, c));
                    block_samples.push(ImageSample::new(s.0, s.1, c));
                }
            }
            if let Err(e) = tx.send(samples) {
                println!("Worker thread exiting with send error {:?}", e);
                return;
            }
        }
        target.write_block(&block_samples, sampler.get_region());
        block_samples.clear();
    }
}

/// Render the scene in parallel using `n` threads and write the result to the render target
fn render_parallel(rt: &mut film::RenderTarget, scene: &scene::Scene, n: u32, spp: usize){
    let mut pool = scoped_threadpool::Pool::new(n);
    println!("Rendering using {} threads", n);
    pool.scoped(|scope| {
        let dim = rt.dimensions();
        let block_queue = sampler::BlockQueue::new((dim.0 as u32, dim.1 as u32), (8, 8));
        let light_list: Vec<_> = scene.bvh.into_iter().filter_map(|x| {
            match x {
                &Instance::Emitter(ref e) => Some(e),
                _ => None,
            }
        }).collect();
        assert!(!light_list.is_empty(), "At least one light is required");

        let rx = {
            let (tx, rx) = mpsc::channel();
            for _ in 0..n {
                let t = tx.clone();
                let b = &block_queue;
                let r = &*rt;
                let l = &light_list;
                scope.execute(move || {
                    thread_work(t, spp, b, scene, r, l);
                });
            }
            rx
        };

        for mut v in rx.iter() {
            for s in v.drain(..) {
                rt.write(s.x, s.y, &s.color);
            }
        }
    });
}

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

    let (mut scene, spp, (width, height)) = scene::Scene::load_file(&args.arg_scenefile[..]);
    let mut rt = film::RenderTarget::new(width, height,
                    Box::new(filter::MitchellNetravali::new(2.0, 2.0, 1.0 / 3.0, 1.0 / 3.0))
                    as Box<filter::Filter + Send + Sync>);
    let n = match args.flag_n {
        Some(n) => n,
        None => num_cpus::get() as u32,
    };

    // Render 5 frames. TODO: This should be read from scene file
    let scene_time = 0.0;
    let frames = 1;
    let time_step = scene_time / (frames as f32);
    for i in 0..frames {
        scene.camera.update_shutter(i as f32 * time_step, (i as f32 + 1.0) * time_step);
        let d = Duration::span(|| render_parallel(&mut rt, &scene, n, spp));
        let time = d.as_secs() as f64 + (d.subsec_nanos() as f64) / 1_000_000_000.0;
        println!("Rendering took {}s", time);

        let img = rt.get_render();
        let out_file = match &args.flag_o {
            &Some(ref f) => f.to_string(),
            &None => format!("out_frame{:03}.png", i).to_string(),
        };

        match image::save_buffer(&Path::new(&out_file), &img[..], width as u32, height as u32, image::RGB(8)) {
            Ok(_) => {},
            Err(e) => println!("Error saving image, {}", e),
        };
        let img = rt.get_block_render();
        match image::save_buffer(&Path::new("block_out.png"), &img[..], width as u32, height as u32, image::RGB(8)) {
            Ok(_) => {},
            Err(e) => println!("Error saving image, {}", e),
        };
        rt.clear();
    }
}

<|endoftext|>


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

extern crate git_together;

use std::env;
use std::process::Command;

use git_together::GitTogether;
use git_together::errors::*;

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

        match *args.as_slice() {
            ["with"] => {
                println!("{} {}",
                         option_env!("CARGO_PKG_NAME")
                             .unwrap_or("git-together"),
                         option_env!("CARGO_PKG_VERSION")
                             .unwrap_or("unknown version"));

                let gt = GitTogether::new()?;

                let authors = gt.all_authors()?;
                let mut sorted: Vec<_> = authors.iter().collect();
                sorted.sort_by(|a, b| a.0.cmp(b.0));

                for (initials, author) in sorted {
                    println!("{}: {}", initials, author);
                }
            }
            ["with", ref inits..] if inits.contains(&"--clear") => {
                let mut gt = GitTogether::new()?;

                let _ = gt.set_active(&[]);
            }
            ["with", ref inits..] => {
                let mut gt = GitTogether::new()?;

                let authors = gt.set_active(inits)?;
                for author in authors {
                    println!("{}", author);
                }
            }
            [sub_cmd, ref rest..] if ["commit", "merge", "revert"]
                .contains(&sub_cmd) => {
                let mut gt = GitTogether::new()?;

                if sub_cmd == "merge" {
                    env::set_var("GIT_TOGETHER_NO_SIGNOFF", "1");
                }

                let mut cmd = Command::new("git");
                let cmd = cmd.arg(sub_cmd);
                let cmd = gt.signoff(cmd)?;
                let cmd = cmd.args(rest);

                let status = cmd.status()
                    .chain_err(|| "failed to execute process")?;
                if status.success() {
                    gt.rotate_active()?;
                }
            }
            [ref args..] => {
                Command::new("git").args(args)
                    .status()
                    .chain_err(|| "failed to execute process")?;
            }
        };

        Ok(())
    })
}

fn run<F>(f: F)
    where F: Fn() -> Result<()>
{
    if let Err(e) = f() {
        println!("error: {}", e);

        for e in e.iter().skip(1) {
            println!("caused by: {}", e);
        }

        if let Some(backtrace) = e.backtrace() {
            println!("backtrace: {:?}", backtrace);
        }

        std::process::exit(1);
    }
}
<commit_msg>simplify handling --clear command line arg<commit_after>#![feature(advanced_slice_patterns, slice_patterns)]

extern crate git_together;

use std::env;
use std::process::Command;

use git_together::GitTogether;
use git_together::errors::*;

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

        match *args.as_slice() {
            ["with"] => {
                println!("{} {}",
                         option_env!("CARGO_PKG_NAME")
                             .unwrap_or("git-together"),
                         option_env!("CARGO_PKG_VERSION")
                             .unwrap_or("unknown version"));

                let gt = GitTogether::new()?;

                let authors = gt.all_authors()?;
                let mut sorted: Vec<_> = authors.iter().collect();
                sorted.sort_by(|a, b| a.0.cmp(b.0));

                for (initials, author) in sorted {
                    println!("{}: {}", initials, author);
                }
            }
            ["with", "--clear"] => {
                let mut gt = GitTogether::new()?;

                let _ = gt.set_active(&[]);
            }
            ["with", ref inits..] => {
                let mut gt = GitTogether::new()?;

                let authors = gt.set_active(inits)?;
                for author in authors {
                    println!("{}", author);
                }
            }
            [sub_cmd, ref rest..] if ["commit", "merge", "revert"]
                .contains(&sub_cmd) => {
                let mut gt = GitTogether::new()?;

                if sub_cmd == "merge" {
                    env::set_var("GIT_TOGETHER_NO_SIGNOFF", "1");
                }

                let mut cmd = Command::new("git");
                let cmd = cmd.arg(sub_cmd);
                let cmd = gt.signoff(cmd)?;
                let cmd = cmd.args(rest);

                let status = cmd.status()
                    .chain_err(|| "failed to execute process")?;
                if status.success() {
                    gt.rotate_active()?;
                }
            }
            [ref args..] => {
                Command::new("git").args(args)
                    .status()
                    .chain_err(|| "failed to execute process")?;
            }
        };

        Ok(())
    })
}

fn run<F>(f: F)
    where F: Fn() -> Result<()>
{
    if let Err(e) = f() {
        println!("error: {}", e);

        for e in e.iter().skip(1) {
            println!("caused by: {}", e);
        }

        if let Some(backtrace) = e.backtrace() {
            println!("backtrace: {:?}", backtrace);
        }

        std::process::exit(1);
    }
}
<|endoftext|>


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

use std::collections::{HashMap, HashSet};
use std::env;
use std::io::{Write, Read};
use std::process::{Command, Stdio};

extern crate crates_index;
extern crate tiny_http;

static INDEX_LOCAL_PATH: &'static str = "crates.io-index";

fn build_dot(crate_name: &str, dep_map: &HashMap<String, Vec<String>>) -> Vec<u8> {
    let mut crate_names = vec![crate_name];

    let mut dot = String::new();
    dot.push_str("digraph graphname {");

    // Which dependencies we've already seen
    let mut seen_set = HashSet::new();

    while let Some(crate_name) = crate_names.pop() {
        if seen_set.contains(crate_name as &str) {
            continue;
        }
        seen_set.insert(crate_name);
        for crate_dep in dep_map.get(crate_name).unwrap() {
            dot.push_str(&format!("{} -> {};", crate_name.replace("-", "_"), crate_dep.replace("-", "_")));
            if !seen_set.contains(crate_dep as &str) {
                crate_names.push(crate_dep);
            }
        }
    }
    dot.push_str("}");

    let child = Command::new("dot").arg("-Tpng").stdin(Stdio::piped()).stdout(Stdio::piped()).spawn().unwrap();
    {
        child.stdin.unwrap().write_all(dot.as_bytes()).unwrap();
    }

    let mut ret = vec![];
    child.stdout.unwrap().read_to_end(&mut ret).unwrap();
    ret
}

fn main() {
    let index = crates_index::CratesIndex::new(INDEX_LOCAL_PATH.into());
    if !index.exists() {
        println!("Cloning crates.io-index");
        index.clone_index();
    }

    let dep_map = index.dependency_map();

    let port = match env::var("PORT") {
        Ok(p) => p.parse::<u16>().unwrap(),
        Err(..) => 8000,
    };

    let server = tiny_http::ServerBuilder::new().with_port(port).build().unwrap();

    println!("Server listening on port {}", port);
    for req in server.incoming_requests() {
        let response = {
            let crate_name = req.get_url().trim_left_matches("/");
            if dep_map.get(crate_name).is_some() {
                let data = build_dot(crate_name, &dep_map);
                let res = tiny_http::Response::from_data(data);
                res.with_header("Content-Type: image/png".parse::<tiny_http::Header>().unwrap())
            } else {
                tiny_http::Response::from_string("could not find crate")
            }
        };
        req.respond(response);
    }
}
<commit_msg>Clean up valid response generation<commit_after>// Copyright 2015 Corey Farwell
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::{HashMap, HashSet};
use std::env;
use std::io::{Write, Read};
use std::process::{Command, Stdio};

extern crate crates_index;
extern crate tiny_http;

static INDEX_LOCAL_PATH: &'static str = "crates.io-index";

fn build_dot(crate_name: &str, dep_map: &HashMap<String, Vec<String>>) -> Vec<u8> {
    let mut crate_names = vec![crate_name];

    let mut dot = String::new();
    dot.push_str("digraph graphname {");

    // Which dependencies we've already seen
    let mut seen_set = HashSet::new();

    while let Some(crate_name) = crate_names.pop() {
        if seen_set.contains(crate_name as &str) {
            continue;
        }
        seen_set.insert(crate_name);
        for crate_dep in dep_map.get(crate_name).unwrap() {
            dot.push_str(&format!("{} -> {};", crate_name.replace("-", "_"), crate_dep.replace("-", "_")));
            if !seen_set.contains(crate_dep as &str) {
                crate_names.push(crate_dep);
            }
        }
    }
    dot.push_str("}");

    let child = Command::new("dot").arg("-Tpng").stdin(Stdio::piped()).stdout(Stdio::piped()).spawn().unwrap();
    {
        child.stdin.unwrap().write_all(dot.as_bytes()).unwrap();
    }

    let mut ret = vec![];
    child.stdout.unwrap().read_to_end(&mut ret).unwrap();
    ret
}

fn main() {
    let index = crates_index::CratesIndex::new(INDEX_LOCAL_PATH.into());
    if !index.exists() {
        println!("Cloning crates.io-index");
        index.clone_index();
    }

    let dep_map = index.dependency_map();

    let port = match env::var("PORT") {
        Ok(p) => p.parse::<u16>().unwrap(),
        Err(..) => 8000,
    };

    let server = tiny_http::ServerBuilder::new().with_port(port).build().unwrap();

    println!("Server listening on port {}", port);
    for req in server.incoming_requests() {
        let response = {
            let crate_name = req.get_url().trim_left_matches("/");
            if dep_map.get(crate_name).is_some() {
                let data = build_dot(crate_name, &dep_map);
                let content_type_header = "Content-Type: image/png".parse::<tiny_http::Header>().unwrap();
                tiny_http::Response::from_data(data).with_header(content_type_header)
            } else {
                tiny_http::Response::from_string("could not find crate")
            }
        };
        req.respond(response);
    }
}
<|endoftext|>


<commit_before>#![feature(env, path)]
extern crate git2;

use std::cell::RefCell;
use std::collections::HashMap;
use std::env::args;
use git2::{Branch, BranchType, Commit, ResetType, ObjectType, Oid, Repository, Signature, Tree};

fn main() {
    for path_str in args().skip(1) {
        let repo = get_repository(&path_str);
        let mut store: HashMap<Oid, Data> = HashMap::new();
        let mut roots = Vec::new();
        for branch in get_branches(&repo).into_iter() {
            populate_from_branch(branch, &repo, &mut store, &mut roots)
        }
        for data in store.values() {
            for parent in data.commit.parents() {
                store[parent.id()].children.borrow_mut().push(data.commit.id())
            }
        }
        for oid in roots.iter() {
            let tree = repo.find_tree(repo.find_commit(*oid).unwrap().tree_id()).unwrap();
            rebuild(*oid, &repo, &tree, &store);
        }
        for branch in get_branches(&repo).into_iter() {
            let new_oid = store[branch.get().target().unwrap()].new_commit.borrow().as_ref().unwrap().id();
            if !branch.is_head() {
                let new_commit = repo.find_commit(new_oid).unwrap();
                repo.branch(branch.name().unwrap().unwrap(), &new_commit, true, None, None).unwrap();
            } else {
                let new_commit = repo.find_object(new_oid, Some(ObjectType::Commit)).unwrap();
                repo.reset(&new_commit, ResetType::Hard, None, None, None).unwrap();
            }
        }
    }
}

fn get_repository(path_str: &str) -> Repository {
    match Repository::init(&Path::new(path_str)) {
        Ok(repo) => repo,
        Err(e) => panic!("failed to init `{}`: {}", path_str, e),
    }
}

fn get_branches<'a>(repo: &'a Repository) -> Vec<Branch<'a>> {
    repo.branches(Some(BranchType::Local)).unwrap().map(|tup| tup.0).collect()
}

fn populate_from_branch<'a>(branch: Branch<'a>, repo: &'a Repository, store: &mut HashMap<Oid, Data<'a>>, roots: &mut Vec<Oid>) {
    populate(repo.find_commit(branch.into_reference().target().unwrap()).unwrap(), store, roots);
}

fn populate<'a>(commit: Commit<'a>, store: &mut HashMap<Oid, Data<'a>>, roots: &mut Vec<Oid>) {
    let oid = commit.id();
    if !store.contains_key(&oid) {
        store.insert(commit.id(), Data::new(commit));
    }
    if (&mut store[oid]).commit.parents().next().is_none() {
        roots.push(oid);
    } else {
        let parents: Vec<Commit> = (&mut store[oid]).commit.parents().collect();
        for parent in parents.into_iter() {
            populate(parent, store, roots);
        }
    }
}

fn rebuild<'a>(oid: Oid, repo: &'a Repository, tree: &Tree<'a>, store: &'a HashMap<Oid, Data<'a>>) {
    let ref data = store[oid];
    let is_rebuilt = |&: c: Commit, store: &HashMap<Oid, Data>| {
        store[c.id()].new_commit.borrow().is_some()
    };
    if data.new_commit.borrow().is_none() && data.commit.parents().all(|c| is_rebuilt(c, store)) {
        if data.commit.author().name().unwrap() != "Anonymous" &&
           data.commit.author().email().unwrap() != "anon@ymo.us" &&
           data.commit.committer().name().unwrap() != "Anonymous" &&
           data.commit.committer().email().unwrap() != "anon@ymo.us" {
               let author = Signature::new("Anonymous", "anon@ymo.us", &data.commit.author().when());
               let committer = Signature::new("Anonymous", "anon@ymo.us", &data.commit.committer().when());
               let message = data.commit.message().unwrap();
               let parents_vals = get_parents(oid, repo, store);
               let parents: Vec<_> = parents_vals.iter().map(|commit| commit).collect();
               let new_oid = repo.commit(None, &author.unwrap(), &committer.unwrap(), message,
                            tree, &parents[]).unwrap();
               {
                   let mut new_commit = data.new_commit.borrow_mut();
                   *new_commit = Some(repo.find_commit(new_oid).unwrap());
               }
               let new_tree = repo.find_tree(repo.find_commit(new_oid).unwrap().tree_id()).unwrap();
               for child_oid in data.children.borrow().iter() {
                   rebuild(*child_oid, repo, &new_tree, store);
               }
        } else {
            for child_oid in data.children.borrow().iter() {
                rebuild(*child_oid, repo, tree, store);
            }
        }
    }
}

fn get_parents<'a>(oid: Oid, repo: &'a Repository, store: &'a HashMap<Oid, Data<'a>>) -> Vec<Commit<'a>> {
    store[oid].commit.parents().map(|commit| {
        repo.find_commit(store[commit.id()].new_commit.borrow().as_ref().unwrap().id()).unwrap()
    }).collect()
}

struct Data<'a> {
    commit: Commit<'a>,
    children: RefCell<Vec<Oid>>,
    new_commit: RefCell<Option<Commit<'a>>>,
}

impl<'a> Data<'a> {
    pub fn new(commit: Commit<'a>) -> Data {
        Data {
            commit: commit,
            children: RefCell::new(Vec::new()),
            new_commit: RefCell::new(None),
        }
    }
}
<commit_msg>Fixed issue with lifetime bounds.<commit_after>#![feature(env, old_path)]
extern crate git2;

use std::cell::RefCell;
use std::collections::HashMap;
use std::env::args;
use git2::{Branch, BranchType, Commit, ResetType, ObjectType, Oid, Repository, Signature, Tree};

fn main() {
    for path_str in args().skip(1) {
        let repo = get_repository(&path_str);
        let mut store: HashMap<Oid, Data> = HashMap::new();
        let mut roots = Vec::new();
        for branch in get_branches(&repo).into_iter() {
            populate_from_branch(branch, &repo, &mut store, &mut roots)
        }
        for data in store.values() {
            for parent in data.commit.parents() {
                store[parent.id()].children.borrow_mut().push(data.commit.id())
            }
        }
        for oid in roots.iter() {
            let tree = repo.find_tree(repo.find_commit(*oid).unwrap().tree_id()).unwrap();
            rebuild(*oid, &repo, &tree, &store);
        }
        for branch in get_branches(&repo).into_iter() {
            let new_oid = store[branch.get().target().unwrap()].new_commit.borrow().as_ref().unwrap().id();
            if !branch.is_head() {
                let new_commit = repo.find_commit(new_oid).unwrap();
                repo.branch(branch.name().unwrap().unwrap(), &new_commit, true, None, None).unwrap();
            } else {
                let new_commit = repo.find_object(new_oid, Some(ObjectType::Commit)).unwrap();
                repo.reset(&new_commit, ResetType::Hard, None, None, None).unwrap();
            }
        }
    }
}

fn get_repository(path_str: &str) -> Repository {
    match Repository::init(&Path::new(path_str)) {
        Ok(repo) => repo,
        Err(e) => panic!("failed to init `{}`: {}", path_str, e),
    }
}

fn get_branches<'a>(repo: &'a Repository) -> Vec<Branch<'a>> {
    repo.branches(Some(BranchType::Local)).unwrap().map(|tup| tup.0).collect()
}

fn populate_from_branch<'a>(branch: Branch<'a>, repo: &'a Repository, store: &mut HashMap<Oid, Data<'a>>, roots: &mut Vec<Oid>) {
    populate(repo.find_commit(branch.into_reference().target().unwrap()).unwrap(), store, roots);
}

fn populate<'a>(commit: Commit<'a>, store: &mut HashMap<Oid, Data<'a>>, roots: &mut Vec<Oid>) {
    let oid = commit.id();
    if !store.contains_key(&oid) {
        store.insert(commit.id(), Data::new(commit));
    }
    if (&mut store[oid]).commit.parents().next().is_none() {
        roots.push(oid);
    } else {
        let parents: Vec<Commit> = (&mut store[oid]).commit.parents().collect();
        for parent in parents.into_iter() {
            populate(parent, store, roots);
        }
    }
}

fn rebuild<'a>(oid: Oid, repo: &'a Repository, tree: &Tree<'a>, store: &HashMap<Oid, Data<'a>>) {
    let ref data = store[oid];
    let is_rebuilt = |&: c: Commit, store: &HashMap<Oid, Data>| {
        store[c.id()].new_commit.borrow().is_some()
    };
    if data.new_commit.borrow().is_none() && data.commit.parents().all(|c| is_rebuilt(c, store)) {
        if data.commit.author().name().unwrap() != "Anonymous" &&
           data.commit.author().email().unwrap() != "anon@ymo.us" &&
           data.commit.committer().name().unwrap() != "Anonymous" &&
           data.commit.committer().email().unwrap() != "anon@ymo.us" {
               let author = Signature::new("Anonymous", "anon@ymo.us", &data.commit.author().when());
               let committer = Signature::new("Anonymous", "anon@ymo.us", &data.commit.committer().when());
               let message = data.commit.message().unwrap();
               let parents_vals = get_parents(oid, repo, store);
               let parents: Vec<_> = parents_vals.iter().map(|commit| commit).collect();
               let new_oid = repo.commit(None, &author.unwrap(), &committer.unwrap(), message,
                            tree, &parents).unwrap();
               {
                   let mut new_commit = data.new_commit.borrow_mut();
                   *new_commit = Some(repo.find_commit(new_oid).unwrap());
               }
               let new_tree = repo.find_tree(repo.find_commit(new_oid).unwrap().tree_id()).unwrap();
               for child_oid in data.children.borrow().iter() {
                   rebuild(*child_oid, repo, &new_tree, store);
               }
        } else {
            for child_oid in data.children.borrow().iter() {
                rebuild(*child_oid, repo, tree, store);
            }
        }
    }
}

fn get_parents<'a>(oid: Oid, repo: &'a Repository, store: &HashMap<Oid, Data<'a>>) -> Vec<Commit<'a>> {
    store[oid].commit.parents().map(|commit| {
        repo.find_commit(store[commit.id()].new_commit.borrow().as_ref().unwrap().id()).unwrap()
    }).collect()
}

struct Data<'a> {
    commit: Commit<'a>,
    children: RefCell<Vec<Oid>>,
    new_commit: RefCell<Option<Commit<'a>>>,
}

impl<'a> Data<'a> {
    pub fn new(commit: Commit<'a>) -> Data {
        Data {
            commit: commit,
            children: RefCell::new(Vec::new()),
            new_commit: RefCell::new(None),
        }
    }
}
<|endoftext|>


<commit_before>extern crate regex;
extern crate clap;
extern crate walkdir;
extern crate ansi_term;

use std::io::Write;

macro_rules! println_stderr(
    ($($arg:tt)*) => { {
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

use clap::{Arg, App, AppSettings};
use regex::Regex;
use walkdir::WalkDir;
use ansi_term::Colour::Blue;

use std::env;
use std::path::PathBuf;
use std::ops::Deref;

fn find(rgx: Regex, dirs: Vec<PathBuf>, paint: bool) {
    let painter;
    let replacement = if paint {
        painter = Blue.paint("$search");
        painter.deref()
    } else {
        "$search"
    };

    for d in dirs.iter() {
        let wkd = WalkDir::new(d);

        for f in wkd.into_iter() {
            if f.is_err() {
                println_stderr!("{}", f.err().unwrap());
                continue;
            }

            let entry = f.unwrap();
            let path = entry.path();
            let s = path.to_str().unwrap();

            if rgx.is_match(s) {
                let canon_path = std::fs::canonicalize(path).unwrap();
                let final_s = canon_path.to_str().unwrap();
                let display = rgx.replace_all(final_s, replacement);
                println!("{}", display);
            }
        }
    }
}

fn main() {
    let matches = App::new("fnd, a simpler way to find files")
        .version("0.2.0")
        .author("Mathew Robinson <mrobinson@praelatus.io>")
        .about("Finds files")
        .setting(AppSettings::TrailingVarArg)
        .arg(Arg::with_name("color")
            .long("no_color")
            .short("nc")
            .help("When specified will not highlight matches with ansi \
                   term color codes this is useful when piping output"))
        .arg(Arg::with_name("REGEX")
            .required(true)
            .index(1)
            .help("The REGEX to search for, defaults to fuzzy finding"))
        .arg(Arg::with_name("DIRS")
            .multiple(true)
            .help("Where to search for SEARCH")
            .default_value("."))
        .get_matches();

    let search = matches.value_of("REGEX").unwrap();
    let dirs: Vec<&str> = matches.values_of("DIRS").unwrap().collect();

    let mut d: Vec<PathBuf> = dirs.iter()
        .map(|x| {
            if *x == "." {
                return env::current_dir().unwrap().to_path_buf();
            }

            PathBuf::from(x)
        })
        .collect();

    d = d.iter()
        .map(|x| std::fs::canonicalize(x).unwrap())
        .collect();

    let mut re = "(?P<search>".to_string();
    re.push_str(search);
    re.push_str(")");

    let rgx = Regex::new(&re).unwrap();

    find(rgx, d, !matches.is_present("color"));
}
<commit_msg>make error handling more idiomatic and cleaner<commit_after>extern crate regex;
extern crate clap;
extern crate walkdir;
extern crate ansi_term;

use std::io::Write;

macro_rules! println_stderr(
    ($($arg:tt)*) => { {
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

use clap::{Arg, App, AppSettings};
use regex::Regex;
use walkdir::WalkDir;
use ansi_term::Colour::Blue;

use std::env;
use std::path::PathBuf;
use std::ops::Deref;

fn find(rgx: Regex, dirs: Vec<PathBuf>, paint: bool) {
    let painter;
    let replacement = if paint {
        painter = Blue.paint("$search");
        painter.deref()
    } else {
        "$search"
    };

    for d in dirs.iter() {
        let wkd = WalkDir::new(d);

        for f in wkd.into_iter() {
            let entry;
            match f {
                Ok(e) => entry = e,
                Err(err) => {
                    println_stderr!("{}", err);
                    continue;
                }
            }

            let entry = f.unwrap();
            let path = entry.path();
            let s = path.to_str().unwrap();

            if rgx.is_match(s) {
                let canon_path = std::fs::canonicalize(path).unwrap();
                let final_s = canon_path.to_str().unwrap();
                let display = rgx.replace_all(final_s, replacement);
                println!("{}", display);
            }
        }
    }
}

fn main() {
    let matches = App::new("fnd, a simpler way to find files")
        .version("0.2.0")
        .author("Mathew Robinson <mrobinson@praelatus.io>")
        .about("Finds files")
        .setting(AppSettings::TrailingVarArg)
        .arg(Arg::with_name("color")
            .long("no_color")
            .short("nc")
            .help("When specified will not highlight matches with ansi \
                   term color codes this is useful when piping output"))
        .arg(Arg::with_name("REGEX")
            .required(true)
            .index(1)
            .help("The REGEX to search for, defaults to fuzzy finding"))
        .arg(Arg::with_name("DIRS")
            .multiple(true)
            .help("Where to search for SEARCH")
            .default_value("."))
        .get_matches();

    let search = matches.value_of("REGEX").unwrap();
    let dirs: Vec<&str> = matches.values_of("DIRS").unwrap().collect();

    let mut d: Vec<PathBuf> = dirs.iter()
        .map(|x| {
            if *x == "." {
                return env::current_dir().unwrap().to_path_buf();
            }

            PathBuf::from(x)
        })
        .collect();

    d = d.iter()
        .map(|x| std::fs::canonicalize(x).unwrap())
        .collect();

    let mut re = "(?P<search>".to_string();
    re.push_str(search);
    re.push_str(")");

    let rgx = Regex::new(&re).unwrap();

    find(rgx, d, !matches.is_present("color"));
}
<|endoftext|>


<commit_before>extern crate getopts;
extern crate xmltree;

mod utils;

use getopts::{Options, Matches};
use std::env;
use xmltree::Element;

use utils::{log_print, LogLevel};

use std::cmp::{Ord, Ordering};

#[derive(Debug, Eq, PartialEq, PartialOrd)]
struct Attr<'attr> {
    key: &'attr str,
    value: &'attr str,
}

impl<'attr> Attr<'attr> {
    fn new(data: (&'attr str, &'attr str)) -> Attr<'attr> {
        Attr {
            key: data.0,
            value: data.1,
        }
    }

    fn print(&self) -> String {
        format!("{}=\"{}\"", self.key, self.value)
    }
}

impl<'attr> Ord for Attr<'attr> {
    fn cmp(&self, rhs: &Attr<'attr>) -> Ordering {
        self.key.cmp(rhs.key)
    }
}

#[derive(Debug)]
struct Tag<'tag> {
    el: &'tag Element,
    attrs: Vec<Attr<'tag>>,
}

impl<'tag> PartialEq for Tag<'tag> {
    fn eq(&self, rhs: &Tag<'tag>) -> bool {
        match self.el.text {
            Some(_) => self.el.text == rhs.el.text,
            None => self.el.name == rhs.el.name && self.attrs == rhs.attrs,
        }
    }
}

impl<'tag> Tag<'tag> {
    fn new(el: &'tag Element) -> Tag<'tag> {

        let mut ret_val: Tag<'tag> = Tag {
            el: el,
            attrs: Vec::new(),
        };

        for attr in &el.attributes {
            let attr: Attr<'tag> = Attr::<'tag>::new((attr.0, attr.1));
            ret_val.attrs.push(attr);
        }

        ret_val.attrs.sort();

        ret_val
    }

    fn print(&self) -> String {
        let mut ret_val: String = String::from("<");

        ret_val.push_str(&self.el.name);

        for attr in &self.attrs {
            ret_val.push(' ');
            ret_val.push_str(&attr.print());
        }

        ret_val.push_str(">");

        ret_val
    }
}

fn compare_nodes(el_x: &Element, el_y: &Element, indent: &mut usize) {

    let tag_x: Tag = Tag::new(el_x);
    println!("{}", tag_x.print());

    if !el_x.children.is_empty() {
        for child in &el_x.children {
            compare_nodes(child, child, indent);
        }
    } else {

    }
}

fn main() {

    let args: Vec<String> = env::args().collect();
    let program: String = args[0].clone();

    let mut opts: Options = Options::new();
    opts.optopt("h", "help", "Show help page", "");
    //opts.optopt("f", "output-file", "Save result to file", "");
    //opts.optopt("v", "version", "Show version", "");

    let matches: Matches = match opts.parse(&args[1..]) {
        Ok(v) => v,
        Err(_) => {
            utils::print_usage(&program, &opts);
            return;
        }
    };

    if matches.opt_present("h") {
        utils::print_usage(&program, &opts);
        return;
    }

    if matches.free.len() < 2 {
        utils::print_usage(&program, &opts);
        return;
    }

    let content_x: String = match utils::read_file_content(&matches.free[0]) {
        Ok(v) => v,
        Err(e) => {
            println!("{}", e);
            return;
        }
    };

    let content_y: String = match utils::read_file_content(&matches.free[1]) {
        Ok(v) => v,
        Err(e) => {
            println!("{}", e);
            return;
        }
    };

    let el_x: Element = match Element::parse(content_x.as_bytes()) {
        Ok(el) => el,
        Err(_) => {
            log_print(LogLevel::ERROR, "Unable to parse XML document.");
            return;
        }
    };

    let el_y: Element = match Element::parse(content_y.as_bytes()) {
        Ok(el) => el,
        Err(_) => {
            log_print(LogLevel::ERROR, "Unable to parse XML document.");
            return;
        }
    };

    let mut indent: usize = 0;

    compare_nodes(&el_x, &el_y, &mut indent);
}
<commit_msg>Introduce print_diff fn. .print and .print_end fncs are added fot Tag struct<commit_after>extern crate getopts;
extern crate xmltree;

mod utils;

use getopts::{Options, Matches};
use std::env;
use xmltree::Element;

use utils::{log_print, LogLevel};

use std::cmp::{Ord, Ordering};

#[derive(Debug, Eq, PartialEq, PartialOrd)]
struct Attr<'attr> {
    key: &'attr str,
    value: &'attr str,
}

impl<'attr> Attr<'attr> {
    fn new(data: (&'attr str, &'attr str)) -> Attr<'attr> {
        Attr {
            key: data.0,
            value: data.1,
        }
    }

    fn print(&self) -> String {
        format!("{}=\"{}\"", self.key, self.value)
    }
}

impl<'attr> Ord for Attr<'attr> {
    fn cmp(&self, rhs: &Attr<'attr>) -> Ordering {
        self.key.cmp(rhs.key)
    }
}

#[derive(Debug)]
struct Tag<'tag> {
    el: &'tag Element,
    attrs: Vec<Attr<'tag>>,
}

impl<'tag> PartialEq for Tag<'tag> {
    fn eq(&self, rhs: &Tag<'tag>) -> bool {
        match self.el.text {
            Some(_) => self.el.text == rhs.el.text,
            None => self.el.name == rhs.el.name && self.attrs == rhs.attrs,
        }
    }
}

impl<'tag> Tag<'tag> {
    fn new(el: &'tag Element) -> Tag<'tag> {

        let mut ret_val: Tag<'tag> = Tag {
            el: el,
            attrs: Vec::new(),
        };

        for attr in &el.attributes {
            let attr: Attr<'tag> = Attr::<'tag>::new((attr.0, attr.1));
            ret_val.attrs.push(attr);
        }

        ret_val.attrs.sort();

        ret_val
    }

    fn print(&self) -> String {
        let mut ret_val: String = String::from("<");

        ret_val.push_str(&self.el.name);

        for attr in &self.attrs {
            ret_val.push(' ');
            ret_val.push_str(&attr.print());
        }

        ret_val.push_str(">");

        if let Some(ref text) = self.el.text {
            ret_val.push_str(text);
            ret_val.push_str(&format!("</{}>", self.el.name));
        }

        ret_val
    }

    fn print_end(&self) -> Option<String> {
        if self.el.text.is_none() {
            Some(format!("</{}>", self.el.name))
        } else {
            None
        }
    }
}

fn print_diff(tag_x: &Tag, tag_y: &Tag, indent: &mut usize) -> String {
    "".into()
}

fn compare_nodes<'cn>(tag_x: &Tag<'cn>, tag_y: &Tag<'cn>, indent: &mut usize) {

    if tag_x == tag_y {
        let indent_str = utils::repeat_char(' ', *indent);
        let start_tag = tag_x.print();
        let end_tag = tag_x.print_end();

        *indent += 2;

        println!("{}{}", indent_str, start_tag);

        for child_x in &tag_x.el.children {
            let tag_child_x: Tag = Tag::new(child_x);

            match tag_y.el.children.iter().find(|e| e.name == child_x.name) {
                Some(el) => compare_nodes(&tag_child_x, &Tag::new(el), indent),
                None => {}
            }
        }

        if let Some(v) = end_tag {
            println!("{}{}", indent_str, v)
        }

        *indent -= 2;

    } else {
        print_diff(tag_x, tag_y, indent);
    }

}

fn main() {

    let args: Vec<String> = env::args().collect();
    let program: String = args[0].clone();

    let mut opts: Options = Options::new();
    opts.optopt("h", "help", "Show help page", "");
    //opts.optopt("f", "output-file", "Save result to file", "");
    //opts.optopt("v", "version", "Show version", "");

    let matches: Matches = match opts.parse(&args[1..]) {
        Ok(v) => v,
        Err(_) => {
            utils::print_usage(&program, &opts);
            return;
        }
    };

    if matches.opt_present("h") {
        utils::print_usage(&program, &opts);
        return;
    }

    if matches.free.len() < 2 {
        utils::print_usage(&program, &opts);
        return;
    }

    let content_x: String = match utils::read_file_content(&matches.free[0]) {
        Ok(v) => v,
        Err(e) => {
            println!("{}", e);
            return;
        }
    };

    let content_y: String = match utils::read_file_content(&matches.free[1]) {
        Ok(v) => v,
        Err(e) => {
            println!("{}", e);
            return;
        }
    };

    let el_x: Element = match Element::parse(content_x.as_bytes()) {
        Ok(el) => el,
        Err(_) => {
            log_print(LogLevel::ERROR, "Unable to parse XML document.");
            return;
        }
    };

    let el_y: Element = match Element::parse(content_y.as_bytes()) {
        Ok(el) => el,
        Err(_) => {
            log_print(LogLevel::ERROR, "Unable to parse XML document.");
            return;
        }
    };

    let mut indent: usize = 0;

    compare_nodes(&Tag::new(&el_x), &Tag::new(&el_y), &mut indent);
}
<|endoftext|>


<commit_before>extern crate crypto;
extern crate regex;
extern crate rustc_serialize;

use crypto::md5::Md5;
use crypto::digest::Digest;

use rustc_serialize::{json, Decodable, Encodable};

use std::collections::HashMap;
use std::ffi::OsString;
use std::fs::{self, DirEntry, File};
use std::io::prelude::*;
use std::path::Path;
use std::process::{self, Command};

trait Stringable {
    fn to_string(self) -> String;
}

impl Stringable for DirEntry {
    fn to_string(self) -> String {
        self.path().as_path().to_str().unwrap().to_owned()
    }
}

impl Stringable for OsString {
    fn to_string(self) -> String {
        self.as_os_str().to_str().unwrap().to_owned()
    }
}

const INDEX_PATH: &'static str = "blaze/file_index.json";
const CONFIG_PATH: &'static str = "blaze/lint_config.json";

// Map from path to hash
#[derive(RustcDecodable, RustcEncodable, Default)]
pub struct Index {
    files: HashMap<String, String>,
}

#[derive(RustcDecodable)]
pub struct Lint {
    name: String,
    command: String,
    args: Vec<String>,
}

impl Lint {
    fn command(&self, paths: &Vec<String>) -> Command {
        let mut c = Command::new(&self.command);
        for arg in &self.args {
            c.arg(arg);
        }
        for path in paths {
            c.arg(path);
        }
        c
    }

    // runs this lint on all given files, return all the clean files
    fn resolve(&self, files: Vec<String>) -> Vec<String> {
        let output = &self.command(&files)
                          .output()
                          .unwrap_or_else(|_| {
                              println!("{} not installed", self.name);
                              process::exit(1);
                          });
        let stdout = String::from_utf8_lossy(&output.stdout);
        if stdout != "" {
            println!("{}", stdout);
        }
        let stderr = String::from_utf8_lossy(&output.stderr);
        if stderr != "" {
            println!("{}", stderr);
        }
        files.into_iter()
             .filter(|file| {
                 let re = regex::Regex::new(&format!(".*{}.*", file)).unwrap();
                 !re.is_match(&stdout) && !re.is_match(&stderr)
             })
             .collect()
    }
}

#[derive(RustcDecodable)]
pub struct LintConfig {
    // filetypes is a map from extension to lints
    filetypes: HashMap<String, Vec<Lint>>,
    global_ignore: Vec<String>,
}

impl Default for LintConfig {
    fn default() -> Self {
        println!("No {} file was found", CONFIG_PATH);
        process::exit(1);
    }
}

fn main() {
    let lint_config: LintConfig = load(CONFIG_PATH);
    let mut new_index = Index::default();

    for (extension, lints) in &lint_config.filetypes {
        let mut files = dirty_files(extension, &lint_config.global_ignore, &mut new_index);

        for lint in lints.iter() {
            if !files.is_empty() {
                println!("Running {} on {} files", lint.name, files.len());
                files = lint.resolve(files);
            }
        }

        while let Some(file) = files.pop() {
            let file_hash = hash(&file);
            new_index.files.insert(file, file_hash);
        }
    }

    save(INDEX_PATH, &new_index);
}

fn dirty_files(extension: &String, ignore: &Vec<String>, new_index: &mut Index) -> Vec<String> {
    let old_index: Index = load(INDEX_PATH);
    let mut dirty_files = vec![];

    let mut dirs_to_visit: Vec<String> = vec![".".to_owned()];
    while let Some(dir) = dirs_to_visit.pop() {

        for entry in fs::read_dir(dir).unwrap() {
            let dir_entry = entry.unwrap();

            let file_name = dir_entry.file_name().to_string();
            let file_extension = match dir_entry.path().extension() {
                Some(ext) => ext.to_str().unwrap().to_owned(),
                None => "".to_owned(),
            };

            if ignore.contains(&file_name) {
                continue;
            }

            let path = dir_entry.to_string();

            if (fs::metadata(path.clone()).unwrap()).is_dir() {
                dirs_to_visit.push(path);
                continue;
            }

            if &file_extension != extension {
                continue;
            }

            let file_hash = hash(&path);
            if old_index.files.get(&path) != Some(&file_hash) {
                dirty_files.push(path);
            } else {
                new_index.files.insert(path, file_hash);
            }
        }

    }
    dirty_files
}

fn hash(path: &String) -> String {
    let mut file = match File::open(path) {
        Err(_) => panic!("couldn't open file to get hash: {}", path),
        Ok(file) => file,
    };
    let mut s = String::new();
    match file.read_to_string(&mut s) {
        Err(_) => panic!("couldn't read file to string: {}", path),
        Ok(_) => (),
    };

    let mut hasher = Md5::new();
    hasher.input(s.as_bytes());
    let mut output = [0; 16]; // Md5 is 16 bytes
    hasher.result(&mut output);
    let temp: &[u8] = &output;
    rustc_serialize::hex::ToHex::to_hex(temp)
}

fn save<P: AsRef<Path>, T: Encodable>(path: P, t: &T) {
    let encoded = json::encode(t).unwrap();
    let mut file = File::create(path).unwrap();
    match write!(file, "{}", encoded) {
        Err(_) => panic!(),
        Ok(_) => (),
    };
}

fn load<P: AsRef<Path>, T: Decodable + Default>(path: P) -> T {
    let mut file = match File::open(path) {
        Err(_) => return T::default(),
        Ok(file) => file,
    };
    let mut s = String::new();
    file.read_to_string(&mut s).unwrap();

    json::decode(&s).expect("Could not decode json")
}
<commit_msg>clippy run<commit_after>extern crate crypto;
extern crate regex;
extern crate rustc_serialize;

use crypto::md5::Md5;
use crypto::digest::Digest;

use rustc_serialize::{json, Decodable, Encodable};

use std::collections::HashMap;
use std::ffi::OsString;
use std::fs::{self, DirEntry, File};
use std::io::prelude::*;
use std::path::Path;
use std::process::{self, Command};

trait Stringable {
    fn to_string(self) -> String;
}

impl Stringable for DirEntry {
    fn to_string(self) -> String {
        self.path().as_path().to_str().unwrap().to_owned()
    }
}

impl Stringable for OsString {
    fn to_string(self) -> String {
        self.as_os_str().to_str().unwrap().to_owned()
    }
}

const INDEX_PATH: &'static str = "blaze/file_index.json";
const CONFIG_PATH: &'static str = "blaze/lint_config.json";

// Map from path to hash
#[derive(RustcDecodable, RustcEncodable, Default)]
pub struct Index {
    files: HashMap<String, String>,
}

#[derive(RustcDecodable)]
pub struct Lint {
    name: String,
    command: String,
    args: Vec<String>,
}

impl Lint {
    fn command(&self, paths: &[String]) -> Command {
        let mut c = Command::new(&self.command);
        for arg in &self.args {
            c.arg(arg);
        }
        for path in paths {
            c.arg(path);
        }
        c
    }

    // runs this lint on all given files, return all the clean files
    fn resolve(&self, files: Vec<String>) -> Vec<String> {
        let output = &self.command(&files)
                          .output()
                          .unwrap_or_else(|_| {
                              println!("{} not installed", self.name);
                              process::exit(1);
                          });
        let stdout = String::from_utf8_lossy(&output.stdout);
        if stdout != "" {
            println!("{}", stdout);
        }
        let stderr = String::from_utf8_lossy(&output.stderr);
        if stderr != "" {
            println!("{}", stderr);
        }
        files.into_iter()
             .filter(|file| {
                 let re = regex::Regex::new(&format!(".*{}.*", file)).unwrap();
                 !re.is_match(&stdout) && !re.is_match(&stderr)
             })
             .collect()
    }
}

#[derive(RustcDecodable)]
pub struct LintConfig {
    // filetypes is a map from extension to lints
    filetypes: HashMap<String, Vec<Lint>>,
    global_ignore: Vec<String>,
}

impl Default for LintConfig {
    fn default() -> Self {
        println!("No {} file was found", CONFIG_PATH);
        process::exit(1);
    }
}

fn main() {
    let lint_config: LintConfig = load(CONFIG_PATH);
    let mut new_index = Index::default();

    for (extension, lints) in &lint_config.filetypes {
        let mut files = dirty_files(extension, &lint_config.global_ignore, &mut new_index);

        for lint in lints.iter() {
            if !files.is_empty() {
                println!("Running {} on {} files", lint.name, files.len());
                files = lint.resolve(files);
            }
        }

        while let Some(file) = files.pop() {
            let file_hash = hash(&file);
            new_index.files.insert(file, file_hash);
        }
    }

    save(INDEX_PATH, &new_index);
}

fn dirty_files(extension: &str, ignore: &[String], new_index: &mut Index) -> Vec<String> {
    let old_index: Index = load(INDEX_PATH);
    let mut dirty_files = vec![];

    let mut dirs_to_visit: Vec<String> = vec![".".to_owned()];
    while let Some(dir) = dirs_to_visit.pop() {

        for entry in fs::read_dir(dir).unwrap() {
            let dir_entry = entry.unwrap();

            let file_name = dir_entry.file_name().to_string();
            let file_extension = match dir_entry.path().extension() {
                Some(ext) => ext.to_str().unwrap().to_owned(),
                None => "".to_owned(),
            };

            if ignore.contains(&file_name) {
                continue;
            }

            let path = dir_entry.to_string();

            if (fs::metadata(path.clone()).unwrap()).is_dir() {
                dirs_to_visit.push(path);
                continue;
            }

            if &file_extension != extension {
                continue;
            }

            let file_hash = hash(&path);
            if old_index.files.get(&path) != Some(&file_hash) {
                dirty_files.push(path);
            } else {
                new_index.files.insert(path, file_hash);
            }
        }

    }
    dirty_files
}

fn hash(path: &str) -> String {
    let mut file = match File::open(path) {
        Err(_) => panic!("couldn't open file to get hash: {}", path),
        Ok(file) => file,
    };
    let mut s = String::new();
    match file.read_to_string(&mut s) {
        Err(_) => panic!("couldn't read file to string: {}", path),
        Ok(_) => (),
    };

    let mut hasher = Md5::new();
    hasher.input(s.as_bytes());
    let mut output = [0; 16]; // Md5 is 16 bytes
    hasher.result(&mut output);
    let temp: &[u8] = &output;
    rustc_serialize::hex::ToHex::to_hex(temp)
}

fn save<P: AsRef<Path>, T: Encodable>(path: P, t: &T) {
    let encoded = json::encode(t).unwrap();
    let mut file = File::create(path).unwrap();
    match write!(file, "{}", encoded) {
        Err(_) => panic!(),
        Ok(_) => (),
    };
}

fn load<P: AsRef<Path>, T: Decodable + Default>(path: P) -> T {
    let mut file = match File::open(path) {
        Err(_) => return T::default(),
        Ok(file) => file,
    };
    let mut s = String::new();
    file.read_to_string(&mut s).unwrap();

    json::decode(&s).expect("Could not decode json")
}
<|endoftext|>


<commit_before>#![feature(std_misc)]
mod models;
mod parser;
mod mayberef;

use std::fs::{File, read_dir};
use std::io::{BufReader, BufRead, Read, Write, stdin};
use std::path::{Path};
use std::collections::HashMap;
use std::collections::hash_map::Entry::*;
use std::ascii::OwnedAsciiExt;
use models::*;

fn visit_tokens<T: Read, F: FnMut(String) -> ()>(reader: BufReader<T>, mut counter: F) {
    for line in reader.lines() {
    	if let Ok(line) = line {
	    	for word in line.split(|c: char| !c.is_alphabetic()) {
	    		if word.len() > 0 {
	    			let word = word.to_string().into_ascii_lowercase();
		    		counter(word);
		    	}
	    	}
	    }
    }
}

fn get_line() -> String {
    let mut stdin = stdin();
    let mut buffer = String::new();
    stdin.read_line(&mut buffer).unwrap();
    buffer
}

fn find_most_common_words(corpus_loc: &str, outfile: &str) {
    let path = Path::new(corpus_loc);
    let mut word_counts = HashMap::new();
    visit_files(path, 100000, &mut |read| visit_tokens(read, &mut |s|
        match (&mut word_counts).entry(s) {
            Vacant(e) => { e.insert(1); },
            Occupied(mut e) => { *e.get_mut() += 1; },
    }));

    let mut counts: Vec<_> = word_counts.into_iter().collect();
    counts.sort_by(|a, b| b.1.cmp(&a.1));

    let mut out = File::create(&Path::new(outfile)).unwrap();
    for &(ref word, count) in &counts[..] {
        out.write_all(format!("{}, {}\n", word, count).as_bytes()).unwrap();
    }

}

fn load_most_common_words(filename: &str) -> Vec<String> {
    let file = File::open(&Path::new(filename)).unwrap();
    let reader = BufReader::new(file);
    reader.lines().map(|line|
        line.unwrap().split(',').next().unwrap().to_string()
    ).collect()
}

fn visit_files<F: FnMut(BufReader<File>) -> ()>(path: &Path, num: usize, mut file_processor: F) {
    let files = read_dir(path);
    for file in files.unwrap().take(num) {
        let path = file.unwrap().path();
        if path.to_str().unwrap().ends_with(".txt") {
            let file = File::open(&path).unwrap();
            let reader = BufReader::new(file);
            file_processor(reader);
        }
    }
}

fn main() {
    const CORPUS_DIR: &'static str = "/home/jamougha/corpus/pg";
    const WORDS: &'static str = "/home/jamougha/corpus/pg/word_counts.csv";
    //find_most_common_words(CORPUS_DIR, WORDS);
    let words = load_most_common_words(WORDS);
    let mut builder = LanguageModelBuilder::new(words);

    let path = Path::new(CORPUS_DIR);

    visit_files(&path, 100000, |read| {
        let mut acc = (&mut builder).new_file();
        visit_tokens(read, |w| (&mut acc).add_word(w));
    });

    let model = builder.build();
    println!("Model loaded");
    loop {
        println!("");
        let input = get_line();
        if input.starts_with(":q") {
            break;
        }

        match parser::parse(input.trim_matches(|c: char| c.is_whitespace()), &model) {
            Ok(word_vec) => {
                let nearest = model.nearest_words(&word_vec);
                println!(" = {:?}", word_vec);
                println!("-------------");
                for word in nearest.iter().take(20) {
                    println!("{:?}, {}", word, word_vec.distance(word));
                }
            }
            Err(e) => println!("{:?}", e)
        }

    }

}
<commit_msg>Use the window width parameter.<commit_after>#![feature(std_misc)]
mod models;
mod parser;
mod mayberef;

use std::fs::{File, read_dir};
use std::io::{BufReader, BufRead, Read, Write, stdin};
use std::path::{Path};
use std::collections::HashMap;
use std::collections::hash_map::Entry::*;
use std::ascii::OwnedAsciiExt;
use models::*;

fn visit_tokens<T: Read, F: FnMut(String) -> ()>(reader: BufReader<T>, mut counter: F) {
    for line in reader.lines() {
    	if let Ok(line) = line {
	    	for word in line.split(|c: char| !c.is_alphabetic()) {
	    		if word.len() > 0 {
	    			let word = word.to_string().into_ascii_lowercase();
		    		counter(word);
		    	}
	    	}
	    }
    }
}

fn get_line() -> String {
    let mut stdin = stdin();
    let mut buffer = String::new();
    stdin.read_line(&mut buffer).unwrap();
    buffer
}

fn find_most_common_words(corpus_loc: &str, outfile: &str) {
    let path = Path::new(corpus_loc);
    let mut word_counts = HashMap::new();
    visit_files(path, 100000, &mut |read| visit_tokens(read, &mut |s|
        match (&mut word_counts).entry(s) {
            Vacant(e) => { e.insert(1); },
            Occupied(mut e) => { *e.get_mut() += 1; },
    }));

    let mut counts: Vec<_> = word_counts.into_iter().collect();
    counts.sort_by(|a, b| b.1.cmp(&a.1));

    let mut out = File::create(&Path::new(outfile)).unwrap();
    for &(ref word, count) in &counts[..] {
        out.write_all(format!("{}, {}\n", word, count).as_bytes()).unwrap();
    }

}

fn load_most_common_words(filename: &str) -> Vec<String> {
    let file = File::open(&Path::new(filename)).unwrap();
    let reader = BufReader::new(file);
    reader.lines().map(|line|
        line.unwrap().split(',').next().unwrap().to_string()
    ).collect()
}

fn visit_files<F: FnMut(BufReader<File>) -> ()>(path: &Path, num: usize, mut file_processor: F) {
    let files = read_dir(path);
    for file in files.unwrap().take(num) {
        let path = file.unwrap().path();
        if path.to_str().unwrap().ends_with(".txt") {
            let file = File::open(&path).unwrap();
            let reader = BufReader::new(file);
            file_processor(reader);
        }
    }
}

fn main() {
    const CORPUS_DIR: &'static str = "/home/jamougha/corpus/pg";
    const WORDS: &'static str = "/home/jamougha/corpus/pg/word_counts.csv";
    //find_most_common_words(CORPUS_DIR, WORDS);
    let words = load_most_common_words(WORDS);
    let mut builder = LanguageModelBuilder::new(10, words);

    let path = Path::new(CORPUS_DIR);

    visit_files(&path, 100000, |read| {
        let mut acc = (&mut builder).new_file();
        visit_tokens(read, |w| (&mut acc).add_word(w));
    });

    let model = builder.build();
    println!("Model loaded");
    loop {
        println!("");
        let input = get_line();
        if input.starts_with(":q") {
            break;
        }

        match parser::parse(input.trim_matches(|c: char| c.is_whitespace()), &model) {
            Ok(word_vec) => {
                let nearest = model.nearest_words(&word_vec);
                println!(" = {:?}", word_vec);
                println!("-------------");
                for word in nearest.iter().take(20) {
                    println!("{:?}, {}", word, word_vec.distance(word));
                }
            }
            Err(e) => println!("{:?}", e)
        }

    }

}
<|endoftext|>


<commit_before>extern crate rudit;
extern crate termion;

use std::io::{Write, stdout};
use termion::raw::IntoRawMode;
use termion::event::Key;
use termion::input::TermRead;
use termion::cursor::Goto;
use rudit::gapbuffer::GapBuffer;

fn main() {
    let mut buffer = GapBuffer::new(30);
    let mut stdout = stdout().into_raw_mode().unwrap();
    let mut index = 0;
    let mut cx: u16 = 3;
    let mut cy: u16 = 1;
    // buffer.insert(0, 'a');
    // buffer.insert(1, 'b');
    // buffer.insert(2, '\n');
    // buffer.insert(3, 'c');
    // index = 3;
    // cy = 2;
    write!(stdout,
           "{}{}",
           termion::clear::All,
           termion::cursor::Goto(cx, cy))
        .unwrap();
    stdout.flush().unwrap();
    'main: loop {

        write!(stdout, "{}", termion::clear::CurrentLine).unwrap();

        draw_lines(&mut stdout, &buffer.buffer);
        draw_cursor(&mut stdout, cx, cy);

        stdout.flush().unwrap();

        for c in std::io::stdin().keys() {
            match c.unwrap() {
                Key::Char('\n') => {
                    buffer.insert(index, '\n');
                    cx = 3;
                    cy += 1;
                    index += 1;
                }
                Key::Char(c) => {
                    buffer.insert(index, c);
                    index += 1;
                    cx += 1;
                }
                Key::Up => {
                    cy -= 1;
                }
                Key::Left => {
                    if cx > 3 {
                        cx -= 1;
                        index -= 1;
                    }
                }
                Key::Right => {
                    // inefficient(?)
                    // let mut b = vec!['\0'; buffer.buffer.len()];
                    // for i in 0..buffer.gap_start {
                    //     b[i] = buffer.buffer[i];
                    // }
                    // for i in buffer.gap_end..buffer.buffer.len() {
                    //     b[i - (buffer.gap_end - buffer.gap_start)] = buffer.buffer[i];
                    // }
                    // if b[index] != '\0' {
                    //     cx += 1;
                    //     index += 1;
                    // }

                    // better
                    if buffer.buffer[index] != '\0' ||
                       buffer.buffer[buffer.buffer.len() - index + buffer.gap_start - 1] != '\0' {
                        cx += 1;
                        index += 1;
                    }
                }
                Key::Esc => break,
                _ => (),
            }
            continue 'main;
        }
        write!(stdout, "{}", termion::clear::All).unwrap();
        stdout.flush().unwrap();
        break;
    }
}

fn draw_lines(stdout: &mut termion::raw::RawTerminal<std::io::Stdout>, buffer: &Vec<char>) {
    let s: String = buffer.iter().collect();
    for (index, i) in s.split('\n').enumerate() {
        write!(stdout,
               "{}{}{}{}",
               Goto(0, (index + 1) as u16),
               index,
               Goto(3, (index + 1) as u16),
               i)
            .unwrap();
    }
}

fn draw_cursor(stdout: &mut termion::raw::RawTerminal<std::io::Stdout>, cx: u16, cy: u16) {
    write!(stdout, "{}", termion::cursor::Goto(cx, cy)).unwrap();
}
<commit_msg>up cursor movement working<commit_after>extern crate rudit;
extern crate termion;

use std::io::{Write, stdout};
use termion::raw::IntoRawMode;
use termion::event::Key;
use termion::input::TermRead;
use termion::cursor::Goto;
use rudit::gapbuffer::GapBuffer;

fn main() {
    let mut buffer = GapBuffer::new(30);
    let mut stdout = stdout().into_raw_mode().unwrap();
    let mut index = 0;
    let mut cx: u16 = 3;
    let mut cy: u16 = 1;
    // buffer.insert(0, 'a');
    // buffer.insert(1, 'b');
    // buffer.insert(2, '\n');
    // buffer.insert(3, 'c');
    // index = 3;
    // cy = 2;
    write!(stdout,
           "{}{}",
           termion::clear::All,
           termion::cursor::Goto(cx, cy))
            .unwrap();
    stdout.flush().unwrap();
    'main: loop {

        write!(stdout, "{}", termion::clear::CurrentLine).unwrap();

        draw_lines(&mut stdout, &buffer.buffer);
        draw_cursor(&mut stdout, cx, cy);

        stdout.flush().unwrap();

        for c in std::io::stdin().keys() {
            match c.unwrap() {
                Key::Char('\n') => {
                    buffer.insert(index, '\n');
                    cx = 3;
                    cy += 1;
                    index += 1;
                }
                Key::Char(c) => {
                    buffer.insert(index, c);
                    index += 1;
                    cx += 1;
                }
                Key::Up => {
                    let mut new_line_pos = index;
                    let mut count_previous_line = 0;
                    for i in (0..index).rev() {
                        new_line_pos -= 1;
                        if i == 0 || buffer.buffer[i] == '\n' {
                            break;
                        }
                    }
                    if new_line_pos == 0 {
                        count_previous_line = 1;
                    }
                    for i in (0..new_line_pos).rev() {
                        count_previous_line += 1;
                        if i == 0 || buffer.buffer[i] == '\n' {
                            count_previous_line += 1;
                            break;
                        }
                    }
                    index = (cy as usize) - 1 +
                            std::cmp::min((cx as usize) - 3, count_previous_line - 1);
                    index -= 1;
                    cy -= 1;
                }
                Key::Left => {
                    if cx > 3 {
                        cx -= 1;
                        index -= 1;
                    }
                }
                Key::Right => {
                    if buffer.buffer[index] != '\0' ||
                       buffer.buffer[buffer.buffer.len() - index + buffer.gap_start - 1] != '\0' {
                        cx += 1;
                        index += 1;
                    }
                }
                Key::Esc => break,
                _ => (),
            }
            continue 'main;
        }
        write!(stdout, "{}", termion::clear::All).unwrap();
        stdout.flush().unwrap();
        break;
    }
}

fn draw_lines(stdout: &mut termion::raw::RawTerminal<std::io::Stdout>, buffer: &Vec<char>) {
    let s: String = buffer.iter().collect();
    for (index, i) in s.split('\n').enumerate() {
        write!(stdout,
               "{}{}{}{}",
               Goto(0, (index + 1) as u16),
               index + 1,
               Goto(3, (index + 1) as u16),
               i)
                .unwrap();
    }
}

fn draw_cursor(stdout: &mut termion::raw::RawTerminal<std::io::Stdout>, cx: u16, cy: u16) {
    write!(stdout, "{}", termion::cursor::Goto(cx, cy)).unwrap();
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate tokio_core;
extern crate tokio_proto;
extern crate tokio_service;

use std::io;
use std::str;
use tokio_core::io::{Codec, EasyBuf};
use tokio_core::io::{Io, Framed};
use tokio_proto::pipeline::ServerProto;
use tokio_proto::TcpServer;
use tokio_service::Service;
use futures::{future, Future, BoxFuture};

#[derive(Default)]
pub struct CliCodec {
    /// Offset within the incoming EasyBuf at which newline search last ended
    search_offset: usize,
}

impl Codec for CliCodec {
    /// Input type is a tuple with the command name and an optional argument string
    type In = (String, Option<String>);

    /// Response type is just a string
    type Out = String;

    /// Find a newline, decode to a tuple of command name and argument string
    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Self::In>> {
        // Find newline
        let m = buf
            .as_slice()
            .iter()
            .skip(self.search_offset)
            .position(|&b| b == b'\n');

        match m {
            // Process the line if a newline was found
            Some(idx) => {
                println!("Found newline at position {}, started at {}", idx, self.search_offset); // XXX

                let line = buf.drain_to(self.search_offset + idx);
                buf.drain_to(1);

                self.search_offset = 0;

                match str::from_utf8(line.as_slice()) {
                    // Return the string on successful UTF-8 decode
                    // (TODO: split on the first space, ignore blank lines)
                    Ok(s) => Ok(Some(
                            ("Received".to_string(), Some(s.trim().to_string()))
                            )),

                    // Return an error if invalid UTF-8 is received
                    Err(e) => Err(io::Error::new(io::ErrorKind::Other, format!("invalid UTF-8: {:?}", e))),
                }
            },

            // Save our position if a newline wasn't found
            _ => {
                println!("Haven't received newline yet!  We started at offset {}, now at {}", self.search_offset, buf.len()); // XXX

                self.search_offset = buf.len();

                Ok(None)
            }
        }
    }

    /// Append the String to the outgoing buffer
    fn encode(&mut self, msg: String, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.extend(msg.as_bytes());
        buf.push(b'\n');
        Ok(())
    }
}

pub struct CliProto;

impl<T: Io + 'static> ServerProto<T> for CliProto {
    type Request = (String, Option<String>);
    type Response = String;

    type Transport = Framed<T, CliCodec>;
    type BindTransport = Result<Self::Transport, io::Error>;

    fn bind_transport(&self, io: T) -> Self::BindTransport {
        Ok(io.framed(CliCodec::default()))
    }
}

trait CliCommand {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn call(&self, args: &str) -> &str;
}

pub struct CliServer;

impl Service for CliServer {
    type Request = (String, Option<String>);
    type Response = String;

    type Error = io::Error;

    type Future = BoxFuture<Self::Response, Self::Error>;

    fn call(&self, req: Self::Request) -> Self::Future {
        future::ok(format!("Received: {:?}", req)).boxed()
    }
}

fn main() {
    let addr = "0.0.0.0:14311".parse().unwrap();
    let server = TcpServer::new(CliProto, addr);

    println!("Serving on {}", addr);
    server.serve(|| Ok(CliServer));
}
<commit_msg>Added unused functions to add commands to the server.<commit_after>extern crate futures;
extern crate tokio_core;
extern crate tokio_proto;
extern crate tokio_service;

use std::io;
use std::str;
use std::collections::BTreeMap;
use tokio_core::io::{Codec, EasyBuf};
use tokio_core::io::{Io, Framed};
use tokio_proto::pipeline::ServerProto;
use tokio_proto::TcpServer;
use tokio_service::Service;
use futures::{future, Future, BoxFuture};

#[derive(Default)]
pub struct CliCodec {
    /// Offset within the incoming EasyBuf at which newline search last ended
    search_offset: usize,
}

impl Codec for CliCodec {
    /// Input type is a tuple with the command name and an optional argument string
    type In = (String, Option<String>);

    /// Response type is just a string
    type Out = String;

    /// Find a newline, decode to a tuple of command name and argument string
    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Self::In>> {
        // Find newline
        let m = buf
            .as_slice()
            .iter()
            .skip(self.search_offset)
            .position(|&b| b == b'\n');

        match m {
            // Process the line if a newline was found
            Some(idx) => {
                println!("Found newline at position {}, started at {}", idx, self.search_offset); // XXX

                let line = buf.drain_to(self.search_offset + idx);
                buf.drain_to(1);

                self.search_offset = 0;

                match str::from_utf8(line.as_slice()) {
                    // Return the string on successful UTF-8 decode
                    // (TODO: split on the first space, ignore blank lines)
                    Ok(s) => Ok(Some(
                            ("Received".to_string(), Some(s.trim().to_string()))
                            )),

                    // Return an error if invalid UTF-8 is received
                    Err(e) => Err(io::Error::new(io::ErrorKind::Other, format!("invalid UTF-8: {:?}", e))),
                }
            },

            // Save our position if a newline wasn't found
            _ => {
                println!("Haven't received newline yet!  We started at offset {}, now at {}", self.search_offset, buf.len()); // XXX

                self.search_offset = buf.len();

                Ok(None)
            }
        }
    }

    /// Append the String to the outgoing buffer
    fn encode(&mut self, msg: String, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.extend(msg.as_bytes());
        buf.push(b'\n');
        Ok(())
    }
}

pub struct CliProto;

impl<T: Io + 'static> ServerProto<T> for CliProto {
    type Request = (String, Option<String>);
    type Response = String;

    type Transport = Framed<T, CliCodec>;
    type BindTransport = Result<Self::Transport, io::Error>;

    fn bind_transport(&self, io: T) -> Self::BindTransport {
        Ok(io.framed(CliCodec::default()))
    }
}

trait CliCommand {
    fn name(&self) -> &str;
    fn description(&self) -> &str;
    fn call(&self, args: Option<String>) -> String;
}

#[derive(Default)]
pub struct CliServer<'a> {
    commands: BTreeMap<&'a str, &'a CliCommand>,
}

impl<'a> CliServer<'a> {
    fn add_command(&mut self, cmd: &'a CliCommand) {
        self.commands.insert(cmd.name(), cmd);
    }
}

impl<'a> Service for CliServer<'a> {
    type Request = (String, Option<String>);
    type Response = String;

    type Error = io::Error;

    type Future = BoxFuture<Self::Response, Self::Error>;

    fn call(&self, req: Self::Request) -> Self::Future {
        match self.commands.get(&req.0[..]) {
            Some(cmd) => {
                println!("Calling command {}", req.0);
                // TODO: have commands return futures?
                future::ok(cmd.call(req.1)).boxed()
            },
            None => {
                println!("No match found for command {}", req.0);
                future::ok(format!("Received: {:?}", req)).boxed()
            }
        }
    }
}

fn main() {
    let addr = "0.0.0.0:14311".parse().unwrap();
    let server = TcpServer::new(CliProto, addr);

    println!("Serving on {}", addr);
    server.serve(|| Ok(CliServer::default()));
}
<|endoftext|>


<commit_before>extern crate getopts;

mod diff;

use std::io;
use std::io::Write;
use std::env;
use getopts::Options;

struct Range {
    start: i32,
    end: i32,
}

fn input() -> Result<Vec<String>, io::Error> {
    let mut lines: Vec<String> = Vec::new();
    loop {
        let mut line = String::new();
        match io::stdin().read_line(&mut line) {
            Err(error) => return Err(error),
            Ok(_) => {},
        }
        match line.trim() {
            "." => {
                break
            },
            _ => {
                lines.push(line)
            }
        }
    }
    Ok(lines)
}

fn command(line: &String, line_num: &mut i32, diff: &diff::Diff) -> Result<diff::Diff, String> {
    // parse the command line to get
    // Line num or range
    // command
    match line.trim() {
        "a" => {
            append_after(Range{start: *line_num, end: *line_num}, diff)
                .map_err(|err| err.to_string())
        },
        "q" => std::process::exit(0),
        "u" => Ok(diff.undo()),
        _ => Err("?".to_string()),
    }
}

fn append_after(range: Range, diff: &diff::Diff) -> Result<diff::Diff, io::Error> {
    input()
        .map_err(|err| err)
        .map(|lines| {
            diff.add_lines(range.end+1, lines)
        })
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optopt("p", "prompt", "prompt to show while in command mode", "PROMPT");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => panic!(f.to_string())
    };

    let prompt = matches.opt_str("p")
        .unwrap_or_else(|| "".to_string());
    let mut diff = diff::Diff::new();
    let mut line_num: i32 = 1;
    loop {
        print!("{}", prompt);
        match io::stdout().flush() {
            Ok(_) => (),
            Err(err) => {
                println!("Error flushing stdout: {}", err);
                continue
            }
        }
        let mut line = String::new();
        match io::stdin().read_line(&mut line) {
            Ok(_) => (),
            Err(_) => {
                println!("?");
                continue
            },
        }
        match command(&line, &mut line_num, &mut diff) {
            Ok(d) => {
                diff = d;
            },
            Err(err) => println!("Error: {}", err),

        }
    }
}

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

}
<commit_msg>Make command parsing more idiomatic<commit_after>extern crate getopts;

mod diff;

use std::io;
use std::io::Write;
use std::env;
use getopts::Options;

static CurrentAddress: Address = Address::Nth(0);

struct Range {
    start: Box<Address>,
    end: Box<Address>,
}

enum Address {
    Current,
    Last,
    Nth(i32),
    Previous,
    NthPrevious(i32),
    Next,
    NthNext(i32),
    All,
    Range(Range),
    CurrentToEnd,
    RENext(String),
    REPrevious(String),
    Mark(String),
}

trait Operation {
    fn apply(Address, &diff::Diff) -> Result<diff::Diff, String>;
}

struct nop;

impl Operation for nop {
    fn apply(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
        panic!("Command didn't get set. This shouldn't have happened");
        Err("Command didn't get set. This shouldn't have happened".to_string())
    }
}

struct append_after;

impl Operation for append_after {
    fn apply(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
        let line_num: i32 = match addr {
            Address::Nth(ln) => ln,
            _ => 0,
        };
        input()
            .map_err(|err| err.to_string())
            .map(|lines| {
                diff.add_lines(line_num, lines)
            })
    }
}

struct undo;

impl Operation for undo {
    fn apply(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
        Ok(diff.undo())
    }
}

struct quit;

impl Operation for quit {
    fn apply(addr: Address, diff: &diff::Diff) -> Result<diff::Diff, String> {
        std::process::exit(0);
        Err("Should never get here".to_string())
    }
}

struct Command {
    address: Address,
    operation: Operation,
}

fn input() -> Result<Vec<String>, io::Error> {
    let mut lines: Vec<String> = Vec::new();
    loop {
        let mut line = String::new();
        match io::stdin().read_line(&mut line) {
            Err(error) => return Err(error),
            Ok(_) => {},
        }
        match line.trim() {
            "." => {
                break
            },
            _ => {
                lines.push(line)
            }
        }
    }
    Ok(lines)
}

fn parse_cmd(line: &String) -> Result<Command, String> {
    let mut command = Command {
        address: Address::Current,
        command: nop,
    };
    command.command = match line.trim() {
        "a" => append_after,
        "q" => quit,
        "u" => undo,
        _ => {
            return Err("Uknown command".to_string())
        },
    };
    Ok(command)
}

fn command(line: &String, line_num: i32, diff: &diff::Diff) -> Result<diff::Diff, String> {
    parse_cmd(line)
        .map_err(|err| err.to_string())
        .and_then(|cmd| {
            cmd.operation.apply(cmd.address, diff)
        })
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optopt("p", "prompt", "prompt to show while in command mode", "PROMPT");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => panic!(f.to_string())
    };

    let prompt = matches.opt_str("p")
        .unwrap_or_else(|| "".to_string());
    let mut diff = diff::Diff::new();
    let mut line_num: i32 = 1;
    loop {
        print!("{}", prompt);
        match io::stdout().flush() {
            Ok(_) => (),
            Err(err) => {
                println!("Error flushing stdout: {}", err);
                continue
            }
        }
        let mut line = String::new();
        match io::stdin().read_line(&mut line) {
            Ok(_) => (),
            Err(_) => {
                println!("?");
                continue
            },
        }
        match command(&line, line_num, &mut diff) {
            Ok(d) => {
                diff = d;
            },
            Err(err) => println!("Error: {}", err),

        }
    }
}

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

}
<|endoftext|>