<commit_before>#![feature(core)]

use std::num::Float;
use std::collections::binary_heap::BinaryHeap; // pq
use std::cmp::Ordering;

type float = f64;
type time = u64;

const TIME_RESOLUTION: time = 1000_000; // in micro seconds.

#[derive(Debug)]
struct NeuronConfig {
    arp:       time,
    tau_m:     float,
    tau_r:     float,
    weight_r:  float,
    threshold: float,
}

#[derive(Debug)]
struct Neuron {
    /// End of absolute refractory period
    arp_end:         time,
    last_spike_time: time,
    mem_pot:         float,

    /// An index into a [NeuronConfig] table.
    config_id:       usize,
}

#[derive(Debug)]
enum NeuronResult {
    InArp,
    NoFire,
    Fire
}

impl Neuron {
    fn new(config_id: usize) -> Neuron {
        Neuron {
            arp_end: 0,
            last_spike_time: 0,
            mem_pot: 0.0,
            config_id: config_id,
        }
    }

    fn spike(&mut self, timestamp: time, weight: float, cfg: &NeuronConfig) -> NeuronResult {
        assert!(timestamp >= self.last_spike_time);
        assert!(cfg.tau_m >= 0.0);

        // Return early if still in absolute refractory period (arp)
        if timestamp < self.arp_end {
            return NeuronResult::InArp;
        }

        // Time since end of last absolute refractory period (arp)
        assert!(timestamp >= self.arp_end);
        let delta = timestamp - self.arp_end;

        // Convert delta to float
        let delta: float = (delta as float) / TIME_RESOLUTION as float;

        // Calculate dynamic threshold
        let dyn_threshold = cfg.threshold +
                            cfg.weight_r * (-delta / cfg.tau_r).exp();

        // Update memory potential
        if cfg.tau_m > 0.0 {

            let d = timestamp - self.last_spike_time;
            // Convert delta to float
            let d: float = (d as float) / TIME_RESOLUTION as float;

            let decay = (-d / cfg.tau_m).exp();
            self.mem_pot *= decay;
            self.mem_pot += weight;
        }
        else {
            self.mem_pot = weight;
        }

        // Update last spike time
        self.last_spike_time = timestamp;

        if self.mem_pot >= dyn_threshold {
            self.arp_end = timestamp + cfg.arp;
            NeuronResult::Fire
        }
        else {
            NeuronResult::NoFire
        }
    }
}

#[derive(Debug)]
struct Event {
    time:   time,
    weight: float,
    target: usize
}

impl PartialEq for Event {
    fn eq(&self, other: &Self) -> bool {
        self.time == other.time
    }
}

impl Eq for Event {}

impl PartialOrd for Event {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.time.partial_cmp(&other.time).map(|o| o.reverse())
    }
}

impl Ord for Event {
    fn cmp(&self, other: &Self) -> Ordering {
        self.time.cmp(&other.time).reverse()
    }
}

fn ms(n: time) -> time { n * 1000 }
fn us(n: time) -> time { n }

#[derive(Debug)]
struct Synapse {
    delay:  time,
    weight: float,
    post_neuron: usize,
}

struct Net {
    neurons: Vec<Neuron>,
    neuron_configs: Vec<NeuronConfig>,
    synapses: Vec<Vec<Synapse>>,
    events: BinaryHeap<Event>,
}

impl Net {
    fn new() -> Net {
        Net {
            neurons: vec![],
            neuron_configs: vec![],
            synapses: vec![],
            events: BinaryHeap::new(),
        }
    }

    /// Returns the config_id
    fn create_neuron_config(&mut self, config: NeuronConfig) -> usize {
        self.neuron_configs.push(config);
        self.neuron_configs.len() - 1
    }

    /// Returns the neuron_id
    fn create_neuron(&mut self, config_id: usize) -> usize {
        self.neurons.push(Neuron::new(config_id));
        self.synapses.push(vec![]);
        self.neurons.len() - 1
    }

    fn create_synapse(&mut self, from_neuron: usize, synapse: Synapse) {
        let mut syn_arr = &mut (self.synapses.as_mut_slice())[from_neuron];
        syn_arr.push(synapse);
    }

    fn add_event(&mut self, event: Event) {
        self.events.push(event);
    }

    fn fire(&mut self, timestamp: time, neuron_id: usize) {
        for syn in &self.synapses[neuron_id] {
            println!("{:?}", syn);
            self.events.push(Event {
                time: timestamp + syn.delay,
                weight: syn.weight,
                target: syn.post_neuron
            });
        }
    }

    fn simulate(&mut self) {
	loop {
	    println!("-------------------------------------");

	    if let Some(ev) = self.events.pop() {
		println!("{:?}", ev);
                let neuron_id = ev.target;
                let fire = {
		    let neuron = &mut (self.neurons.as_mut_slice())[neuron_id];
		    let cfg = &(self.neuron_configs.as_slice())[neuron.config_id];
		    let fire = neuron.spike(ev.time, ev.weight, cfg);
		    println!("{:?}", fire);
		    println!("{:?}", neuron);
                    fire
                };
                match fire {
                    NeuronResult::Fire => {
                        // Post a new event to all synapses
                        self.fire(ev.time, neuron_id);
                    }
                    _ => {
                    }
                }
	    }
	    else {
		break;
	    }
	}
    }
}

fn main() {

    let mut net = Net::new();

    // Koinzidenz neurons
    let cfg_k = net.create_neuron_config(NeuronConfig {
        arp: us(500), // 0.5 ms = 500 us
        tau_m: 0.04,
        tau_r: 0.5,
        weight_r: 0.0,
        threshold: 1.1,
    });

    // Input neurons
    let cfg_i = net.create_neuron_config(NeuronConfig {
        arp: ms(1),
        tau_m: 0.0,
        tau_r: 0.5,
        weight_r: 0.0,
        threshold: 0.6,
    });

    let inp1 = net.create_neuron(cfg_i);
    let inp2 = net.create_neuron(cfg_i);

    net.create_synapse(inp1, Synapse {delay: us(160), weight: 1.0, post_neuron: inp2});

    // Fill event queue with events
    for i in 1..100 {
        let ev = Event {
            time:   ms(i) / 10,
            weight: 0.6,
            target: inp1
        };

        net.add_event(ev);
    }

    net.simulate();
}
<commit_msg>Use newtype NeuronConfigId instead of plain integer<commit_after>#![feature(core)]

use std::num::Float;
use std::collections::binary_heap::BinaryHeap; // pq
use std::cmp::Ordering;

type float = f64;
type time = u64;

const TIME_RESOLUTION: time = 1000_000; // in micro seconds.

#[derive(Debug)]
struct NeuronConfig {
    arp:       time,
    tau_m:     float,
    tau_r:     float,
    weight_r:  float,
    threshold: float,
}

#[derive(Debug, Copy)]
struct NeuronConfigId(usize);

#[derive(Debug)]
struct Neuron {
    /// End of absolute refractory period
    arp_end:         time,
    last_spike_time: time,
    mem_pot:         float,

    /// An index into a [NeuronConfig] table.
    config_id:       NeuronConfigId,
}

#[derive(Debug)]
enum NeuronResult {
    InArp,
    NoFire,
    Fire
}

impl Neuron {
    fn new(config_id: NeuronConfigId) -> Neuron {
        Neuron {
            arp_end: 0,
            last_spike_time: 0,
            mem_pot: 0.0,
            config_id: config_id,
        }
    }

    fn spike(&mut self, timestamp: time, weight: float, cfg: &NeuronConfig) -> NeuronResult {
        assert!(timestamp >= self.last_spike_time);
        assert!(cfg.tau_m >= 0.0);

        // Return early if still in absolute refractory period (arp)
        if timestamp < self.arp_end {
            return NeuronResult::InArp;
        }

        // Time since end of last absolute refractory period (arp)
        assert!(timestamp >= self.arp_end);
        let delta = timestamp - self.arp_end;

        // Convert delta to float
        let delta: float = (delta as float) / TIME_RESOLUTION as float;

        // Calculate dynamic threshold
        let dyn_threshold = cfg.threshold +
                            cfg.weight_r * (-delta / cfg.tau_r).exp();

        // Update memory potential
        if cfg.tau_m > 0.0 {

            let d = timestamp - self.last_spike_time;
            // Convert delta to float
            let d: float = (d as float) / TIME_RESOLUTION as float;

            let decay = (-d / cfg.tau_m).exp();
            self.mem_pot *= decay;
            self.mem_pot += weight;
        }
        else {
            self.mem_pot = weight;
        }

        // Update last spike time
        self.last_spike_time = timestamp;

        if self.mem_pot >= dyn_threshold {
            self.arp_end = timestamp + cfg.arp;
            NeuronResult::Fire
        }
        else {
            NeuronResult::NoFire
        }
    }
}

#[derive(Debug)]
struct Event {
    time:   time,
    weight: float,
    target: usize
}

impl PartialEq for Event {
    fn eq(&self, other: &Self) -> bool {
        self.time == other.time
    }
}

impl Eq for Event {}

impl PartialOrd for Event {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.time.partial_cmp(&other.time).map(|o| o.reverse())
    }
}

impl Ord for Event {
    fn cmp(&self, other: &Self) -> Ordering {
        self.time.cmp(&other.time).reverse()
    }
}

fn ms(n: time) -> time { n * 1000 }
fn us(n: time) -> time { n }

#[derive(Debug)]
struct Synapse {
    delay:  time,
    weight: float,
    post_neuron: usize,
}

struct Net {
    neurons: Vec<Neuron>,
    neuron_configs: Vec<NeuronConfig>,
    synapses: Vec<Vec<Synapse>>,
    events: BinaryHeap<Event>,
}

impl Net {
    fn new() -> Net {
        Net {
            neurons: vec![],
            neuron_configs: vec![],
            synapses: vec![],
            events: BinaryHeap::new(),
        }
    }

    fn create_neuron_config(&mut self, config: NeuronConfig) -> NeuronConfigId {
        self.neuron_configs.push(config);
        NeuronConfigId(self.neuron_configs.len() - 1)
    }

    /// Returns the neuron_id
    fn create_neuron(&mut self, config_id: NeuronConfigId) -> usize {
        self.neurons.push(Neuron::new(config_id));
        self.synapses.push(vec![]);
        self.neurons.len() - 1
    }

    fn create_synapse(&mut self, from_neuron: usize, synapse: Synapse) {
        let mut syn_arr = &mut (self.synapses.as_mut_slice())[from_neuron];
        syn_arr.push(synapse);
    }

    fn add_event(&mut self, event: Event) {
        self.events.push(event);
    }

    fn fire(&mut self, timestamp: time, neuron_id: usize) {
        for syn in &self.synapses[neuron_id] {
            println!("{:?}", syn);
            self.events.push(Event {
                time: timestamp + syn.delay,
                weight: syn.weight,
                target: syn.post_neuron
            });
        }
    }

    fn get_config_for_neuron<'a>(&'a self, neuron: &Neuron) -> &'a NeuronConfig {
        match neuron.config_id {
            NeuronConfigId(idx) => {
                &(self.neuron_configs.as_slice())[idx]
            }
        }
    }

    fn simulate(&mut self) {
	loop {
	    println!("-------------------------------------");

	    if let Some(ev) = self.events.pop() {
		println!("{:?}", ev);
                let neuron_id = ev.target;
                let fire = {
		    let neuron = &mut (self.neurons.as_mut_slice())[neuron_id];

                    let cfg = match neuron.config_id {
                        NeuronConfigId(idx) => {
                            &(self.neuron_configs.as_slice())[idx]
                        }
                    };

		    let fire = neuron.spike(ev.time, ev.weight, cfg);
		    println!("{:?}", fire);
		    println!("{:?}", neuron);
                    fire
                };
                match fire {
                    NeuronResult::Fire => {
                        // Post a new event to all synapses
                        self.fire(ev.time, neuron_id);
                    }
                    _ => {
                    }
                }
	    }
	    else {
		break;
	    }
	}
    }
}

fn main() {

    let mut net = Net::new();

    // Koinzidenz neurons
    let cfg_k = net.create_neuron_config(NeuronConfig {
        arp: us(500), // 0.5 ms = 500 us
        tau_m: 0.04,
        tau_r: 0.5,
        weight_r: 0.0,
        threshold: 1.1,
    });

    // Input neurons
    let cfg_i = net.create_neuron_config(NeuronConfig {
        arp: ms(1),
        tau_m: 0.0,
        tau_r: 0.5,
        weight_r: 0.0,
        threshold: 0.6,
    });

    let inp1 = net.create_neuron(cfg_i);
    let inp2 = net.create_neuron(cfg_i);

    net.create_synapse(inp1, Synapse {delay: us(160), weight: 1.0, post_neuron: inp2});

    // Fill event queue with events
    for i in 1..100 {
        let ev = Event {
            time:   ms(i) / 10,
            weight: 0.6,
            target: inp1
        };

        net.add_event(ev);
    }

    net.simulate();
}
<|endoftext|>


<commit_before>
extern crate getopts;
use getopts::Options;
use std::env;
use std::process::Command;

// construct options
fn options() -> Options {
    let mut opts = Options::new();
    opts.optopt("d", "dir", "Take the pages from the given directory. (default: public)", "<dir>");
    opts.optopt("m", "message", "Use the given <msg> as the commit message. (default: Update documentation)", "<msg>");
    opts.optopt("b", "branch", "Name of the branch to write to. (default: code-pages]", "<branch>");
    opts.optflag("p", "push", "Push the branch to origin/<branch> after committing. (default: false)");
    opts.optflag("h", "help", "Print this help message.");
    opts
}

fn print_usage(program: &str, opts: &Options) {
    let brief = format!("Usage: {} [options] <dir>", program);
    println!("{}", opts.usage(&brief));
}

fn check_repo() -> bool {
    Command::new("git")
            .arg("rev-parse")
            .status()
            .expect("Unknown Git error")
            .success()
}

fn try_rebase(remote: &str, branch: &str) -> bool {
    let output =  Command::new("git")
            .args(&["rev-list", "--max-count=1",
                 &format!("{}/{}", remote, branch)[..]])
            .output().unwrap();

    if !output.status.success() {
        let msg = String::from_utf8(output.stderr).unwrap();
        println!("stdout:{}",msg);
        return false;
    }

    let rev = String::from_utf8(output.stdout).unwrap();
    println!("rev:{}", rev);

    Command::new("git")
            .args(&["update-ref",
                &format!("refs/heads/{}",branch)[..], &rev[..]])
            .status()
            .unwrap()
            .success()
}

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

    let opts = options();

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => {m}
        Err(f) => { panic!(f.to_string())}
    };
    if matches.opt_present("h") {
        print_usage(&program, &opts);
        return;
    }

    let page_dir = matches.opt_str("d").unwrap_or(String::from("public"));
    let commit_msg = matches.opt_str("m").unwrap_or(String::from("Update documentation"));
    let branch = matches.opt_str("b").unwrap_or(String::from("code-pages"));
    let push = matches.opt_present("p");

    if !check_repo() {
        println!("check repo failed.");
        return
    }

    if !try_rebase("origin", &branch[..]) {
        println!("rebase failed.");
        return
    }

    println!("page_dir:{}, commit_msg:{}, branch:{}, push:{}.", page_dir, commit_msg, branch, push);

}
<commit_msg>trim rev<commit_after>
extern crate getopts;
use getopts::Options;
use std::env;
use std::process::Command;

// construct options
fn options() -> Options {
    let mut opts = Options::new();
    opts.optopt("d", "dir", "Take the pages from the given directory. (default: public)", "<dir>");
    opts.optopt("m", "message", "Use the given <msg> as the commit message. (default: Update documentation)", "<msg>");
    opts.optopt("b", "branch", "Name of the branch to write to. (default: code-pages]", "<branch>");
    opts.optflag("p", "push", "Push the branch to origin/<branch> after committing. (default: false)");
    opts.optflag("h", "help", "Print this help message.");
    opts
}

fn print_usage(program: &str, opts: &Options) {
    let brief = format!("Usage: {} [options] <dir>", program);
    println!("{}", opts.usage(&brief));
}

fn check_repo() -> bool {
    Command::new("git")
            .arg("rev-parse")
            .status()
            .expect("Unknown Git error")
            .success()
}

fn try_rebase(remote: &str, branch: &str) -> bool {
    let output =  Command::new("git")
            .args(&["rev-list", "--max-count=1",
                 &format!("{}/{}",remote, branch)[..]])
            .output().unwrap();

    if !output.status.success() {
        let msg = String::from_utf8(output.stderr).unwrap();
        println!("stderr:{}",msg);
        //return false;
    }

    let rev = String::from_utf8(output.stdout).unwrap();
    let rev = rev.trim();

    Command::new("git")
            .args(&["update-ref",
                &format!("refs/heads/{}",branch)[..], rev])
            .status()
            .unwrap()
            .success()
}

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

    let opts = options();

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => {m}
        Err(f) => { panic!(f.to_string())}
    };
    if matches.opt_present("h") {
        print_usage(&program, &opts);
        return;
    }

    let page_dir = matches.opt_str("d").unwrap_or(String::from("public"));
    let commit_msg = matches.opt_str("m").unwrap_or(String::from("Update documentation"));
    let branch = matches.opt_str("b").unwrap_or(String::from("code-pages"));
    let push = matches.opt_present("p");

    if !check_repo() {
        println!("check repo failed.");
        return
    }

    if !try_rebase("origin", &branch[..]) {
        println!("rebase failed.");
        return
    }

    println!("page_dir:{}, commit_msg:{}, branch:{}, push:{}.", page_dir, commit_msg, branch, push);

}
<|endoftext|>


<commit_before>use png;
use color::{Color, Black, White, Red, Green, Blue};
use point::Point;
use scene::{Scene, Spot};
use shapes::{Object, Sphere, Plane};

static WIDTH: int = 1000;
static HEIGHT: int = 1000;

#[main]
fn main() {
  let mut pixels = ~[Black, ..((WIDTH * HEIGHT) as uint)];

  let scene = Scene {
    eye: Point::new(-12000., 0., 0.),
    spots: ~[
      Spot {
        pos: Point::new(0., -200., 0.),
        color: White
      },
    ],
    objects: ~[
      Object {
        pos: Point::new(0., 400., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 400., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 400., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
    ]
  };

  for x in range(0, WIDTH) {
    for y in range(0, HEIGHT) {
      let vector = Point {
        x: 10000.,
        y: (WIDTH / 2 - x) as f64,
        z: (HEIGHT / 2 - y) as f64
      };

      let (obj, k) = scene.get_closest(&vector);

      pixels[y * WIDTH + x] =
        if obj.is_none() || k <= 0. {
           Black
        }
        else {
          let closest = obj.unwrap();
          scene.get_color(closest, &vector, k)
        };
    }
  }

  let img = png::Image {
    width: WIDTH as u32,
    height: HEIGHT as u32,
    color_type: png::RGB8,
    pixels: pixels.flat_map(|&Color { r, g, b }| { ~[r, g, b] })
  };

  png::store_png(&img, &Path::new("out.png"));
}<commit_msg>Small refactoring of main<commit_after>use png;
use color::{Color, Black, White, Red, Green, Blue};
use point::Point;
use scene::{Scene, Spot};
use shapes::{Object, Sphere, Plane};

static WIDTH: int = 1000;
static HEIGHT: int = 1000;

#[main]
fn main() {
  let mut pixels = ~[Black, ..((WIDTH * HEIGHT) as uint)];

  let scene = Scene {
    eye: Point::new(-12000., 0., 0.),
    spots: ~[
      Spot {
        pos: Point::new(0., -200., 0.),
        color: White
      },
    ],
    objects: ~[
      Object {
        pos: Point::new(0., 400., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 400., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 400., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., -400., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., 400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., 0.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
      Object {
        pos: Point::new(0., 0., -400.),
        shininess: 0.,
        color: Green,
        shape: ~Sphere { radius: 100. }
      },
    ]
  };

  for x in range(0, WIDTH) {
    for y in range(0, HEIGHT) {
      let vector = Point {
        x: 10000.,
        y: (WIDTH / 2 - x) as f64,
        z: (HEIGHT / 2 - y) as f64
      };

      pixels[y * WIDTH + x] = match scene.get_closest(&vector) {
        (Some(obj), k) if k > 0. => scene.get_color(obj, &vector, k),
        _ => Black
      }
    }
  }

  let img = png::Image {
    width: WIDTH as u32,
    height: HEIGHT as u32,
    color_type: png::RGB8,
    pixels: pixels.flat_map(|&Color { r, g, b }| { ~[r, g, b] })
  };

  png::store_png(&img, &Path::new("out.png"));
}<|endoftext|>


<commit_before>#[macro_use]
extern crate nom;
#[macro_use]
extern crate log;
extern crate stderrlog;
#[macro_use]
extern crate clap;
#[macro_use]
extern crate quick_error;
extern crate linked_hash_map;
#[macro_use]
extern crate assert_matches;

#[cfg(test)]
extern crate env_logger;

use std::io::{self, stdin};
use clap::{Arg, App};

#[macro_use]
mod stream_buf;
use stream_buf::{StreamBuf, ReadStreamBuf, FillError, FillApplyError};
use access_log::{RecordState, SessionState};

// Generated with ./mk_vsl_tag from Varnish headers: include/tbl/vsl_tags.h include/tbl/vsl_tags_http.h include/vsl_int.h
// https://github.com/varnishcache/varnish-cache/blob/master/include/vapi/vsl_int.h
// https://github.com/varnishcache/varnish-cache/blob/master/include/tbl/vsl_tags.h
// https://github.com/varnishcache/varnish-cache/blob/master/include/tbl/vsl_tags_http.h
mod vsl_tag_e;
mod vsl;
use vsl::{binary_vsl_tag, vsl_record_v3, vsl_record_v4};
use vsl::VslRecord;

mod access_log;

fn main() {
    let arguments = App::new("Varnish VSL log to syslog logger")
        .version(crate_version!())
        .author(crate_authors!())
        .about("Reads binary VSL log entreis, correlates them togeter and emits JSON log entry to syslog")
        .arg(Arg::with_name("v3")
             .long("varnish-v3")
             .short("3")
             .help("Parse Varnish v3 binary log"))
        .arg(Arg::with_name("quiet")
             .long("quiet")
             .short("q")
             .help("Don't log anything"))
        .arg(Arg::with_name("verbose")
             .long("verbose")
             .short("v")
             .multiple(true)
             .help("Sets the level of verbosity; e.g. -vv for INFO level, -vvvv for TRACE level"))
        .arg(Arg::with_name("output-log")
             .long("output-log")
             .short("l")
             .conflicts_with_all(&["output-debug-records", "output-debug-sessions"])
             .help("Output log content"))
        .arg(Arg::with_name("output-debug-records")
             .long("output-debug-records")
             .short("r")
             .conflicts_with_all(&["output-log", "output-debug-sessions"])
             .help("Output debug format records"))
        .arg(Arg::with_name("output-debug-sessions")
             .long("output-debug-session")
             .short("s")
             .conflicts_with_all(&["output-log", "output-debug-records"]) // TODO: use Set
             .help("Output debug format sessions"))
        .get_matches();

    stderrlog::new()
        .module(module_path!())
        .quiet(arguments.is_present("quiet"))
        .verbosity(arguments.occurrences_of("verbose") as usize)
        .init()
        .unwrap();

    let stdin = stdin();
    let stdin = stdin.lock();
    // for testing
    //let mut rfb = ReadStreamBuf::with_capacity(stdin, 123);
    let mut rfb = ReadStreamBuf::new(stdin);

    let vsl_record: fn(&[u8]) -> nom::IResult<&[u8], VslRecord>;

    if ! arguments.is_present("v3") {
        loop {
            match rfb.fill_apply(binary_vsl_tag) {
                Err(FillApplyError::Parser(_)) => {
                    error!("Input is not Varnish v4 VSL binary format");
                    panic!("Bad input format")
                }
                Err(err) => {
                    error!("Error while reading VSL tag: {}", err);
                    panic!("VSL tag error")
                }
                Ok(None) => continue,
                Ok(Some(_)) => break,
            }
        }
        vsl_record = vsl_record_v4;
    } else {
        vsl_record = vsl_record_v3;
    }

    rfb.recycle(); // TODO: VSL should benefit from alignment - bench test it

    let mut record_state = RecordState::new();
    let mut session_state = SessionState::new();

    loop {
        let record = match rfb.fill_apply(vsl_record) {
            Err(FillApplyError::FillError(FillError::Io(err))) => {
                if err.kind() == io::ErrorKind::UnexpectedEof {
                    info!("Reached end of stream");
                    break
                }
                error!("Got IO Error while reading stream: {}", err);
                panic!("Stream IO error")
            },
            Err(FillApplyError::FillError(err)) => {
                error!("Failed to fill parsing buffer: {}", err);
                panic!("Fill error")
            }
            Err(FillApplyError::Parser(err)) => {
                error!("Failed to parse VSL record: {}", err);
                panic!("Parser error")
            },
            Ok(None) => continue,
            Ok(Some(record)) => record,
        };

        if arguments.is_present("output-log") {
            println!("{}", record);
        } else if arguments.is_present("output-debug-records") {
            if let Some(record) = record_state.apply(&record) {
                println!("{:#?}", record)
            }
        } else if arguments.is_present("output-debug-sessions") {
            if let Some(session) = session_state.apply(&record) {
                println!("{:#?}", session)
            }
        } else {
            panic!("default output unipl")
        }
    }

    for client in session_state.unmatched_client_access_records() {
        warn!("ClientAccessRecord without matching session left: {:?}", client)
    }

    for backend in session_state.unmatched_backend_access_records() {
        warn!("BackendAccessRecord without matching session left: {:?}", backend)
    }

    info!("Done");
}
<commit_msg>better argument spec for output selection<commit_after>#[macro_use]
extern crate nom;
#[macro_use]
extern crate log;
extern crate stderrlog;
#[macro_use]
extern crate clap;
#[macro_use]
extern crate quick_error;
extern crate linked_hash_map;
#[macro_use]
extern crate assert_matches;

#[cfg(test)]
extern crate env_logger;

use std::io::{self, stdin};
use clap::{Arg, App};

#[macro_use]
mod stream_buf;
use stream_buf::{StreamBuf, ReadStreamBuf, FillError, FillApplyError};
use access_log::{RecordState, SessionState};

// Generated with ./mk_vsl_tag from Varnish headers: include/tbl/vsl_tags.h include/tbl/vsl_tags_http.h include/vsl_int.h
// https://github.com/varnishcache/varnish-cache/blob/master/include/vapi/vsl_int.h
// https://github.com/varnishcache/varnish-cache/blob/master/include/tbl/vsl_tags.h
// https://github.com/varnishcache/varnish-cache/blob/master/include/tbl/vsl_tags_http.h
mod vsl_tag_e;
mod vsl;
use vsl::{binary_vsl_tag, vsl_record_v3, vsl_record_v4};
use vsl::VslRecord;

mod access_log;

arg_enum! {
    #[derive(Debug)]
    enum OutputFormat {
        LogEntries,
        RecordsDebug,
        SessionsDebug
    }
}

fn main() {
    let arguments = App::new("Varnish VSL log to syslog logger")
        .version(crate_version!())
        .author(crate_authors!())
        .about("Reads binary VSL log entreis, correlates them togeter and emits JSON log entry to syslog")
        .arg(Arg::with_name("v3")
             .long("varnish-v3")
             .short("3")
             .help("Parse Varnish v3 binary log"))
        .arg(Arg::with_name("quiet")
             .long("quiet")
             .short("q")
             .help("Don't log anything"))
        .arg(Arg::with_name("verbose")
             .long("verbose")
             .short("v")
             .help("Sets the level of verbosity; e.g. -vv for INFO level, -vvvv for TRACE level")
             .multiple(true))
        .arg(Arg::with_name("output")
             .long("output-format")
             .short("o")
             .help("Format of the output")
             .takes_value(true)
             .possible_values(&OutputFormat::variants())
             .default_value(OutputFormat::variants().last().unwrap()))
        .get_matches();

    stderrlog::new()
        .module(module_path!())
        .quiet(arguments.is_present("quiet"))
        .verbosity(arguments.occurrences_of("verbose") as usize)
        .init()
        .unwrap();

    let output_format = value_t!(arguments, "output", OutputFormat).unwrap_or_else(|e| e.exit());

    let stdin = stdin();
    let stdin = stdin.lock();
    // for testing
    //let mut rfb = ReadStreamBuf::with_capacity(stdin, 123);
    let mut rfb = ReadStreamBuf::new(stdin);

    let vsl_record: fn(&[u8]) -> nom::IResult<&[u8], VslRecord>;

    if ! arguments.is_present("v3") {
        loop {
            match rfb.fill_apply(binary_vsl_tag) {
                Err(FillApplyError::Parser(_)) => {
                    error!("Input is not Varnish v4 VSL binary format");
                    panic!("Bad input format")
                }
                Err(err) => {
                    error!("Error while reading VSL tag: {}", err);
                    panic!("VSL tag error")
                }
                Ok(None) => continue,
                Ok(Some(_)) => break,
            }
        }
        vsl_record = vsl_record_v4;
    } else {
        vsl_record = vsl_record_v3;
    }

    rfb.recycle(); // TODO: VSL should benefit from alignment - bench test it

    let mut record_state = RecordState::new();
    let mut session_state = SessionState::new();

    loop {
        let record = match rfb.fill_apply(vsl_record) {
            Err(FillApplyError::FillError(FillError::Io(err))) => {
                if err.kind() == io::ErrorKind::UnexpectedEof {
                    info!("Reached end of stream");
                    break
                }
                error!("Got IO Error while reading stream: {}", err);
                panic!("Stream IO error")
            },
            Err(FillApplyError::FillError(err)) => {
                error!("Failed to fill parsing buffer: {}", err);
                panic!("Fill error")
            }
            Err(FillApplyError::Parser(err)) => {
                error!("Failed to parse VSL record: {}", err);
                panic!("Parser error")
            },
            Ok(None) => continue,
            Ok(Some(record)) => record,
        };

        match output_format {
            OutputFormat::LogEntries => println!("{}", record),
            OutputFormat::RecordsDebug => {
                if let Some(record) = record_state.apply(&record) {
                    println!("{:#?}", record)
                }
            }
            OutputFormat::SessionsDebug => {
                if let Some(session) = session_state.apply(&record) {
                    println!("{:#?}", session)
                }
            }
        }
    }

    for client in session_state.unmatched_client_access_records() {
        warn!("ClientAccessRecord without matching session left: {:?}", client)
    }

    for backend in session_state.unmatched_backend_access_records() {
        warn!("BackendAccessRecord without matching session left: {:?}", backend)
    }

    info!("Done");
}
<|endoftext|>


<commit_before>extern crate toml;

use std::env;
use std::fs::File;
use std::io::prelude::*;

fn main() {
    let cmd = std::env::args().nth(1).expect("not enought arguments");

    // dermine config file path (env variable, then default)
    let config_file = env::var("RESH_CONFIG")
        .unwrap_or("/etc/resh.yml".to_string());

    // load allowed command definitions from file -> exit on failure
    let mut contents = String::new();
    File::open(config_file)
        .unwrap_or_else(|e| {
            println!("Failed to open file: {}", e);
            std::process::exit(1)
        })
        .read_to_string(&mut contents)
        .unwrap_or_else(|e| {
            println!("Failed to read file: {}", e);
            std::process::exit(1)
        });
    let config = contents.parse::<toml::Value>()
        .unwrap_or_else(|e| {
            println!("Failed to parse file: {}", e);
            std::process::exit(1)
        });

    let commands = config["commands"]
        .as_table()
        .unwrap();

    if !commands.contains_key(&cmd) {
        println!("No such command definition");
        std::process::exit(1);
    }

    let command = match commands.get(&cmd) {
        Some(bla) => bla,
        None => {
            println!("Failed to get definition of command {}", cmd);
            std::process::exit(1)
        }
    };

    println!("Executing: {}", command);

    let mut child = std::process::Command::new("/bin/sh")
        .arg("-c")
        .arg(command.as_str().unwrap())
        .spawn()
        .expect("failed to execute child");

    let result = child
        .wait()
        .expect("failed to wait on child");

    std::process::exit(result.code().unwrap());
}
<commit_msg>Print errors to stderr<commit_after>extern crate toml;

use std::env;
use std::fs::File;
use std::io::prelude::*;

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

fn main() {
    let cmd = std::env::args().nth(1).expect("not enought arguments");

    // dermine config file path (env variable, then default)
    let config_file = env::var("RESH_CONFIG")
        .unwrap_or_else(|_| {"/etc/resh.yml".to_string()});

    // load allowed command definitions from file -> exit on failure
    let mut contents = String::new();
    File::open(config_file)
        .unwrap_or_else(|e| {
            eprintln!("Failed to open file: {}", e);
            std::process::exit(1)
        })
        .read_to_string(&mut contents)
        .unwrap_or_else(|e| {
            eprintln!("Failed to read file: {}", e);
            std::process::exit(1)
        });
    let config = contents.parse::<toml::Value>()
        .unwrap_or_else(|e| {
            eprintln!("Failed to parse file: {}", e);
            std::process::exit(1)
        });

    let commands = config["commands"]
        .as_table()
        .unwrap();

    if !commands.contains_key(&cmd) {
        eprintln!("No such command definition");
        std::process::exit(1);
    }

    let command = match commands.get(&cmd) {
        Some(bla) => bla,
        None => {
            eprintln!("Failed to get definition of command {}", cmd);
            std::process::exit(1)
        }
    };

    println!("Executing: {}", command);

    let mut child = std::process::Command::new("/bin/sh")
        .arg("-c")
        .arg(command.as_str().unwrap())
        .spawn()
        .expect("failed to execute child");

    let result = child
        .wait()
        .expect("failed to wait on child");

    std::process::exit(result.code().unwrap());
}
<|endoftext|>


<commit_before>fn main() {
    println!("{}", check());
}

#[cfg(target_arch = "x86_64")]
fn check() -> bool {
    std::mem::size_of::<usize>() == 8
}

#[cfg(target_arch = "i686")]
fn check() -> bool {
    std::mem::size_of::<usize>() == 4
}

#[test]
fn ok() {
    assert!(check());
}
<commit_msg>Use cfg<commit_after>fn main() {
    println!("{}", check());
}

#[cfg(target_arch = "x86_64")]
fn check() -> bool {
    std::mem::size_of::<usize>() == 8
}

#[cfg(not(target_arch = "x86_64"))]
fn check() -> bool {
    std::mem::size_of::<usize>() == 4
}

#[test]
fn ok() {
    assert!(check());
}
<|endoftext|>


<commit_before>use crate::exercise::{Exercise, ExerciseList};
use crate::run::run;
use crate::verify::verify;
use clap::{crate_version, App, Arg, SubCommand};
use notify::DebouncedEvent;
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::ffi::OsStr;
use std::fs;
use std::io::BufRead;
use std::path::Path;
use std::sync::mpsc::channel;
use std::time::Duration;
use syntect::easy::HighlightFile;
use syntect::highlighting::{Style, ThemeSet};
use syntect::parsing::SyntaxSet;
use syntect::util::as_24_bit_terminal_escaped;

mod exercise;
mod run;
mod verify;

fn main() {
    let matches = App::new("rustlings")
        .version(crate_version!())
        .author("Olivia Hugger, Carol Nichols")
        .about("Rustlings is a collection of small exercises to get you used to writing and reading Rust code")
        .subcommand(SubCommand::with_name("verify").alias("v").about("Verifies all exercises according to the recommended order"))
        .subcommand(SubCommand::with_name("watch").alias("w").about("Reruns `verify` when files were edited"))
        .subcommand(
            SubCommand::with_name("run")
                .alias("r")
                .about("Runs/Tests a single exercise")
                .arg(Arg::with_name("file").required(true).index(1))
                .arg(Arg::with_name("test").short("t").long("test").help("Run the file as a test")),
        )
        .get_matches();

    let ss = SyntaxSet::load_defaults_newlines();
    let ts = ThemeSet::load_defaults();

    if None == matches.subcommand_name() {
        println!();
        println!(r#"       welcome to...                      "#);
        println!(r#"                 _   _ _                  "#);
        println!(r#"  _ __ _   _ ___| |_| (_)_ __   __ _ ___  "#);
        println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#);
        println!(r#" | |  | |_| \__ \ |_| | | | | | (_| \__ \ "#);
        println!(r#" |_|   \__,_|___/\__|_|_|_| |_|\__, |___/ "#);
        println!(r#"                               |___/      "#);
        println!();
    }

    if !Path::new("info.toml").exists() {
        println!(
            "{} must be run from the rustlings directory",
            std::env::current_exe().unwrap().to_str().unwrap()
        );
        std::process::exit(1);
    }

    let toml_str = &fs::read_to_string("info.toml").unwrap();
    let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;

    if let Some(ref matches) = matches.subcommand_matches("run") {
        let filename = matches.value_of("file").unwrap_or_else(|| {
            println!("Please supply a file name!");
            std::process::exit(1);
        });

        let filepath = Path::new(filename).canonicalize().unwrap();
        let exercise = exercises
            .iter()
            .find(|e| filepath.ends_with(&e.path))
            .unwrap_or_else(|| {
                println!("No exercise found for your file name!");
                std::process::exit(1)
            });

        run(&exercise).unwrap_or_else(|_| std::process::exit(1));
    }

    if matches.subcommand_matches("verify").is_some() {
        verify(&exercises).unwrap_or_else(|_| std::process::exit(1));
    }

    if matches.subcommand_matches("watch").is_some() {
        watch(&exercises).unwrap();
    }

    if matches.subcommand_name().is_none() {
        let mut highlighter =
            HighlightFile::new("default_out.md", &ss, &ts.themes["base16-eighties.dark"]).unwrap();
        for maybe_line in highlighter.reader.lines() {
            let line = maybe_line.unwrap();
            let regions: Vec<(Style, &str)> = highlighter.highlight_lines.highlight(&line, &ss);
            println!("{}", as_24_bit_terminal_escaped(&regions[..], true));
        }
    }

    println!("\x1b[0m");
}

fn watch(exercises: &[Exercise]) -> notify::Result<()> {
    let (tx, rx) = channel();

    let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_secs(2))?;
    watcher.watch(Path::new("./exercises"), RecursiveMode::Recursive)?;

    let _ignored = verify(exercises.iter());

    loop {
        match rx.recv() {
            Ok(event) => match event {
                DebouncedEvent::Create(b) | DebouncedEvent::Chmod(b) | DebouncedEvent::Write(b) => {
                    if b.extension() == Some(OsStr::new("rs")) {
                        println!("----------**********----------\n");
                        let filepath = b.as_path().canonicalize().unwrap();
                        let exercise = exercises
                            .iter()
                            .skip_while(|e| !filepath.ends_with(&e.path));
                        let _ignored = verify(exercise);
                    }
                }
                _ => {}
            },
            Err(e) => println!("watch error: {:?}", e),
        }
    }
}
<commit_msg>Remove unwrap on canonicalize result<commit_after>use crate::exercise::{Exercise, ExerciseList};
use crate::run::run;
use crate::verify::verify;
use clap::{crate_version, App, Arg, SubCommand};
use notify::DebouncedEvent;
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
use std::ffi::OsStr;
use std::fs;
use std::io::BufRead;
use std::path::Path;
use std::sync::mpsc::channel;
use std::time::Duration;
use syntect::easy::HighlightFile;
use syntect::highlighting::{Style, ThemeSet};
use syntect::parsing::SyntaxSet;
use syntect::util::as_24_bit_terminal_escaped;

mod exercise;
mod run;
mod verify;

fn main() {
    let matches = App::new("rustlings")
        .version(crate_version!())
        .author("Olivia Hugger, Carol Nichols")
        .about("Rustlings is a collection of small exercises to get you used to writing and reading Rust code")
        .subcommand(SubCommand::with_name("verify").alias("v").about("Verifies all exercises according to the recommended order"))
        .subcommand(SubCommand::with_name("watch").alias("w").about("Reruns `verify` when files were edited"))
        .subcommand(
            SubCommand::with_name("run")
                .alias("r")
                .about("Runs/Tests a single exercise")
                .arg(Arg::with_name("file").required(true).index(1))
                .arg(Arg::with_name("test").short("t").long("test").help("Run the file as a test")),
        )
        .get_matches();

    let ss = SyntaxSet::load_defaults_newlines();
    let ts = ThemeSet::load_defaults();

    if None == matches.subcommand_name() {
        println!();
        println!(r#"       welcome to...                      "#);
        println!(r#"                 _   _ _                  "#);
        println!(r#"  _ __ _   _ ___| |_| (_)_ __   __ _ ___  "#);
        println!(r#" | '__| | | / __| __| | | '_ \ / _` / __| "#);
        println!(r#" | |  | |_| \__ \ |_| | | | | | (_| \__ \ "#);
        println!(r#" |_|   \__,_|___/\__|_|_|_| |_|\__, |___/ "#);
        println!(r#"                               |___/      "#);
        println!();
    }

    if !Path::new("info.toml").exists() {
        println!(
            "{} must be run from the rustlings directory",
            std::env::current_exe().unwrap().to_str().unwrap()
        );
        std::process::exit(1);
    }

    let toml_str = &fs::read_to_string("info.toml").unwrap();
    let exercises = toml::from_str::<ExerciseList>(toml_str).unwrap().exercises;

    if let Some(ref matches) = matches.subcommand_matches("run") {
        let filename = matches.value_of("file").unwrap_or_else(|| {
            println!("Please supply a file name!");
            std::process::exit(1);
        });

        let matching_exercise = |e: &&Exercise| {
            Path::new(filename)
                .canonicalize()
                .map(|p| p.ends_with(&e.path))
                .unwrap_or(false)
        };

        let exercise = exercises.iter().find(matching_exercise).unwrap_or_else(|| {
            println!("No exercise found for your file name!");
            std::process::exit(1)
        });

        run(&exercise).unwrap_or_else(|_| std::process::exit(1));
    }

    if matches.subcommand_matches("verify").is_some() {
        verify(&exercises).unwrap_or_else(|_| std::process::exit(1));
    }

    if matches.subcommand_matches("watch").is_some() {
        watch(&exercises).unwrap();
    }

    if matches.subcommand_name().is_none() {
        let mut highlighter =
            HighlightFile::new("default_out.md", &ss, &ts.themes["base16-eighties.dark"]).unwrap();
        for maybe_line in highlighter.reader.lines() {
            let line = maybe_line.unwrap();
            let regions: Vec<(Style, &str)> = highlighter.highlight_lines.highlight(&line, &ss);
            println!("{}", as_24_bit_terminal_escaped(&regions[..], true));
        }
    }

    println!("\x1b[0m");
}

fn watch(exercises: &[Exercise]) -> notify::Result<()> {
    let (tx, rx) = channel();

    let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_secs(2))?;
    watcher.watch(Path::new("./exercises"), RecursiveMode::Recursive)?;

    let _ignored = verify(exercises.iter());

    loop {
        match rx.recv() {
            Ok(event) => match event {
                DebouncedEvent::Create(b) | DebouncedEvent::Chmod(b) | DebouncedEvent::Write(b) => {
                    if b.extension() == Some(OsStr::new("rs")) {
                        println!("----------**********----------\n");
                        let filepath = b.as_path().canonicalize().unwrap();
                        let exercise = exercises
                            .iter()
                            .skip_while(|e| !filepath.ends_with(&e.path));
                        let _ignored = verify(exercise);
                    }
                }
                _ => {}
            },
            Err(e) => println!("watch error: {:?}", e),
        }
    }
}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate toml;

extern crate rustc_serialize;
use rustc_serialize::json;

use std::io::{Read, Write};
use std::thread;

use hyper::Client;
use hyper::server::{Server, Request, Response};
use hyper::status::StatusCode;

// required JSON keys are non-snakecase
#[allow(non_snake_case)]
#[derive(RustcDecodable)]
pub struct SymbolRequest {
    memoryMap: Vec<(String,String)>,
    // TODO check that key actually fits in 8-bit int
    stacks: Vec<Vec<(i8,i64)>>,
    symbolSources: Vec<String>,
    version: u8,
}

fn main() {
    let address = "0.0.0.0:8080";

    println!("Listening on {}", address);
    Server::http(address).unwrap().handle(server).unwrap();
}

/**
  * Receives single HTTP requests and demuxes to symbols file fetches from S3 bucket.
  */
fn server(mut req: Request, mut res: Response) {
    match req.method {
        hyper::Post => {
            let mut res = res.start().unwrap();

            let mut buffer = String::new();
            let _ = req.read_to_string(&mut buffer);
            println!("DEBUG raw POST: {:?}", &buffer);
            let decoded: SymbolRequest = json::decode(&buffer).unwrap();

            println!("DEBUG decoded memoryMap: {:?}", decoded.memoryMap);
            println!("DEBUG decoded stacks: {:?}", decoded.stacks);
            println!("DEBUG decoded symbolSources: {:?}", decoded.symbolSources);
            println!("DEBUG decoded version: {}", decoded.version);

            let symbol_url = get_config("symbol_urls.public");
            let symbols = client(symbol_url, decoded.memoryMap);
            let _ = res.write_all(symbols.as_bytes());

            res.end().unwrap();
        },
        _ => { *res.status_mut() = StatusCode::MethodNotAllowed },
    }
}

/**
  * Creates multiple client connections and aggregates result.
  */
fn client(url: String, memory_map: Vec<(String,String)>) -> String {
    let mut handles = vec![];
    for (debug_file, debug_id) in memory_map {
        let pdb = debug_file.find(".pdb").unwrap();
        let (symbol_name, _) = debug_file.split_at(pdb);
        let symbol_file = format!("{}.sym", symbol_name);
        let this_url = format!("{}/{}/{}/{}", url, debug_file, debug_id, symbol_file);

        // TODO decide min/max possible threads, possibly based on number of cores?
        // TODO most of the time is spent waiting on I/O, maybe async would be more appropriate?
        handles.push(thread::spawn(move || {
            let c = Client::new();
            let mut res = c.get(&this_url).send().unwrap();
            let mut body = String::new();
            let _ = res.read_to_string(&mut body);

            (symbol_file, body)
        }));
    }

    let mut result = String::new();

    for handle in handles {
        let (symbol_file, body) = handle.join().unwrap();
        for c in format!("{:?} {:?}\n", symbol_file, body).chars() {
            result.push(c);
        }
    }

    result
}

fn get_config(value_name: &str) -> String {
    // TODO move to actual file, static str for the moment
    let toml: &'static str = r#"
        [symbol_urls]
        public = "https://s3-us-west-2.amazonaws.com/org.mozilla.crash-stats.symbols-public/v1"
    "#;
    // TODO support multiple URLs
    let value: toml::Value = toml.parse().unwrap();

    value.lookup(value_name).unwrap().as_str().unwrap().to_string()
}
<commit_msg>formatting and comments<commit_after>extern crate hyper;
extern crate rustc_serialize;
extern crate toml;

use std::fs::File;
use std::io::{Read, Write};
use std::thread;

use hyper::Client;
use hyper::server::{Server, Request, Response};
use hyper::status::StatusCode;

use rustc_serialize::json;

// required JSON keys are non-snakecase
#[allow(non_snake_case)]
#[derive(RustcDecodable)]
pub struct SymbolRequest {
    memoryMap: Vec<(String,String)>,
    // TODO check that key actually fits in 8-bit int
    stacks: Vec<Vec<(i8,i64)>>,
    symbolSources: Vec<String>,
    version: u8,
}

fn main() {
    let address = "0.0.0.0:8080";

    println!("Listening on {}", address);
    Server::http(address).unwrap().handle(server).unwrap();
}

/**
  * Receives single HTTP requests and demuxes to symbols file fetches from S3 bucket.
  */
fn server(mut req: Request, mut res: Response) {
    println!("DEBUG: incoming connection");

    match req.method {
        hyper::Post => {
            let mut res = res.start().unwrap();

            let mut buffer = String::new();
            let _ = req.read_to_string(&mut buffer);
            println!("DEBUG raw POST: {:?}", &buffer);

            let decoded: SymbolRequest = json::decode(&buffer).unwrap();

            println!("DEBUG decoded memoryMap: {:?}", decoded.memoryMap);
            println!("DEBUG decoded stacks: {:?}", decoded.stacks);
            println!("DEBUG decoded symbolSources: {:?}", decoded.symbolSources);
            println!("DEBUG decoded version: {}", decoded.version);

            let symbol_url = get_config("symbol_urls.public");
            let symbols = client(symbol_url, decoded.memoryMap);
            let _ = res.write_all(symbols.as_bytes());

            res.end().unwrap();
            println!("DEBUG finished");
        },
        _ => { *res.status_mut() = StatusCode::MethodNotAllowed },
    }
}

/**
  * Creates multiple client connections and aggregates result.
  */
fn client(url: String, memory_map: Vec<(String,String)>) -> String {
    let mut handles = vec![];

    for (debug_file, debug_id) in memory_map {
        let pdb = debug_file.find(".pdb").unwrap();
        let (symbol_name, _) = debug_file.split_at(pdb);
        let symbol_file = format!("{}.sym", symbol_name);
        let this_url = format!("{}/{}/{}/{}", url, debug_file, debug_id, symbol_file);

        // TODO most of the time is spent waiting on I/O, maybe async would be more appropriate?
        // TODO decide min/max possible threads, possibly based on number of cores?
        handles.push(thread::spawn(move || {
            let mut body = String::new();
            let c = Client::new();
            let mut res = c.get(&this_url).send().unwrap();
            let _ = res.read_to_string(&mut body);

            (symbol_file, body)
        }));
    }

    let mut result = String::new();

    for handle in handles {
        let (symbol_file, body) = handle.join().unwrap();

        for c in format!("{:?} {:?}\n", symbol_file, body).chars() {
            result.push(c);
        }
    }

    result
}

fn get_config(value_name: &str) -> String {
    // TODO move to actual file, static str for the moment
    let toml: &'static str = r#"
        [symbol_urls]
        public = "https://s3-us-west-2.amazonaws.com/org.mozilla.crash-stats.symbols-public/v1"
    "#;
    // TODO support multiple URLs
    let value: toml::Value = toml.parse().unwrap();

    value.lookup(value_name).unwrap().as_str().unwrap().to_string()
}
<|endoftext|>


<commit_before>mod app;
mod error;
mod exec;
mod exit_codes;
mod filesystem;
mod filetypes;
mod filter;
mod options;
mod output;
mod regex_helper;
mod walk;

use std::env;
use std::path::{Path, PathBuf};
use std::process;
use std::sync::Arc;
use std::time;

use anyhow::{anyhow, Context, Result};
use atty::Stream;
use globset::GlobBuilder;
use lscolors::LsColors;
use regex::bytes::{RegexBuilder, RegexSetBuilder};

use crate::exec::CommandTemplate;
use crate::exit_codes::ExitCode;
use crate::filetypes::FileTypes;
use crate::filter::{SizeFilter, TimeFilter};
use crate::options::Options;
use crate::regex_helper::pattern_has_uppercase_char;

// We use jemalloc for performance reasons, see https://github.com/sharkdp/fd/pull/481
#[cfg(all(not(windows), not(target_env = "musl")))]
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;

fn run() -> Result<ExitCode> {
    let matches = app::build_app().get_matches_from(env::args_os());

    // Set the current working directory of the process
    if let Some(base_directory) = matches.value_of_os("base-directory") {
        let base_directory = Path::new(base_directory);
        if !filesystem::is_dir(base_directory) {
            return Err(anyhow!(
                "The '--base-directory' path '{}' is not a directory.",
                base_directory.to_string_lossy()
            ));
        }
        env::set_current_dir(base_directory).with_context(|| {
            format!(
                "Could not set '{}' as the current working directory.",
                base_directory.to_string_lossy()
            )
        })?;
    }

    let current_directory = Path::new(".");
    if !filesystem::is_dir(current_directory) {
        return Err(anyhow!(
            "Could not retrieve current directory (has it been deleted?)."
        ));
    }

    // Get the search pattern
    let pattern = matches
        .value_of_os("pattern")
        .map(|p| {
            p.to_str().ok_or(anyhow!(
                "The search pattern includes invalid UTF-8 sequences."
            ))
        })
        .transpose()?
        .unwrap_or("");

    // Get one or more root directories to search.
    let mut dir_vec: Vec<_> = match matches
        .values_of_os("path")
        .or_else(|| matches.values_of_os("search-path"))
    {
        Some(paths) => paths
            .map(|path| {
                let path_buffer = PathBuf::from(path);
                if filesystem::is_dir(&path_buffer) {
                    Ok(path_buffer)
                } else {
                    Err(anyhow!(
                        "Search path '{}' is not a directory.",
                        path_buffer.to_string_lossy()
                    ))
                }
            })
            .collect::<Result<Vec<_>>>()?,
        None => vec![current_directory.to_path_buf()],
    };

    if matches.is_present("absolute-path") {
        dir_vec = dir_vec
            .iter()
            .map(|path_buffer| {
                path_buffer
                    .canonicalize()
                    .and_then(|pb| filesystem::absolute_path(pb.as_path()))
                    .unwrap()
            })
            .collect();
    }

    // Detect if the user accidentally supplied a path instead of a search pattern
    if !matches.is_present("full-path")
        && pattern.contains(std::path::MAIN_SEPARATOR)
        && filesystem::is_dir(Path::new(pattern))
    {
        return Err(anyhow!(
            "The search pattern '{pattern}' contains a path-separation character ('{sep}') \
             and will not lead to any search results.\n\n\
             If you want to search for all files inside the '{pattern}' directory, use a match-all pattern:\n\n  \
             fd . '{pattern}'\n\n\
             Instead, if you want your pattern to match the full file path, use:\n\n  \
             fd --full-path '{pattern}'",
            pattern = pattern,
            sep = std::path::MAIN_SEPARATOR,
        ));
    }

    let pattern_regex = if matches.is_present("glob") {
        let glob = GlobBuilder::new(pattern).literal_separator(true).build()?;
        glob.regex().to_owned()
    } else if matches.is_present("fixed-strings") {
        // Treat pattern as literal string if '--fixed-strings' is used
        regex::escape(pattern)
    } else {
        String::from(pattern)
    };

    // The search will be case-sensitive if the command line flag is set or
    // if the pattern has an uppercase character (smart case).
    let case_sensitive = !matches.is_present("ignore-case")
        && (matches.is_present("case-sensitive") || pattern_has_uppercase_char(&pattern_regex));

    let interactive_terminal = atty::is(Stream::Stdout);
    let colored_output = match matches.value_of("color") {
        Some("always") => true,
        Some("never") => false,
        _ => env::var_os("NO_COLOR").is_none() && interactive_terminal,
    };

    let path_separator = matches.value_of("path-separator").map(|str| str.to_owned());

    #[cfg(windows)]
    let colored_output = colored_output && ansi_term::enable_ansi_support().is_ok();

    let ls_colors = if colored_output {
        Some(LsColors::from_env().unwrap_or_default())
    } else {
        None
    };

    let command = if let Some(args) = matches.values_of("exec") {
        Some(CommandTemplate::new(args))
    } else if let Some(args) = matches.values_of("exec-batch") {
        Some(CommandTemplate::new_batch(args)?)
    } else if matches.is_present("list-details") {
        let color = matches.value_of("color").unwrap_or("auto");
        let color_arg = ["--color=", color].concat();

        Some(
            CommandTemplate::new_batch(&[
                "ls",
                "-l",               // long listing format
                "--human-readable", // human readable file sizes
                "--directory",      // list directories themselves, not their contents
                &color_arg,         // enable colorized output, if enabled
            ])
            .unwrap(),
        )
    } else {
        None
    };

    let size_limits = if let Some(vs) = matches.values_of("size") {
        vs.map(|sf| {
            SizeFilter::from_string(sf).ok_or(anyhow!(
                "'{}' is not a valid size constraint. See 'fd --help'.",
                sf
            ))
        })
        .collect::<Result<Vec<_>>>()?
    } else {
        vec![]
    };

    let now = time::SystemTime::now();
    let mut time_constraints: Vec<TimeFilter> = Vec::new();
    if let Some(t) = matches.value_of("changed-within") {
        if let Some(f) = TimeFilter::after(&now, t) {
            time_constraints.push(f);
        } else {
            return Err(anyhow!(
                "'{}' is not a valid date or duration. See 'fd --help'.",
                t
            ));
        }
    }
    if let Some(t) = matches.value_of("changed-before") {
        if let Some(f) = TimeFilter::before(&now, t) {
            time_constraints.push(f);
        } else {
            return Err(anyhow!(
                "'{}' is not a valid date or duration. See 'fd --help'.",
                t
            ));
        }
    }

    let config = Options {
        case_sensitive,
        search_full_path: matches.is_present("full-path"),
        ignore_hidden: !(matches.is_present("hidden")
            || matches.occurrences_of("rg-alias-hidden-ignore") >= 2),
        read_fdignore: !(matches.is_present("no-ignore")
            || matches.is_present("rg-alias-hidden-ignore")),
        read_vcsignore: !(matches.is_present("no-ignore")
            || matches.is_present("rg-alias-hidden-ignore")
            || matches.is_present("no-ignore-vcs")),
        follow_links: matches.is_present("follow"),
        one_file_system: matches.is_present("one-file-system"),
        null_separator: matches.is_present("null_separator"),
        max_depth: matches
            .value_of("max-depth")
            .or_else(|| matches.value_of("rg-depth"))
            .or_else(|| matches.value_of("exact-depth"))
            .and_then(|n| usize::from_str_radix(n, 10).ok()),
        min_depth: matches
            .value_of("min-depth")
            .or_else(|| matches.value_of("exact-depth"))
            .and_then(|n| usize::from_str_radix(n, 10).ok()),
        threads: std::cmp::max(
            matches
                .value_of("threads")
                .and_then(|n| usize::from_str_radix(n, 10).ok())
                .unwrap_or_else(num_cpus::get),
            1,
        ),
        max_buffer_time: matches
            .value_of("max-buffer-time")
            .and_then(|n| u64::from_str_radix(n, 10).ok())
            .map(time::Duration::from_millis),
        ls_colors,
        interactive_terminal,
        file_types: matches.values_of("file-type").map(|values| {
            let mut file_types = FileTypes::default();
            for value in values {
                match value {
                    "f" | "file" => file_types.files = true,
                    "d" | "directory" => file_types.directories = true,
                    "l" | "symlink" => file_types.symlinks = true,
                    "x" | "executable" => {
                        file_types.executables_only = true;
                        file_types.files = true;
                    }
                    "e" | "empty" => {
                        file_types.empty_only = true;
                    }
                    _ => unreachable!(),
                }
            }

            // If only 'empty' was specified, search for both files and directories:
            if file_types.empty_only && !(file_types.files || file_types.directories) {
                file_types.files = true;
                file_types.directories = true;
            }

            file_types
        }),
        extensions: matches
            .values_of("extension")
            .map(|exts| {
                let patterns = exts
                    .map(|e| e.trim_start_matches('.'))
                    .map(|e| format!(r".\.{}$", regex::escape(e)));
                RegexSetBuilder::new(patterns)
                    .case_insensitive(true)
                    .build()
            })
            .transpose()?,
        command: command.map(Arc::new),
        exclude_patterns: matches
            .values_of("exclude")
            .map(|v| v.map(|p| String::from("!") + p).collect())
            .unwrap_or_else(|| vec![]),
        ignore_files: matches
            .values_of("ignore-file")
            .map(|vs| vs.map(PathBuf::from).collect())
            .unwrap_or_else(|| vec![]),
        size_constraints: size_limits,
        time_constraints,
        show_filesystem_errors: matches.is_present("show-errors"),
        path_separator,
        max_results: matches
            .value_of("max-results")
            .and_then(|n| usize::from_str_radix(n, 10).ok())
            .filter(|&n| n != 0)
            .or_else(|| {
                if matches.is_present("max-one-result") {
                    Some(1)
                } else {
                    None
                }
            }),
    };

    let re = RegexBuilder::new(&pattern_regex)
        .case_insensitive(!config.case_sensitive)
        .dot_matches_new_line(true)
        .build()
        .map_err(|e| {
            anyhow!(
                "{}\n\nNote: You can use the '--fixed-strings' option to search for a \
                 literal string instead of a regular expression. Alternatively, you can \
                 also use the '--glob' option to match on a glob pattern.",
                e.to_string()
            )
        })?;

    walk::scan(&dir_vec, Arc::new(re), Arc::new(config))
}

fn main() {
    let result = run();
    match result {
        Ok(exit_code) => {
            process::exit(exit_code.into());
        }
        Err(err) => {
            eprintln!("[fd error]: {}", err);
            process::exit(ExitCode::GeneralError.into());
        }
    }
}
<commit_msg>Always enable colors on Windows, closes #469<commit_after>mod app;
mod error;
mod exec;
mod exit_codes;
mod filesystem;
mod filetypes;
mod filter;
mod options;
mod output;
mod regex_helper;
mod walk;

use std::env;
use std::path::{Path, PathBuf};
use std::process;
use std::sync::Arc;
use std::time;

use anyhow::{anyhow, Context, Result};
use atty::Stream;
use globset::GlobBuilder;
use lscolors::LsColors;
use regex::bytes::{RegexBuilder, RegexSetBuilder};

use crate::exec::CommandTemplate;
use crate::exit_codes::ExitCode;
use crate::filetypes::FileTypes;
use crate::filter::{SizeFilter, TimeFilter};
use crate::options::Options;
use crate::regex_helper::pattern_has_uppercase_char;

// We use jemalloc for performance reasons, see https://github.com/sharkdp/fd/pull/481
#[cfg(all(not(windows), not(target_env = "musl")))]
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;

fn run() -> Result<ExitCode> {
    let matches = app::build_app().get_matches_from(env::args_os());

    // Set the current working directory of the process
    if let Some(base_directory) = matches.value_of_os("base-directory") {
        let base_directory = Path::new(base_directory);
        if !filesystem::is_dir(base_directory) {
            return Err(anyhow!(
                "The '--base-directory' path '{}' is not a directory.",
                base_directory.to_string_lossy()
            ));
        }
        env::set_current_dir(base_directory).with_context(|| {
            format!(
                "Could not set '{}' as the current working directory.",
                base_directory.to_string_lossy()
            )
        })?;
    }

    let current_directory = Path::new(".");
    if !filesystem::is_dir(current_directory) {
        return Err(anyhow!(
            "Could not retrieve current directory (has it been deleted?)."
        ));
    }

    // Get the search pattern
    let pattern = matches
        .value_of_os("pattern")
        .map(|p| {
            p.to_str().ok_or(anyhow!(
                "The search pattern includes invalid UTF-8 sequences."
            ))
        })
        .transpose()?
        .unwrap_or("");

    // Get one or more root directories to search.
    let mut dir_vec: Vec<_> = match matches
        .values_of_os("path")
        .or_else(|| matches.values_of_os("search-path"))
    {
        Some(paths) => paths
            .map(|path| {
                let path_buffer = PathBuf::from(path);
                if filesystem::is_dir(&path_buffer) {
                    Ok(path_buffer)
                } else {
                    Err(anyhow!(
                        "Search path '{}' is not a directory.",
                        path_buffer.to_string_lossy()
                    ))
                }
            })
            .collect::<Result<Vec<_>>>()?,
        None => vec![current_directory.to_path_buf()],
    };

    if matches.is_present("absolute-path") {
        dir_vec = dir_vec
            .iter()
            .map(|path_buffer| {
                path_buffer
                    .canonicalize()
                    .and_then(|pb| filesystem::absolute_path(pb.as_path()))
                    .unwrap()
            })
            .collect();
    }

    // Detect if the user accidentally supplied a path instead of a search pattern
    if !matches.is_present("full-path")
        && pattern.contains(std::path::MAIN_SEPARATOR)
        && filesystem::is_dir(Path::new(pattern))
    {
        return Err(anyhow!(
            "The search pattern '{pattern}' contains a path-separation character ('{sep}') \
             and will not lead to any search results.\n\n\
             If you want to search for all files inside the '{pattern}' directory, use a match-all pattern:\n\n  \
             fd . '{pattern}'\n\n\
             Instead, if you want your pattern to match the full file path, use:\n\n  \
             fd --full-path '{pattern}'",
            pattern = pattern,
            sep = std::path::MAIN_SEPARATOR,
        ));
    }

    let pattern_regex = if matches.is_present("glob") {
        let glob = GlobBuilder::new(pattern).literal_separator(true).build()?;
        glob.regex().to_owned()
    } else if matches.is_present("fixed-strings") {
        // Treat pattern as literal string if '--fixed-strings' is used
        regex::escape(pattern)
    } else {
        String::from(pattern)
    };

    // The search will be case-sensitive if the command line flag is set or
    // if the pattern has an uppercase character (smart case).
    let case_sensitive = !matches.is_present("ignore-case")
        && (matches.is_present("case-sensitive") || pattern_has_uppercase_char(&pattern_regex));

    let interactive_terminal = atty::is(Stream::Stdout);
    let colored_output = match matches.value_of("color") {
        Some("always") => true,
        Some("never") => false,
        _ => env::var_os("NO_COLOR").is_none() && interactive_terminal,
    };

    let path_separator = matches.value_of("path-separator").map(|str| str.to_owned());

    #[cfg(windows)]
    ansi_term::enable_ansi_support().ok();

    let ls_colors = if colored_output {
        Some(LsColors::from_env().unwrap_or_default())
    } else {
        None
    };

    let command = if let Some(args) = matches.values_of("exec") {
        Some(CommandTemplate::new(args))
    } else if let Some(args) = matches.values_of("exec-batch") {
        Some(CommandTemplate::new_batch(args)?)
    } else if matches.is_present("list-details") {
        let color = matches.value_of("color").unwrap_or("auto");
        let color_arg = ["--color=", color].concat();

        Some(
            CommandTemplate::new_batch(&[
                "ls",
                "-l",               // long listing format
                "--human-readable", // human readable file sizes
                "--directory",      // list directories themselves, not their contents
                &color_arg,         // enable colorized output, if enabled
            ])
            .unwrap(),
        )
    } else {
        None
    };

    let size_limits = if let Some(vs) = matches.values_of("size") {
        vs.map(|sf| {
            SizeFilter::from_string(sf).ok_or(anyhow!(
                "'{}' is not a valid size constraint. See 'fd --help'.",
                sf
            ))
        })
        .collect::<Result<Vec<_>>>()?
    } else {
        vec![]
    };

    let now = time::SystemTime::now();
    let mut time_constraints: Vec<TimeFilter> = Vec::new();
    if let Some(t) = matches.value_of("changed-within") {
        if let Some(f) = TimeFilter::after(&now, t) {
            time_constraints.push(f);
        } else {
            return Err(anyhow!(
                "'{}' is not a valid date or duration. See 'fd --help'.",
                t
            ));
        }
    }
    if let Some(t) = matches.value_of("changed-before") {
        if let Some(f) = TimeFilter::before(&now, t) {
            time_constraints.push(f);
        } else {
            return Err(anyhow!(
                "'{}' is not a valid date or duration. See 'fd --help'.",
                t
            ));
        }
    }

    let config = Options {
        case_sensitive,
        search_full_path: matches.is_present("full-path"),
        ignore_hidden: !(matches.is_present("hidden")
            || matches.occurrences_of("rg-alias-hidden-ignore") >= 2),
        read_fdignore: !(matches.is_present("no-ignore")
            || matches.is_present("rg-alias-hidden-ignore")),
        read_vcsignore: !(matches.is_present("no-ignore")
            || matches.is_present("rg-alias-hidden-ignore")
            || matches.is_present("no-ignore-vcs")),
        follow_links: matches.is_present("follow"),
        one_file_system: matches.is_present("one-file-system"),
        null_separator: matches.is_present("null_separator"),
        max_depth: matches
            .value_of("max-depth")
            .or_else(|| matches.value_of("rg-depth"))
            .or_else(|| matches.value_of("exact-depth"))
            .and_then(|n| usize::from_str_radix(n, 10).ok()),
        min_depth: matches
            .value_of("min-depth")
            .or_else(|| matches.value_of("exact-depth"))
            .and_then(|n| usize::from_str_radix(n, 10).ok()),
        threads: std::cmp::max(
            matches
                .value_of("threads")
                .and_then(|n| usize::from_str_radix(n, 10).ok())
                .unwrap_or_else(num_cpus::get),
            1,
        ),
        max_buffer_time: matches
            .value_of("max-buffer-time")
            .and_then(|n| u64::from_str_radix(n, 10).ok())
            .map(time::Duration::from_millis),
        ls_colors,
        interactive_terminal,
        file_types: matches.values_of("file-type").map(|values| {
            let mut file_types = FileTypes::default();
            for value in values {
                match value {
                    "f" | "file" => file_types.files = true,
                    "d" | "directory" => file_types.directories = true,
                    "l" | "symlink" => file_types.symlinks = true,
                    "x" | "executable" => {
                        file_types.executables_only = true;
                        file_types.files = true;
                    }
                    "e" | "empty" => {
                        file_types.empty_only = true;
                    }
                    _ => unreachable!(),
                }
            }

            // If only 'empty' was specified, search for both files and directories:
            if file_types.empty_only && !(file_types.files || file_types.directories) {
                file_types.files = true;
                file_types.directories = true;
            }

            file_types
        }),
        extensions: matches
            .values_of("extension")
            .map(|exts| {
                let patterns = exts
                    .map(|e| e.trim_start_matches('.'))
                    .map(|e| format!(r".\.{}$", regex::escape(e)));
                RegexSetBuilder::new(patterns)
                    .case_insensitive(true)
                    .build()
            })
            .transpose()?,
        command: command.map(Arc::new),
        exclude_patterns: matches
            .values_of("exclude")
            .map(|v| v.map(|p| String::from("!") + p).collect())
            .unwrap_or_else(|| vec![]),
        ignore_files: matches
            .values_of("ignore-file")
            .map(|vs| vs.map(PathBuf::from).collect())
            .unwrap_or_else(|| vec![]),
        size_constraints: size_limits,
        time_constraints,
        show_filesystem_errors: matches.is_present("show-errors"),
        path_separator,
        max_results: matches
            .value_of("max-results")
            .and_then(|n| usize::from_str_radix(n, 10).ok())
            .filter(|&n| n != 0)
            .or_else(|| {
                if matches.is_present("max-one-result") {
                    Some(1)
                } else {
                    None
                }
            }),
    };

    let re = RegexBuilder::new(&pattern_regex)
        .case_insensitive(!config.case_sensitive)
        .dot_matches_new_line(true)
        .build()
        .map_err(|e| {
            anyhow!(
                "{}\n\nNote: You can use the '--fixed-strings' option to search for a \
                 literal string instead of a regular expression. Alternatively, you can \
                 also use the '--glob' option to match on a glob pattern.",
                e.to_string()
            )
        })?;

    walk::scan(&dir_vec, Arc::new(re), Arc::new(config))
}

fn main() {
    let result = run();
    match result {
        Ok(exit_code) => {
            process::exit(exit_code.into());
        }
        Err(err) => {
            eprintln!("[fd error]: {}", err);
            process::exit(ExitCode::GeneralError.into());
        }
    }
}
<|endoftext|>


<commit_before>//! # Bearer
//!
//! bearer is a command line utility to generate Authorization HTTP header
//! for bearer tokens. See https://tools.ietf.org/html/rfc6750
//!
//! bearer comes with a `--register` that will ask you the OAuth 2.0
//! client information to initialize the access and refresh tokens.
//!
//! Afterwhat it generate a header you can path to a curl request:
//!
//! ```
//! curl -H "$(bearer client_name)" "http://<oauth2 api>" | jq
//! ```
//!

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

extern crate clap;
extern crate libc;
extern crate tilde_expand;
extern crate toml;
extern crate chrono;

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

extern crate url;
extern crate curl;
extern crate serde_json;

use std::io::Write;
mod helpers;
mod config;
mod commands;
mod results;

fn main() {
    pretty_env_logger::init().unwrap();
    match commands::start() {
        Ok(()) => {
            debug!("Command bearer ended successfully");
        }
        Err(results::BearerError::ValueError(msg)) => {
            let _ = writeln!(&mut std::io::stderr(), "ERROR: {}", msg);
            std::process::exit(1);
        }
        Err(results::BearerError::IOError(err)) => {
            let _ = writeln!(&mut std::io::stderr(), "ERROR: {}", err);
            std::process::exit(1);
        }
        Err(err) => {
            let _ = writeln!(&mut std::io::stderr(), "ERROR: {:?}", err);
            std::process::exit(101);
        }
    }
}
<commit_msg>Fix typo in logging message<commit_after>//! # Bearer
//!
//! bearer is a command line utility to generate Authorization HTTP header
//! for bearer tokens. See https://tools.ietf.org/html/rfc6750
//!
//! bearer comes with a `--register` that will ask you the OAuth 2.0
//! client information to initialize the access and refresh tokens.
//!
//! Afterwhat it generate a header you can path to a curl request:
//!
//! ```
//! curl -H "$(bearer client_name)" "http://<oauth2 api>" | jq
//! ```
//!

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

extern crate clap;
extern crate libc;
extern crate tilde_expand;
extern crate toml;
extern crate chrono;

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

extern crate url;
extern crate curl;
extern crate serde_json;

use std::io::Write;
mod helpers;
mod config;
mod commands;
mod results;

fn main() {
    pretty_env_logger::init().unwrap();
    match commands::start() {
        Ok(()) => {
            debug!("Command bearer ended succesfully");
        }
        Err(results::BearerError::ValueError(msg)) => {
            let _ = writeln!(&mut std::io::stderr(), "ERROR: {}", msg);
            std::process::exit(1);
        }
        Err(results::BearerError::IOError(err)) => {
            let _ = writeln!(&mut std::io::stderr(), "ERROR: {}", err);
            std::process::exit(1);
        }
        Err(err) => {
            let _ = writeln!(&mut std::io::stderr(), "ERROR: {:?}", err);
            std::process::exit(101);
        }
    }
}
<|endoftext|>


<commit_before>extern crate iron;
#[macro_use]
extern crate router;
extern crate persistent;
extern crate rustc_serialize;
extern crate rusqlite;
#[macro_use]
extern crate log;

mod api;
mod query;
mod mapping;
mod logger;

use std::sync::{Mutex, RwLock};
use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};
use std::fs;

use iron::prelude::*;
use iron::typemap::Key;
use rustc_serialize::json::Json;
use rusqlite::Connection;

const VERSION: &'static str = "0.1a0";

#[derive(Debug)]
struct Document {
    data: Json,
}

impl Document {
    fn from_json(data: Json) -> Document {
        Document { data: data }
    }
}

#[derive(Debug)]
struct Index {
    pub connection: Mutex<Connection>,
    pub mappings: HashMap<String, mapping::Mapping>,
    pub docs: HashMap<String, Document>,
    pub aliases: HashSet<String>,
}

impl Index {
    fn new(connection: Connection) -> Index {
        Index {
            connection: Mutex::new(connection),
            mappings: HashMap::new(),
            docs: HashMap::new(),
            aliases: HashSet::new(),
        }
    }

    fn initialise(&mut self) {
        let connection = self.connection.lock().unwrap();

        connection.execute("CREATE TABLE document (
              id              INTEGER PRIMARY KEY,
              mapping         TEXT NOT NULL,
              data            BLOB
              )", &[]).unwrap();
    }
}

struct Globals {
    pub indices_path: PathBuf,
    pub indices: RwLock<HashMap<String, Index>>,
}

impl Globals {
    fn new(indices_path: PathBuf, indices: HashMap<String, Index>) -> Globals {
        Globals {
            indices_path: indices_path,
            indices: RwLock::new(indices),
        }
    }
}

impl Key for Globals {
    type Value = Globals;
}

fn load_index(path: &Path) -> Index {
    Index::new(Connection::open(path).unwrap())
}

fn load_indices(indices_path: &Path) -> HashMap<String, Index> {
    let mut indices = HashMap::new();

    for file in fs::read_dir(&indices_path).unwrap() {
        let path = file.unwrap().path();
        let index_name: String = path.file_stem().unwrap().to_str().unwrap().to_owned();
        if path.extension().unwrap().to_str() == Some("rsi") {
            info!("Loaded index: {}", index_name);
            indices.insert(index_name, load_index(path.as_path()));
        }
    }

    indices
}

fn main() {
    println!("rsearch ({})", VERSION);
    println!("");

    logger::init().unwrap();

    let indices_path = Path::new("./indices").to_path_buf();
    let indices = load_indices(&indices_path.as_path());
    let router = api::get_router();
    let mut chain = Chain::new(router);
    chain.link(persistent::Read::<Globals>::both(Globals::new(indices_path, indices)));
    Iron::new(chain).http("localhost:9200").unwrap();
}
<commit_msg>Improved index loading on startup code<commit_after>extern crate iron;
#[macro_use]
extern crate router;
extern crate persistent;
extern crate rustc_serialize;
extern crate rusqlite;
#[macro_use]
extern crate log;

mod api;
mod query;
mod mapping;
mod logger;

use std::sync::{Mutex, RwLock};
use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};
use std::fs;

use iron::prelude::*;
use iron::typemap::Key;
use rustc_serialize::json::Json;
use rusqlite::Connection;

const VERSION: &'static str = "0.1a0";

#[derive(Debug)]
struct Document {
    data: Json,
}

impl Document {
    fn from_json(data: Json) -> Document {
        Document { data: data }
    }
}

#[derive(Debug)]
struct Index {
    pub connection: Mutex<Connection>,
    pub mappings: HashMap<String, mapping::Mapping>,
    pub docs: HashMap<String, Document>,
    pub aliases: HashSet<String>,
}

impl Index {
    fn new(connection: Connection) -> Index {
        Index {
            connection: Mutex::new(connection),
            mappings: HashMap::new(),
            docs: HashMap::new(),
            aliases: HashSet::new(),
        }
    }

    fn initialise(&mut self) {
        let connection = self.connection.lock().unwrap();

        connection.execute("CREATE TABLE document (
              id              INTEGER PRIMARY KEY,
              mapping         TEXT NOT NULL,
              data            BLOB
              )", &[]).unwrap();
    }
}

struct Globals {
    pub indices_path: PathBuf,
    pub indices: RwLock<HashMap<String, Index>>,
}

impl Globals {
    fn new(indices_path: PathBuf, indices: HashMap<String, Index>) -> Globals {
        Globals {
            indices_path: indices_path,
            indices: RwLock::new(indices),
        }
    }
}

impl Key for Globals {
    type Value = Globals;
}

fn load_index(path: &Path) -> Index {
    Index::new(Connection::open(path).unwrap())
}

fn load_indices(indices_path: &Path) -> HashMap<String, Index> {
    let mut indices = HashMap::new();

    for file in fs::read_dir(&indices_path).unwrap() {
        let path = file.unwrap().path();
        let index_name: String = path.file_stem().unwrap().to_str().unwrap().to_owned();

        if let Some(ext) = path.extension() {
            if ext.to_str() == Some("rsi") {
                info!("Loaded index: {}", index_name);
                indices.insert(index_name, load_index(path.as_path()));
            }
        }
    }

    indices
}

fn main() {
    println!("rsearch ({})", VERSION);
    println!("");

    logger::init().unwrap();

    let indices_path = Path::new("./indices").to_path_buf();
    let indices = load_indices(&indices_path.as_path());
    let router = api::get_router();
    let mut chain = Chain::new(router);
    chain.link(persistent::Read::<Globals>::both(Globals::new(indices_path, indices)));
    Iron::new(chain).http("localhost:9200").unwrap();
}
<|endoftext|>


<commit_before>extern crate readline;

use readline::{readline, add_history};
use grammar::*;
use std::result::Result;

mod grammar;

fn main()
{
    loop
    {
        let result = readline("Kiss! ");
        match result
        {
            Ok(input)   =>
            {
                add_history(input.as_slice());
                for token in evaluate(input)
                {
                    match token
                    {
                        Token::Literal(x)   =>  println!("      Literal({})", x),
                        Token::Operator(_)  =>  println!("      Operator")
                    }
                }
            },
            Err(_)      => break,
        }
    }
}

fn evaluate(input: String) -> Vec<Token>
{
    input
        .split(|c: char| {c.is_whitespace()})
        .map(get_token)
        .filter(Result::is_ok)
        .map(Result::unwrap).collect()
}
<commit_msg>format<commit_after>extern crate readline;

use readline::{readline, add_history};
use grammar::*;
use std::result::Result;

mod grammar;

fn main()
{
    loop
    {
        let result = readline("Kiss! ");
        match result
        {
            Ok(input)   =>
            {
                add_history(input.as_slice());
                for token in evaluate(input)
                {
                    match token
                    {
                        Token::Literal(x)   =>  println!("      Literal({})", x),
                        Token::Operator(_)  =>  println!("      Operator")
                    }
                }
            },
            Err(_)      => break,
        }
    }
}

fn evaluate(input: String) -> Vec<Token>
{
    input
        .split(|c: char| {c.is_whitespace()})
        .map(get_token)
        .filter(Result::is_ok)
        .map(Result::unwrap)
        .collect()
}
<|endoftext|>