<commit_before>extern crate rustc_serialize;
extern crate docopt;

use std::io::{Write, BufRead};
use docopt::Docopt;

static LF: char = '\n';
static VERSION: &'static str = "0.0.1";
static USAGE: &'static str = "
Usage: wc [options] FILE...
       wc [options] --files0-from=F
       wc (-h|--help)
       wc (-v|--version)

Print newline, word, and byte counts for each FILE, and a total line if
more than one FILE is specified. With no FILE, or when FILE is -,
read standard input. A word is a non-zero-length sequence of characters
delimited by white space.
The options below may be used to select which counts are printed, always in
the following order: newline, word, character, byte, maximum line length.

Options:
   -c, --bytes            print the byte counts
   -m, --chars            print the character counts
   -l, --lines            print the newline counts
   --files0-from=F        read input from the files specified by NUL-terminated
                          names in file F; If F is - then read names from
                          standard input
   -L, --max-line-length  print the length of the longest line
   -w, --words            print the word counts
   -h, --help             display this help and quit
   -v, --version          output version information and exit
";

#[allow(non_snake_case)]
#[derive(RustcDecodable, Debug)]
struct Args {
    arg_FILE: Vec<String>,
    flag_bytes: bool,
    flag_chars: bool,
    flag_lines: bool,
    flag_max_line_length: bool,
    flag_words: bool,
    flag_help: bool,
    flag_version: bool,
    flag_files0_from: String,
}

#[derive(Debug)]
enum ProcessingError {
    IO(std::io::Error),
    Utf8(std::str::Utf8Error),
}

impl From<std::io::Error> for ProcessingError {
    fn from(e: std::io::Error) -> ProcessingError {
        ProcessingError::IO(e)
    }
}
impl From<std::str::Utf8Error> for ProcessingError {
    fn from(e: std::str::Utf8Error) -> ProcessingError {
        ProcessingError::Utf8(e)
    }
}

#[derive(Debug)]
struct FileInfo{
    bytes: usize,
    chars: usize,
    lines: usize,
    words: usize,
    max_line_length: usize,
}

type FileInfoResult = Result<FileInfo, ProcessingError>;

fn process_reader<T: std::io::Read>(reader: T) -> FileInfoResult {
    let mut info = FileInfo{
        bytes: 0,
        chars: 0,
        lines: 0,
        words: 0,
        max_line_length: 0,
    };
    // TODO: Only to as much processing as is absolutely necessary to
    // provide the data we will end up printing.
    let mut rbuf = std::io::BufReader::new(reader);
    let mut lbuf = Vec::new();
    loop {
        let size = try!(rbuf.read_until(LF as u8, &mut lbuf));
        info.bytes += size;
        if size == 0 {
            break;
        }
        // Create a scope because we're going to borrow lbuf and
        // the borrow must end before we can clear it.
        {
            let line = try!(std::str::from_utf8(&lbuf));
            let size = line.chars().count();
            info.max_line_length = match line.chars().last() {
                Some(c) => {
                    if c == LF {
                        info.lines += 1;
                        std::cmp::max(info.max_line_length, size - 1)
                    } else {
                        std::cmp::max(info.max_line_length, size)
                    }
                },
                None => std::cmp::max(info.max_line_length, size),
            };
            info.chars += size;
            let mut words: Vec<&str> = line
                .split(|c: char| c.is_whitespace())
                .collect();
            words.retain(|s: &&str| s.len() > 0);
            // words.retain(|s: &&str| s.len() > 0);
            info.words += words.len();
        }
        lbuf.clear()
    }
    Ok(info)
}

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

    if args.flag_version {
        println!("wc v{}", VERSION);
        std::process::exit(0);
    }

    if args.flag_files0_from.len() != 0  && args.arg_FILE.len() != 0 {
        match writeln!(&mut std::io::stderr(),
                       "wc: file operands cannot be combined with --files0-from") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        match writeln!(&mut std::io::stderr(),
                       "Try 'wc --help' for more information") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        std::process::exit(1);
    }

    // TODO: Process --files0-from

    let mut results = Vec::new();
    let mut totals = FileInfo{
        bytes: 0,
        chars: 0,
        lines: 0,
        words: 0,
        max_line_length: 0,
    };
    for file_arg in &args.arg_FILE {
        let filename = file_arg.as_ref();
        let result = match filename {
            "-" => process_reader(std::io::stdin()),
            _ => {
                let file = std::fs::File::open(filename.to_string());
                match file {
                    Ok(f) => process_reader(f),
                    Err(e) => Err(ProcessingError::IO(e)),
                }
            }
        };
        match result {
            Ok(ref r) => {
                totals.chars += r.chars;
                totals.lines += r.lines;
                totals.bytes += r.bytes;
                totals.words += r.words;
                totals.max_line_length = std::cmp::max(totals.max_line_length,
                                                       r.max_line_length);
            },
            Err(_) => {},
        }
        results.push((filename, result));
    }

    // This is used for formatting. The number in the byte count will
    // be the largest, and so will be the widest string, so it's
    // suitable for a field width.
    let field_size = totals.bytes.to_string().len();

    if results.len() > 1 {
        results.push(("total", Ok(totals)));
    }

    let mut errors_encountered = false;

    // Present the results
    for data in results.iter() {
        let (filename, ref result) = *data;
        match *result {
            Ok(ref r) => {
                // let mut parts = Vec::new();
                let mut requested_field = false;
                if args.flag_lines {
                    print!("{:1$} ", r.lines, field_size);
                    requested_field = true;
                }
                if args.flag_words {
                    print!("{:1$} ", r.words, field_size);
                    requested_field = true;
                }
                if args.flag_bytes {
                    print!("{:1$} ", r.bytes, field_size);
                    requested_field = true;
                }
                if args.flag_chars {
                    print!("{:1$} ", r.chars, field_size);
                    requested_field = true;
                }
                if args.flag_max_line_length {
                    print!("{:1$} ", r.max_line_length, field_size);
                    requested_field = true;
                }
                if !requested_field {
                    print!("{:1$} ", r.lines, field_size);
                    print!("{:1$} ", r.words, field_size);
                    print!("{:1$} ", r.bytes, field_size);
                }
                println!("{}", filename);
            },
            Err(ref e) => {
                errors_encountered = true;
                match *e {
                    ProcessingError::IO(ref e) => {
                        println!("wc: {}: {}", filename, e)
                    },
                    ProcessingError::Utf8(ref e) => {
                        println!("wc: {}: {}", filename, e)
                    },
                }
            },
        }
    }

    if errors_encountered {
        std::process::exit(1);
    }
}
<commit_msg>More cleanup<commit_after>extern crate rustc_serialize;
extern crate docopt;

use std::io::{Write, BufRead};
use docopt::Docopt;

static LF: char = '\n';
static VERSION: &'static str = "0.0.1";
static USAGE: &'static str = "
Usage: wc [options] FILE...
       wc [options] --files0-from=F
       wc (-h|--help)
       wc (-v|--version)

Print newline, word, and byte counts for each FILE, and a total line if
more than one FILE is specified. With no FILE, or when FILE is -,
read standard input. A word is a non-zero-length sequence of characters
delimited by white space.
The options below may be used to select which counts are printed, always in
the following order: newline, word, character, byte, maximum line length.

Options:
   -c, --bytes            print the byte counts
   -m, --chars            print the character counts
   -l, --lines            print the newline counts
   --files0-from=F        read input from the files specified by NUL-terminated
                          names in file F; If F is - then read names from
                          standard input
   -L, --max-line-length  print the length of the longest line
   -w, --words            print the word counts
   -h, --help             display this help and quit
   -v, --version          output version information and exit
";

#[allow(non_snake_case)]
#[derive(RustcDecodable, Debug)]
struct Args {
    arg_FILE: Vec<String>,
    flag_bytes: bool,
    flag_chars: bool,
    flag_lines: bool,
    flag_max_line_length: bool,
    flag_words: bool,
    flag_help: bool,
    flag_version: bool,
    flag_files0_from: String,
}

#[derive(Debug)]
enum ProcessingError {
    IO(std::io::Error),
    Utf8(std::str::Utf8Error),
}

impl From<std::io::Error> for ProcessingError {
    fn from(e: std::io::Error) -> ProcessingError {
        ProcessingError::IO(e)
    }
}
impl From<std::str::Utf8Error> for ProcessingError {
    fn from(e: std::str::Utf8Error) -> ProcessingError {
        ProcessingError::Utf8(e)
    }
}

#[derive(Debug)]
struct FileInfo{
    bytes: usize,
    chars: usize,
    lines: usize,
    words: usize,
    max_line_length: usize,
}

type FileInfoResult = Result<FileInfo, ProcessingError>;

fn process_reader<T: std::io::Read>(reader: T) -> FileInfoResult {
    let mut info = FileInfo{
        bytes: 0,
        chars: 0,
        lines: 0,
        words: 0,
        max_line_length: 0,
    };
    // TODO: Only to as much processing as is absolutely necessary to
    // provide the data we will end up printing.
    let mut rbuf = std::io::BufReader::new(reader);
    let mut lbuf = Vec::new();
    loop {
        let size = try!(rbuf.read_until(LF as u8, &mut lbuf));
        info.bytes += size;
        if size == 0 {
            break;
        }
        // Create a scope because we're going to borrow lbuf and
        // the borrow must end before we can clear it.
        {
            let line = try!(std::str::from_utf8(&lbuf));
            let size = line.chars().count();
            info.max_line_length = match line.chars().last() {
                Some(c) => {
                    if c == LF {
                        info.lines += 1;
                        std::cmp::max(info.max_line_length, size - 1)
                    } else {
                        std::cmp::max(info.max_line_length, size)
                    }
                },
                None => std::cmp::max(info.max_line_length, size),
            };
            info.chars += size;
            let mut words: Vec<&str> = line
                .split(|c: char| c.is_whitespace())
                .collect();
            words.retain(|s: &&str| s.len() > 0);
            info.words += words.len();
        }
        lbuf.clear()
    }
    Ok(info)
}

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

    if args.flag_version {
        println!("wc v{}", VERSION);
        std::process::exit(0);
    }

    if args.flag_files0_from.len() != 0  && args.arg_FILE.len() != 0 {
        match writeln!(&mut std::io::stderr(),
                       "wc: file operands cannot be combined with --files0-from") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        match writeln!(&mut std::io::stderr(),
                       "Try 'wc --help' for more information") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        std::process::exit(1);
    }

    // TODO: Process --files0-from

    let mut results = Vec::new();
    let mut totals = FileInfo{
        bytes: 0,
        chars: 0,
        lines: 0,
        words: 0,
        max_line_length: 0,
    };
    for file_arg in &args.arg_FILE {
        let filename = file_arg.as_ref();
        let result = match filename {
            "-" => process_reader(std::io::stdin()),
            _ => {
                let file = std::fs::File::open(filename.to_string());
                match file {
                    Ok(f) => process_reader(f),
                    Err(e) => Err(ProcessingError::IO(e)),
                }
            }
        };
        match result {
            Ok(ref r) => {
                totals.chars += r.chars;
                totals.lines += r.lines;
                totals.bytes += r.bytes;
                totals.words += r.words;
                totals.max_line_length = std::cmp::max(totals.max_line_length,
                                                       r.max_line_length);
            },
            Err(_) => {},
        }
        results.push((filename, result));
    }

    // This is used for formatting. The number in the byte count will
    // be the largest, and so will be the widest string, so it's
    // suitable for a field width.
    let field_size = totals.bytes.to_string().len();

    if results.len() > 1 {
        results.push(("total", Ok(totals)));
    }

    let mut errors_encountered = false;

    // Present the results
    for data in results.iter() {
        let (filename, ref result) = *data;
        match *result {
            Ok(ref r) => {
                // let mut parts = Vec::new();
                let mut requested_field = false;
                if args.flag_lines {
                    print!("{:1$} ", r.lines, field_size);
                    requested_field = true;
                }
                if args.flag_words {
                    print!("{:1$} ", r.words, field_size);
                    requested_field = true;
                }
                if args.flag_bytes {
                    print!("{:1$} ", r.bytes, field_size);
                    requested_field = true;
                }
                if args.flag_chars {
                    print!("{:1$} ", r.chars, field_size);
                    requested_field = true;
                }
                if args.flag_max_line_length {
                    print!("{:1$} ", r.max_line_length, field_size);
                    requested_field = true;
                }
                if !requested_field {
                    print!("{:1$} ", r.lines, field_size);
                    print!("{:1$} ", r.words, field_size);
                    print!("{:1$} ", r.bytes, field_size);
                }
                println!("{}", filename);
            },
            Err(ref e) => {
                errors_encountered = true;
                match *e {
                    ProcessingError::IO(ref e) => {
                        println!("wc: {}: {}", filename, e)
                    },
                    ProcessingError::Utf8(ref e) => {
                        println!("wc: {}: {}", filename, e)
                    },
                }
            },
        }
    }

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


<commit_before>use macroquad::prelude::*;

use colour::Colour;
use graph::{Graph, Position};
use grid::Grid;

mod colour;
mod graph;
mod grid;

fn macroquad_colour(colour: Colour) -> Color {
    match colour {
        Colour::Red => color_u8!(255, 0, 0, 255),
        Colour::Yellow => color_u8!(255, 255, 0, 255),
        Colour::Green => color_u8!(0, 176, 0, 255),
        Colour::LightBrown => color_u8!(255, 204, 102, 255),
        Colour::Purple => color_u8!(128, 0, 128, 255),
        Colour::Cyan => color_u8!(0, 255, 255, 255),
        Colour::Blue => color_u8!(0, 0, 255, 255),
        Colour::Fuchsia => color_u8!(255, 0, 255, 255),
    }
}

fn draw_cell(grid_x: f32, grid_y: f32, cell_size: f32, position: &Position, colour: Colour) {
    let color = macroquad_colour(colour);
    draw_rectangle(
        grid_x + cell_size * position.column as f32,
        grid_y + cell_size * position.row as f32,
        cell_size,
        cell_size,
        color,
    );
}

struct Ui {
    /// Size of the grid in cells.
    size: usize,

    /// Size of the grid in pixels.  Assumes the grid is always square.
    grid_size: f32,

    /// Offset of the grid relative to the whole window along the horizontal axis.
    grid_x: f32,

    /// Offset of the grid relative to the whole window along the vertical axis.
    grid_y: f32,
}

impl Ui {
    fn create(size: usize) -> Ui {
        let mut ui = Ui {
            size,
            grid_size: 0.0,
            grid_x: 0.0,
            grid_y: 0.0,
        };

        ui.resize();

        ui
    }

    fn resize(&mut self) {
        let screen_height = screen_height();
        let screen_width = screen_width();

        let grid_size = screen_height.min(screen_width);
        self.grid_size = grid_size;
        self.grid_x = (screen_width - grid_size) / 2.0;
        self.grid_y = (screen_height - grid_size) / 2.0;
    }

    fn render(&self, graph: &Graph) {
        clear_background(BLACK);

        let grid_x = self.grid_x;
        let grid_y = self.grid_y;
        let cell_size = self.cell_size();

        for &component in graph.neighbours.keys() {
            for position in &graph.components[component].cells {
                draw_cell(grid_x, grid_y, cell_size, position, graph.components[component].colour);
            }
        }
    }

    fn handle_click(&self, graph: &mut Graph) {
        if !is_mouse_button_pressed(MouseButton::Left) {
            return;
        }

        let (raw_x, raw_y) = mouse_position();

        let cell_size = self.cell_size();
        let x = (raw_x - self.grid_x) / cell_size;
        let y = (raw_y - self.grid_y) / cell_size;

        let size = self.size as f32;
        if x < 0.0 || y < 0.0 || x > size || y > size {
            // Out of bounds, nothing to do
            return;
        }

        let rounded_x = x.floor() as usize;
        let rounded_y = y.floor() as usize;

        let clicked_cell_position = Position {
            column: rounded_x,
            row: rounded_y,
        };
        let clicked_component = graph.find_component(clicked_cell_position);
        let colour = clicked_component.colour;

        println!("Detected click at cell ({rounded_x}, {rounded_y}) with colour {colour:#?}")
    }

    fn cell_size(&self) -> f32 {
        self.grid_size / self.size as f32
    }
}

#[macroquad::main("Flood-It")]
async fn main() {
    let size = 8;
    let grid = Grid::generate(size);
    let mut graph = Graph::create(&grid);

    let mut ui = Ui::create(size);

    loop {
        if let Some(KeyCode::Q) = get_last_key_pressed() {
            break;
        }

        ui.handle_click(&mut graph);

        ui.resize();
        ui.render(&graph);

        next_frame().await
    }
}
<commit_msg>Extract method for finding the cell position that was clicked<commit_after>use macroquad::prelude::*;

use colour::Colour;
use graph::{Graph, Position};
use grid::Grid;

mod colour;
mod graph;
mod grid;

fn macroquad_colour(colour: Colour) -> Color {
    match colour {
        Colour::Red => color_u8!(255, 0, 0, 255),
        Colour::Yellow => color_u8!(255, 255, 0, 255),
        Colour::Green => color_u8!(0, 176, 0, 255),
        Colour::LightBrown => color_u8!(255, 204, 102, 255),
        Colour::Purple => color_u8!(128, 0, 128, 255),
        Colour::Cyan => color_u8!(0, 255, 255, 255),
        Colour::Blue => color_u8!(0, 0, 255, 255),
        Colour::Fuchsia => color_u8!(255, 0, 255, 255),
    }
}

fn draw_cell(grid_x: f32, grid_y: f32, cell_size: f32, position: &Position, colour: Colour) {
    let color = macroquad_colour(colour);
    draw_rectangle(
        grid_x + cell_size * position.column as f32,
        grid_y + cell_size * position.row as f32,
        cell_size,
        cell_size,
        color,
    );
}

struct Ui {
    /// Size of the grid in cells.
    size: usize,

    /// Size of the grid in pixels.  Assumes the grid is always square.
    grid_size: f32,

    /// Offset of the grid relative to the whole window along the horizontal axis.
    grid_x: f32,

    /// Offset of the grid relative to the whole window along the vertical axis.
    grid_y: f32,
}

impl Ui {
    fn create(size: usize) -> Ui {
        let mut ui = Ui {
            size,
            grid_size: 0.0,
            grid_x: 0.0,
            grid_y: 0.0,
        };

        ui.resize();

        ui
    }

    fn resize(&mut self) {
        let screen_height = screen_height();
        let screen_width = screen_width();

        let grid_size = screen_height.min(screen_width);
        self.grid_size = grid_size;
        self.grid_x = (screen_width - grid_size) / 2.0;
        self.grid_y = (screen_height - grid_size) / 2.0;
    }

    fn render(&self, graph: &Graph) {
        clear_background(BLACK);

        let grid_x = self.grid_x;
        let grid_y = self.grid_y;
        let cell_size = self.cell_size();

        for &component in graph.neighbours.keys() {
            for position in &graph.components[component].cells {
                draw_cell(grid_x, grid_y, cell_size, position, graph.components[component].colour);
            }
        }
    }

    fn cell_position(&self, raw_position: (f32, f32)) -> Option<Position> {
        let (raw_x, raw_y) = raw_position;

        let cell_size = self.cell_size();
        let x = (raw_x - self.grid_x) / cell_size;
        let y = (raw_y - self.grid_y) / cell_size;

        let size = self.size as f32;
        if x < 0.0 || y < 0.0 || x > size || y > size {
            // Out of bounds, nothing to do
            None
        } else {
            Some(Position{column: x.floor() as usize, row: y.floor() as usize})
        }
    }

    fn handle_click(&self, graph: &mut Graph) {
        if !is_mouse_button_pressed(MouseButton::Left) {
            return;
        }

        if let Some(position) = self.cell_position(mouse_position()) {
            let clicked_component = graph.find_component(position.clone());
            let colour = clicked_component.colour;

            println!("Detected click at cell ({}, {}) with colour {:#?}", position.column, position.row, colour)
        }
    }

    fn cell_size(&self) -> f32 {
        self.grid_size / self.size as f32
    }
}

#[macroquad::main("Flood-It")]
async fn main() {
    let size = 8;
    let grid = Grid::generate(size);
    let mut graph = Graph::create(&grid);

    let mut ui = Ui::create(size);

    loop {
        if let Some(KeyCode::Q) = get_last_key_pressed() {
            break;
        }

        ui.handle_click(&mut graph);

        ui.resize();
        ui.render(&graph);

        next_frame().await
    }
}
<|endoftext|>


<commit_before>#![desc = "Constraint Satisfaction in Rust"]
#![license = "MIT"]
#![crate_id = "csar#0.2"]
#![crate_type = "lib"]

use std::fmt;
use std::cell::{Cell,RefCell};
use std::collections::hashmap::HashMap;
use std::rc::{Rc,Weak};

#[allow(dead_code)]
pub struct Mod {
    vars: RefCell<Vec<Rc<FDVar>>>,
    vars_count: Cell<uint>,
    propagators: RefCell<Vec<Rc<Box<Propagator>>>>,
    prop_count: Cell<uint>,
    waitingOnMin: RefCell<HashMap<uint, Vec<uint>>>,
    waitingOnMax: RefCell<HashMap<uint, Vec<uint>>>,
    waitingOnIns: RefCell<HashMap<uint, Vec<uint>>>
}

// cannot use type Model = Rc<Mod> since that would forbid using impl Model
pub struct Model;

/// Representation of finite domains as a list of intervals, maintaining
/// min and max for easy/quick access
#[deriving(Clone)]
struct Dom {
    min: int,
    max: int,
    intervals: Vec<(int, int)>
}

/// Runtime checked mutability with borrowing
#[deriving(Clone)]
struct Domain {
    dom: RefCell<Dom>
}

pub trait Propagator : ToStr {
    fn id(&self) -> uint;
    fn propagate(&self) -> Vec<uint>;
    fn register(&self);
    fn unregister(&self);
}

pub struct Var;

#[deriving(Clone)]
pub struct FDVar {
    model: Weak<Mod>,
    id: uint,
    name: String,
    dom: Domain
}

#[deriving(Show)]
pub enum Event {
    Min,
    Max,
    Ins
}

#[allow(dead_code)]
impl Model {
    fn new() -> Rc<Mod> {
        Rc::new(Mod {
            vars_count: Cell::new(0),
            vars: RefCell::new(Vec::new()),
            prop_count: Cell::new(0),
            propagators: RefCell::new(Vec::new()),
            waitingOnMin: RefCell::new(HashMap::new()),
            waitingOnMax: RefCell::new(HashMap::new()),
            waitingOnIns: RefCell::new(HashMap::new())
        })
    }
}

#[allow(dead_code)]
impl Mod {
    fn add_var(&self, var: Rc<FDVar>) {
        self.vars.borrow_mut().push(var);
        self.vars_count.set(self.vars_count.get() + 1);
    }

    fn add_prop(&self, prop: Rc<Box<Propagator>>) {
        self.propagators.borrow_mut().push(prop);
        self.prop_count.set(self.prop_count.get() + 1);
    }

    fn add_waiting_max(&self, var: uint, propagator: uint) {
        let mut waiting = self.waitingOnMax.borrow_mut();
        if waiting.contains_key(&var) {
            waiting.get_mut(&var).push(propagator);
        } else {
            waiting.insert(var, vec![propagator]);
        }
    }

    fn add_waiting_min(&self, var: uint, propagator: uint) {
        let mut waiting = self.waitingOnMin.borrow_mut();
        if waiting.contains_key(&var) {
            waiting.get_mut(&var).push(propagator);
        } else {
            waiting.insert(var, vec![propagator]);
        }
    }

    fn add_waiting_ins(&self, var: uint, propagator: uint) {
        let mut waiting = self.waitingOnIns.borrow_mut();
        if waiting.contains_key(&var) {
            waiting.get_mut(&var).push(propagator);
        } else {
            waiting.insert(var, vec![propagator]);
        }
    }

    fn del_waiting_max(&self, var: uint, propagator: uint) {
        self.waitingOnMax.borrow_mut().get_mut(&var).remove(propagator);
    }

    fn get_waiting_on_min(&self, var: uint) -> Vec<uint> {
        let waiting = self.waitingOnMin.borrow();
        match waiting.find_copy(&var) {
            Some(vec) => vec,
            None => Vec::new()
        }
    }

    fn get_waiting_on_max(&self, var: uint) -> Vec<uint> {
        let waiting = self.waitingOnMax.borrow();
        match waiting.find_copy(&var) {
            Some(vec) => vec,
            None => Vec::new()
        }
    }

    fn get_waiting_on_ins(&self, var: uint) -> Vec<uint> {
        let waiting = self.waitingOnIns.borrow();
        match waiting.find_copy(&var) {
            Some(vec) => vec,
            None => Vec::new()
        }
    }
}

#[allow(dead_code)]
impl Domain {
    /// Domain created with initial bounds
    fn new(min: int, max: int) -> Domain {
        Domain {
            dom: RefCell::new(Dom {
                     min: min,
                     max: max,
                     intervals: vec![(min, max)]
                 })
        }
    }

    fn set_min(&self, min: int) {
        let mut dom = self.dom.borrow_mut();
        if min < dom.min { return; }
        if min > dom.max { return; } // TODO failure via conditions
        loop {
            match dom.intervals.get(0) {
                // note that the breaks are for the loop, not the matching
                &(x, _) if min < x => { dom.min = x; break; },
                &(_, y) if min > y => { dom.intervals.shift(); },
                &(_, y) => {
                    dom.min = min;
                    *dom.intervals.get_mut(0) = (min, y);
                    break;
                }
            }
        }
    }

    fn get_min(&self) -> int {
        self.dom.borrow().min
    }

    fn set_max(&self, max: int) {
        let mut dom = self.dom.borrow_mut();
        if max > dom.max { return; }
        if max < dom.min { return; } // TODO failure via conditions
        loop {
            match dom.intervals.last().unwrap() {
                &(_, y) if max > y => { dom.max = y; break; },
                &(x, _) if max < x => { dom.intervals.pop(); },
                &(x, _) => {
                    dom.max = max;
                    *dom.intervals.mut_last().unwrap() = (x, max);
                    break
                }
            }
        }
    }

    fn get_max(&self) -> int {
        self.dom.borrow().max
    }

    fn remove(&self, val: int) {
        let mut dom = self.dom.borrow_mut();
        if val > dom.max || val < dom.min { return; }
        let mut down = 0;
        let mut up = dom.intervals.len();
        let mut test;
        loop {
            test = down + (up - down) / 2;
            match dom.intervals.get(test) {
                &(x, _) if val < x => {
                    if test > down {
                        up = test;
                    } else {
                        break;
                    }
                },
                &(_, y) if val > y => {
                    if test < up - 1 {
                        down = test + 1;
                    } else {
                        break;
                    }
                },
                &(x, y) if val == x && val == y => {
                    dom.intervals.remove(test);
                    break;
                },
                &(x, y) if val == x => {
                    *dom.intervals.get_mut(test) = (x + 1, y);
                    break;
                },
                &(x, y) if val == y => {
                    *dom.intervals.get_mut(test) = (x, y - 1);
                    break;
                },
                &(x, y) => {
                    *dom.intervals.get_mut(test) = (x, val - 1);
                    dom.intervals.insert(test + 1, (val + 1, y));
                    break;
                }
            }
        }
        if test == 0 {
            match dom.intervals.get(test) {
                &(x, _) => dom.min = x
            }
        } else if test == dom.intervals.len() - 1 {
            match dom.intervals.get(test) {
                &(_, y) => dom.max = y
            }
        }
    }
}

impl fmt::Show for Domain {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let dom = self.dom.borrow();
        let mut s = format!("({}, {}) [", dom.min, dom.max);
        for &(min, max) in dom.intervals.iter() {
            s = s + min.to_str() + ".." + max.to_str() + ", ";
        }
        return write!(f, "{}]", s);
    }
}

impl Var {
    pub fn new(model: Rc<Mod>, min: int, max: int, name: &str) -> Rc<FDVar> {
        assert!(min <= max);
        let id = model.vars_count.get();
        let v = Rc::new(FDVar {
            model: model.downgrade(),
            id: id,
            name: name.to_string(),
            dom: Domain::new(min, max)
        });
        model.add_var(v.clone());
        v
    }
}

#[allow(dead_code)]
impl FDVar {
    pub fn min(&self) -> int {
        self.dom.get_min()
    }

    pub fn max(&self) -> int {
        self.dom.get_max()
    }

    fn set_min(&self, v: int) -> Vec<uint> {
        if v > self.min() {
            self.dom.set_min(v);
            if self.is_instanciated() {
                self.model.upgrade().unwrap().get_waiting_on_min(self.id)
                    // + self.waitingOnIns
            } else {
                self.model.upgrade().unwrap().get_waiting_on_min(self.id)
            }
        } else {
            vec![]
        }
    }

    fn set_max(&self, v: int) -> Vec<uint> {
        if v < self.max() {
            self.dom.set_max(v);
            if self.is_instanciated() {
                // self.waitingOnMax + self.waitingOnIns
                self.model.upgrade().unwrap().get_waiting_on_max(self.id)
            } else {
                self.model.upgrade().unwrap().get_waiting_on_max(self.id)
            }
        } else {
            vec![]
        }
    }

    fn is_instanciated(&self) -> bool {
        self.min() == self.max()
    }
}

impl fmt::Show for FDVar {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} ({})", self.name, self.dom)
    }
}

pub struct LtXYx {
    model: Weak<Mod>,
    id: uint,
    x: uint,
    y: uint
}

impl LtXYx {
    pub fn new(model: Rc<Mod>, x: Rc<FDVar>, y: Rc<FDVar>) -> Rc<Box<Propagator>> {
        let id = model.prop_count.get();
        let this = LtXYx { model: model.downgrade(), id: id, x: x.id, y: y.id };
        this.register();
        this.propagate();
        let p = Rc::new((box this) as Box<Propagator>);
        model.add_prop(p.clone());
        p
    }
}

impl Propagator for LtXYx {
    fn id(&self) -> uint {
        self.id
    }

    fn register(&self) {
        self.model.upgrade().unwrap().add_waiting_max(self.y, self.id);
    }

    fn unregister(&self) {
        self.model.upgrade().unwrap().del_waiting_max(self.y, self.id);
    }

    fn propagate(&self) -> Vec<uint> {
        let model = self.model.upgrade().unwrap();
        let mut vars = model.vars.borrow_mut();
        if vars.get(self.x).max() < vars.get(self.y).min() {
            // entailed
            self.unregister();
            vec![]
        } else if vars.get(self.x).max() > vars.get(self.y).max() - 1 {
            //if y.is_instanciated() {
            //   self.unregister();
            //}
            let max = vars.get(self.y).max() - 1;
            vars.get(self.x).set_max(max)
        } else {
            vec![]
        }
    }
}

impl fmt::Show for LtXYx {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} < {}", self.x.to_str(), self.y.to_str())
    }
}

#[cfg(test)]
mod tests;
<commit_msg>single waiting HashMap<commit_after>#![desc = "Constraint Satisfaction in Rust"]
#![license = "MIT"]
#![crate_id = "csar#0.2"]
#![crate_type = "lib"]

use std::fmt;
use std::cell::{Cell,RefCell};
use std::collections::hashmap::HashMap;
use std::rc::{Rc,Weak};

#[allow(dead_code)]
pub struct Mod {
    vars: RefCell<Vec<Rc<FDVar>>>,
    vars_count: Cell<uint>,
    propagators: RefCell<Vec<Rc<Box<Propagator>>>>,
    prop_count: Cell<uint>,
    waiting: RefCell<HashMap<(uint, Event), Vec<uint>>>
}

// cannot use type Model = Rc<Mod> since that would forbid using impl Model
pub struct Model;

/// Representation of finite domains as a list of intervals, maintaining
/// min and max for easy/quick access
#[deriving(Clone)]
struct Dom {
    min: int,
    max: int,
    intervals: Vec<(int, int)>
}

/// Runtime checked mutability with borrowing
#[deriving(Clone)]
struct Domain {
    dom: RefCell<Dom>
}

pub trait Propagator : ToStr {
    fn id(&self) -> uint;
    fn propagate(&self) -> Vec<uint>;
    fn register(&self);
    fn unregister(&self);
}

pub struct Var;

#[deriving(Clone)]
pub struct FDVar {
    model: Weak<Mod>,
    id: uint,
    name: String,
    dom: Domain
}

#[deriving(Show,Hash,Eq,PartialEq)]
pub enum Event {
    Min,
    Max,
    Ins
}

#[allow(dead_code)]
impl Model {
    fn new() -> Rc<Mod> {
        Rc::new(Mod {
            vars_count: Cell::new(0),
            vars: RefCell::new(Vec::new()),
            prop_count: Cell::new(0),
            propagators: RefCell::new(Vec::new()),
            waiting: RefCell::new(HashMap::new())
        })
    }
}

#[allow(dead_code)]
impl Mod {
    fn add_var(&self, var: Rc<FDVar>) {
        self.vars.borrow_mut().push(var);
        self.vars_count.set(self.vars_count.get() + 1);
    }

    fn add_prop(&self, prop: Rc<Box<Propagator>>) {
        self.propagators.borrow_mut().push(prop);
        self.prop_count.set(self.prop_count.get() + 1);
    }

    fn add_waiting(&self, var: uint, event: Event, propagator: uint) {
        let mut waiting = self.waiting.borrow_mut();
        if waiting.contains_key(&(var, event)) {
            waiting.get_mut(&(var, event)).push(propagator);
        } else {
            waiting.insert((var, event), vec![propagator]);
        }
    }

    fn del_waiting(&self, var: uint, event: Event, propagator: uint) {
        self.waiting.borrow_mut().get_mut(&(var, event)).remove(propagator);
    }

    fn get_waiting(&self, var: uint, event: Event) -> Vec<uint> {
        let waiting = self.waiting.borrow();
        match waiting.find_copy(&(var, event)) {
            Some(vec) => vec,
            None => Vec::new()
        }
    }
}

#[allow(dead_code)]
impl Domain {
    /// Domain created with initial bounds
    fn new(min: int, max: int) -> Domain {
        Domain {
            dom: RefCell::new(Dom {
                     min: min,
                     max: max,
                     intervals: vec![(min, max)]
                 })
        }
    }

    fn set_min(&self, min: int) {
        let mut dom = self.dom.borrow_mut();
        if min < dom.min { return; }
        if min > dom.max { return; } // TODO failure via conditions
        loop {
            match dom.intervals.get(0) {
                // note that the breaks are for the loop, not the matching
                &(x, _) if min < x => { dom.min = x; break; },
                &(_, y) if min > y => { dom.intervals.shift(); },
                &(_, y) => {
                    dom.min = min;
                    *dom.intervals.get_mut(0) = (min, y);
                    break;
                }
            }
        }
    }

    fn get_min(&self) -> int {
        self.dom.borrow().min
    }

    fn set_max(&self, max: int) {
        let mut dom = self.dom.borrow_mut();
        if max > dom.max { return; }
        if max < dom.min { return; } // TODO failure via conditions
        loop {
            match dom.intervals.last().unwrap() {
                &(_, y) if max > y => { dom.max = y; break; },
                &(x, _) if max < x => { dom.intervals.pop(); },
                &(x, _) => {
                    dom.max = max;
                    *dom.intervals.mut_last().unwrap() = (x, max);
                    break
                }
            }
        }
    }

    fn get_max(&self) -> int {
        self.dom.borrow().max
    }

    fn remove(&self, val: int) {
        let mut dom = self.dom.borrow_mut();
        if val > dom.max || val < dom.min { return; }
        let mut down = 0;
        let mut up = dom.intervals.len();
        let mut test;
        loop {
            test = down + (up - down) / 2;
            match dom.intervals.get(test) {
                &(x, _) if val < x => {
                    if test > down {
                        up = test;
                    } else {
                        break;
                    }
                },
                &(_, y) if val > y => {
                    if test < up - 1 {
                        down = test + 1;
                    } else {
                        break;
                    }
                },
                &(x, y) if val == x && val == y => {
                    dom.intervals.remove(test);
                    break;
                },
                &(x, y) if val == x => {
                    *dom.intervals.get_mut(test) = (x + 1, y);
                    break;
                },
                &(x, y) if val == y => {
                    *dom.intervals.get_mut(test) = (x, y - 1);
                    break;
                },
                &(x, y) => {
                    *dom.intervals.get_mut(test) = (x, val - 1);
                    dom.intervals.insert(test + 1, (val + 1, y));
                    break;
                }
            }
        }
        if test == 0 {
            match dom.intervals.get(test) {
                &(x, _) => dom.min = x
            }
        } else if test == dom.intervals.len() - 1 {
            match dom.intervals.get(test) {
                &(_, y) => dom.max = y
            }
        }
    }
}

impl fmt::Show for Domain {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let dom = self.dom.borrow();
        let mut s = format!("({}, {}) [", dom.min, dom.max);
        for &(min, max) in dom.intervals.iter() {
            s = s + min.to_str() + ".." + max.to_str() + ", ";
        }
        return write!(f, "{}]", s);
    }
}

impl Var {
    pub fn new(model: Rc<Mod>, min: int, max: int, name: &str) -> Rc<FDVar> {
        assert!(min <= max);
        let id = model.vars_count.get();
        let v = Rc::new(FDVar {
            model: model.downgrade(),
            id: id,
            name: name.to_string(),
            dom: Domain::new(min, max)
        });
        model.add_var(v.clone());
        v
    }
}

#[allow(dead_code)]
impl FDVar {
    pub fn min(&self) -> int {
        self.dom.get_min()
    }

    pub fn max(&self) -> int {
        self.dom.get_max()
    }

    fn set_min(&self, v: int) -> Vec<uint> {
        if v > self.min() {
            self.dom.set_min(v);
            if self.is_instanciated() {
                self.model.upgrade().unwrap().get_waiting(self.id, Min)
                    // + self.waitingOnIns
            } else {
                self.model.upgrade().unwrap().get_waiting(self.id, Min)
            }
        } else {
            vec![]
        }
    }

    fn set_max(&self, v: int) -> Vec<uint> {
        if v < self.max() {
            self.dom.set_max(v);
            if self.is_instanciated() {
                // self.waitingOnMax + self.waitingOnIns
                self.model.upgrade().unwrap().get_waiting(self.id, Max)
            } else {
                self.model.upgrade().unwrap().get_waiting(self.id, Max)
            }
        } else {
            vec![]
        }
    }

    fn is_instanciated(&self) -> bool {
        self.min() == self.max()
    }
}

impl fmt::Show for FDVar {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} ({})", self.name, self.dom)
    }
}

pub struct LtXYx {
    model: Weak<Mod>,
    id: uint,
    x: uint,
    y: uint
}

impl LtXYx {
    pub fn new(model: Rc<Mod>, x: Rc<FDVar>, y: Rc<FDVar>) -> Rc<Box<Propagator>> {
        let id = model.prop_count.get();
        let this = LtXYx { model: model.downgrade(), id: id, x: x.id, y: y.id };
        this.register();
        this.propagate();
        let p = Rc::new((box this) as Box<Propagator>);
        model.add_prop(p.clone());
        p
    }
}

impl Propagator for LtXYx {
    fn id(&self) -> uint {
        self.id
    }

    fn register(&self) {
        self.model.upgrade().unwrap().add_waiting(self.y, Max, self.id);
    }

    fn unregister(&self) {
        self.model.upgrade().unwrap().del_waiting(self.y, Max, self.id);
    }

    fn propagate(&self) -> Vec<uint> {
        let model = self.model.upgrade().unwrap();
        let mut vars = model.vars.borrow_mut();
        if vars.get(self.x).max() < vars.get(self.y).min() {
            // entailed
            self.unregister();
            vec![]
        } else if vars.get(self.x).max() > vars.get(self.y).max() - 1 {
            //if y.is_instanciated() {
            //   self.unregister();
            //}
            let max = vars.get(self.y).max() - 1;
            vars.get(self.x).set_max(max)
        } else {
            vec![]
        }
    }
}

impl fmt::Show for LtXYx {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{} < {}", self.x.to_str(), self.y.to_str())
    }
}

#[cfg(test)]
mod tests;
<|endoftext|>


<commit_before>extern crate ww;

use ww::map::{Map, MapRoomId};
use ww::room::Room;
use ww::direction::Direction::*;
use ww::command::{PrimaryCommand, CommandProcessor};

use RoomId::*;

const MAX_ROOMS: usize = 20;

#[derive(Debug, Copy, Clone)]
enum RoomId {
  Hallway = 1,
  AudienceChamber = 2,
}

// Ideally we'd actually just get rid of MapRoomId and add a constraint
// to Map<T> requiring that T be type-castable as usize, but I don't
// know how to do that, so...
impl MapRoomId for RoomId {
  fn room_id(self) -> usize { self as usize }
}

#[derive(Debug, PartialEq, Copy, Clone)]
enum GameMode {
  Primary,
  Finished,
}

struct GameState<'a> {
  map: &'a mut Map<'a, RoomId>,
  pub curr_mode: GameMode,
  curr_room: RoomId,
  show_desc: bool,
}

impl<'a> GameState<'a> {
  pub fn new(map: &'a mut Map<'a, RoomId>) -> Self {
    Self {
      map: map,
      curr_mode: GameMode::Primary,
      curr_room: Hallway,
      show_desc: true,
    }
  }

  pub fn tick(&mut self) {
    match self.curr_mode {
      GameMode::Primary => {
        if self.show_desc {
          println!("{}", self.map.room(self.curr_room).description);
          self.show_desc = false;
        }

        match PrimaryCommand::get() {
          PrimaryCommand::Go(dir) => {
            if let Some(room) = self.map.room(self.curr_room).get_exit(dir) {
              self.curr_room = room;
              self.show_desc = true;
            } else {
              println!("You can't go that way.");
            }
          },
          PrimaryCommand::Look => { self.show_desc = true; }
          PrimaryCommand::Quit => { self.curr_mode = GameMode::Finished; }
        }
      },
      GameMode::Finished => {}
    }
  }
}

fn build_world(map: &mut Map<RoomId>) {
  map.room(Hallway).describe(
    "Hallway",
    "You are in the hallway. \
     There is a door to the south. \
     Through the windows to the north you can see a secret herb garden."
  );

  map.room(AudienceChamber).describe(
    "Audience Chamber",
    "This is the audience chamber. \
     There is a window to the west. By looking to the right \
     through it you can see the entrance to the castle. \
     Doors leave this room to the north, east, and south."
  );

  map.connect(Hallway, South, AudienceChamber);
}

fn main() {
  let mut rooms = [Room::new(); MAX_ROOMS];
  let mut map = Map::new(&mut rooms);

  build_world(&mut map);

  let mut state = GameState::new(&mut map);

  println!("Werewolves and Wanderer\n");

  while state.curr_mode != GameMode::Finished {
    state.tick();
  }

  println!("Farewell.");
}
<commit_msg>Move build_world() for better readability.<commit_after>extern crate ww;

use ww::map::{Map, MapRoomId};
use ww::room::Room;
use ww::direction::Direction::*;
use ww::command::{PrimaryCommand, CommandProcessor};

use RoomId::*;

const MAX_ROOMS: usize = 20;

#[derive(Debug, Copy, Clone)]
enum RoomId {
  Hallway = 1,
  AudienceChamber = 2,
}

fn build_world(map: &mut Map<RoomId>) {
  map.room(Hallway).describe(
    "Hallway",
    "You are in the hallway. \
     There is a door to the south. \
     Through the windows to the north you can see a secret herb garden."
  );

  map.room(AudienceChamber).describe(
    "Audience Chamber",
    "This is the audience chamber. \
     There is a window to the west. By looking to the right \
     through it you can see the entrance to the castle. \
     Doors leave this room to the north, east, and south."
  );

  map.connect(Hallway, South, AudienceChamber);
}

// Ideally we'd actually just get rid of MapRoomId and add a constraint
// to Map<T> requiring that T be type-castable as usize, but I don't
// know how to do that, so...
impl MapRoomId for RoomId {
  fn room_id(self) -> usize { self as usize }
}

#[derive(Debug, PartialEq, Copy, Clone)]
enum GameMode {
  Primary,
  Finished,
}

struct GameState<'a> {
  map: &'a mut Map<'a, RoomId>,
  pub curr_mode: GameMode,
  curr_room: RoomId,
  show_desc: bool,
}

impl<'a> GameState<'a> {
  pub fn new(map: &'a mut Map<'a, RoomId>) -> Self {
    Self {
      map: map,
      curr_mode: GameMode::Primary,
      curr_room: Hallway,
      show_desc: true,
    }
  }

  pub fn tick(&mut self) {
    match self.curr_mode {
      GameMode::Primary => {
        if self.show_desc {
          println!("{}", self.map.room(self.curr_room).description);
          self.show_desc = false;
        }

        match PrimaryCommand::get() {
          PrimaryCommand::Go(dir) => {
            if let Some(room) = self.map.room(self.curr_room).get_exit(dir) {
              self.curr_room = room;
              self.show_desc = true;
            } else {
              println!("You can't go that way.");
            }
          },
          PrimaryCommand::Look => { self.show_desc = true; }
          PrimaryCommand::Quit => { self.curr_mode = GameMode::Finished; }
        }
      },
      GameMode::Finished => {}
    }
  }
}

fn main() {
  let mut rooms = [Room::new(); MAX_ROOMS];
  let mut map = Map::new(&mut rooms);

  build_world(&mut map);

  let mut state = GameState::new(&mut map);

  println!("Werewolves and Wanderer\n");

  while state.curr_mode != GameMode::Finished {
    state.tick();
  }

  println!("Farewell.");
}
<|endoftext|>


<commit_before>extern crate ansi_term;
#[macro_use]
extern crate clap;
extern crate hyper;
extern crate libzou;
extern crate num_cpus;

use clap::{App, Arg};
use libzou::cargo_helper::get_cargo_info;
use libzou::download::download_chunks;
use libzou::filesize::format_filesize;
use libzou::util::prompt_user;
use libzou::write::OutputFileWriter;
#[macro_use]
mod logs;
use std::fs::{File, remove_file};
use std::path::Path;
use std::process::exit;

static DEFAULT_FILENAME: &'static str = "index.html";

fn main() {

    // Parse arguments

    let argparse = App::new("Zou")
        .about("Zou, a simple and fast download accelerator, written in Rust.")
        .version(crate_version!())
        .arg(Arg::with_name("file")
                 .long("file")
                 .short("f")
                 .takes_value(true)
                 .help("The local file to save the remote content file"))
        .arg(Arg::with_name("threads")
                 .long("threads")
                 .short("t")
                 .takes_value(true)
                 .help("Threads which can use to download"))
        .arg(Arg::with_name("debug")
                 .long("debug")
                 .short("d")
                 .help("Active the debug mode"))
        .arg(Arg::with_name("force")
                 .long("force")
                 .help("Assume Yes to all queries and do not prompt"))
        .arg(Arg::with_name("mirrors")
                 .long("mirrors")
                 .short("m")
                 .multiple(true)
                 .takes_value(true)
                 .help("Download using a list of mirrors - the list of mirrors is used WITH the original URL"))
        .arg(Arg::with_name("url")
            .index(1)
            //.multiple(true)
            .required(true))
        .get_matches();

    // Get informations from arguments

    let url = argparse.value_of("url").unwrap();

    let filename: &str = argparse
        .value_of("file")
        .unwrap_or_else(|| url.split('/').last().unwrap_or(DEFAULT_FILENAME));

    let mirrors: Option<Vec<&str>> = if !argparse.is_present("mirrors") {
        None
    } else {
        Some(argparse.values_of("mirrors").unwrap().collect())
    };

    // Check if multi-threaded download is possible
    let mut threads: usize = value_t!(argparse, "threads", usize)
        .and_then(|v| if v != 0 {
                      Ok(v)
                  } else {
                      Err(clap::Error::with_description("Cannot download a file using 0 thread",
                                                        clap::ErrorKind::InvalidValue))
                  })
        .unwrap_or(num_cpus::get_physical());

    if argparse.is_present("debug") {
        info!(&format!("version: {}", crate_version!()));
        info!(&format!("file: {}", filename));
        info!(&format!("threads: {}", threads));
    }

    let local_path = Path::new(&filename);

    if local_path.exists() {
        if local_path.is_dir() {
            epanic!("The local path to store the remote content is already exists, \
                        and is a directory!");
        }
        if !argparse.is_present("force") {
            let user_input = prompt_user("The path to store the file already exists! \
                                          Do you want to override it? [y/N]");
            if !(user_input == "y" || user_input == "Y") {
                exit(0);
            }
        } else {
            warning!("The path to store the file already exists! \
                                 It is going to be overriden.");
        }
    }

    let cargo_info = get_cargo_info(&url, mirrors).expect("fail to parse url");
    info!(&format!("Remote content length: {}",
                   format_filesize(cargo_info.content_length)));

    let local_file = File::create(local_path).expect("[ERROR] Cannot create a file !");

    local_file
        .set_len(cargo_info.content_length)
        .expect("Cannot extend local file !");
    let out_file = OutputFileWriter::new(local_file);

    // If the server does not accept PartialContent status, download the remote file
    // using only one thread
    if !cargo_info.accept_partialcontent {
        warning!("The remote server does not accept PartialContent status! \
                             Downloading the remote file using one thread.");
        threads = 1;
    }

    if download_chunks(cargo_info, out_file, threads as u64, &url) {
        ok!(&format!("Your download is available in {}",
                     local_path.to_str().unwrap()));
    } else {
        // If the file is not ok, delete it from the file system
        error!("Download failed! An error occured - erasing file... ");
        if remove_file(local_path).is_err() {
            error!("Cannot remove downloaded file!");
        }
    }

}
<commit_msg>New main behaviour<commit_after>extern crate ansi_term;
#[macro_use]
extern crate clap;
extern crate hyper;
extern crate libzou;
extern crate num_cpus;

use clap::{App, Arg};
use libzou::cargo_helper::get_cargo_info;
use libzou::download::download_chunks;
use libzou::filesize::format_filesize;
use libzou::util::prompt_user;
use libzou::write::OutputFileWriter;
#[macro_use]
mod logs;
use std::fs::{File, remove_file};
use std::path::Path;
use std::process::exit;

// static DEFAULT_FILENAME: &'static str = "index.html";

fn main() {

    // Parse arguments

    let argparse = App::new("Zou")
        .about("Zou, a simple and fast download accelerator, written in Rust.")
        .version(crate_version!())
        .arg(Arg::with_name("file")
                 .long("file")
                 .short("f")
                 .takes_value(true)
                 .help("The local file to save the remote content file"))
        .arg(Arg::with_name("threads")
                 .long("threads")
                 .short("t")
                 .takes_value(true)
                 .help("Threads which can use to download"))
        .arg(Arg::with_name("debug")
                 .long("debug")
                 .short("d")
                 .help("Active the debug mode"))
        .arg(Arg::with_name("force")
                 .long("force")
                 .help("Assume Yes to all queries and do not prompt"))
        .arg(Arg::with_name("mirrors")
                 .long("mirrors")
                 .short("m")
                 .multiple(true)
                 .takes_value(true)
                 .help("Download using a list of mirrors - the list of mirrors is used WITH the original URL"))
        .arg(Arg::with_name("url")
            .index(1)
            //.multiple(true)
            .required(true))
        .get_matches();

    // Get informations from arguments

    // Get the URL as a Path structure
    let url = Path::new(argparse.value_of("url").unwrap());

    // Set the mirrors vectors
    let mut servers_urls: Vec<&str> = match url.parent() {
        Some(parent) => vec![parent.to_str().unwrap()],
        None => vec![],
    };
    // Set given mirrors
    if argparse.is_present("mirrors") {
        let mirrors_vec: Vec<&str> = argparse.values_of("mirrors").unwrap().collect();
        for mirror in mirrors_vec {
            servers_urls.push(mirror);
        }
    }

    // Get the path filename
    let filename = url.file_name().unwrap().to_str().unwrap();

    // Check if multi-threaded download is possible
    let mut threads: usize = value_t!(argparse, "threads", usize)
        .and_then(|v| if v != 0 {
                      Ok(v)
                  } else {
                      Err(clap::Error::with_description("Cannot download a file using 0 thread",
                                                        clap::ErrorKind::InvalidValue))
                  })
        .unwrap_or(num_cpus::get_physical());

    if argparse.is_present("debug") {
        info!(&format!("version: {}", crate_version!()));
        info!(&format!("file: {}", filename));
        info!(&format!("threads: {}", threads));
    }

    let local_path = Path::new(&filename);

    if local_path.exists() {
        if local_path.is_dir() {
            epanic!("The local path to store the remote content is already exists, \
                        and is a directory!");
        }
        if !argparse.is_present("force") {
            let user_input = prompt_user("The path to store the file already exists! \
                                          Do you want to override it? [y/N]");
            if !(user_input == "y" || user_input == "Y") {
                exit(0);
            }
        } else {
            warning!("The path to store the file already exists! \
                                 It is going to be overriden.");
        }
    }

    let cargo_info = get_cargo_info(filename, servers_urls).expect("fail to parse url");
    info!(&format!("Remote content length: {}",
                   format_filesize(cargo_info.content_length)));

    let local_file = File::create(local_path).expect("[ERROR] Cannot create a file !");

    local_file
        .set_len(cargo_info.content_length)
        .expect("Cannot extend local file !");
    let out_file = OutputFileWriter::new(local_file);

    // If the server does not accept PartialContent status, download the remote file
    // using only one thread
    if !cargo_info.accept_partialcontent {
        warning!("The remote server does not accept PartialContent status! \
                             Downloading the remote file using one thread.");
        threads = 1;
    }

    if download_chunks(cargo_info, out_file, threads as u64, filename) {
        ok!(&format!("Your download is available in {}",
                     local_path.to_str().unwrap()));
    } else {
        // If the file is not ok, delete it from the file system
        error!("Download failed! An error occured - erasing file... ");
        if remove_file(local_path).is_err() {
            error!("Cannot remove downloaded file!");
        }
    }

}
<|endoftext|>


<commit_before>#[macro_use]
extern crate lazy_static;
extern crate capnp;
extern crate capnp_rpc;
extern crate cassandra;

use std::collections::HashMap;
use capnp::capability::{Server};
use capnp_rpc::ez_rpc::EzRpcServer;
use cassandra::*;

// this is generated automatically as part of the build process
// see build.rs
pub mod killranswers_capnp {
  include!(concat!(env!("OUT_DIR"), "/killranswers_capnp.rs"));
}
use killranswers_capnp::killr_answers;

static CREATE_USER : &'static str = "insert into user (user_id), values (?)";

lazy_static! {

}

struct KillrAnswersImpl;

impl killr_answers::Server for KillrAnswersImpl {
    // fn ask(&mut self, mut context: killr_answers::AskContext) {
    //     println!("Asking");
    // }
    fn register_user(&mut self, mut context: killr_answers::RegisterUserContext) {
        context.done();
    }

}

fn main() {
    println!("Starting up...");
    let rpc_server = EzRpcServer::new("127.0.0.1:6000").unwrap();
    let ka = Box::new(killr_answers::ServerDispatch { server : Box::new(KillrAnswersImpl)});
    //
    rpc_server.serve(ka);

    println!("Done");
}
<commit_msg>properly connecting to the db now<commit_after>#[macro_use]
extern crate lazy_static;
extern crate capnp;
extern crate capnp_rpc;
extern crate cassandra;

use std::collections::HashMap;
use capnp::capability::{Server};
use capnp_rpc::ez_rpc::EzRpcServer;
use cassandra::*;

// this is generated automatically as part of the build process
// see build.rs
pub mod killranswers_capnp {
  include!(concat!(env!("OUT_DIR"), "/killranswers_capnp.rs"));
}
use killranswers_capnp::killr_answers;

// queries for prepared statements
// schema is managed in the python part of the app
// see the cqlengine Models
static CREATE_USER : &'static str = "insert into user (user_id), values (?)";

struct KillrAnswersImpl {
    db: CassSession,
}

impl KillrAnswersImpl {
    // returns a Boxed implemention
    fn new() -> Box<KillrAnswersImpl> {

        let mut cluster = CassCluster::new();
        cluster.set_contact_points("127.0.0.1").unwrap();
        cluster.set_protocol_version(3).unwrap();
        let mut session = CassSession::new().connect(&mut cluster).wait().unwrap();

        Box::new(KillrAnswersImpl{ db: session })
    }
}

impl killr_answers::Server for KillrAnswersImpl {
    // fn ask(&mut self, mut context: killr_answers::AskContext) {
    //     println!("Asking");
    // }
    fn register_user(&mut self, mut context: killr_answers::RegisterUserContext) {
        context.done();
    }

}

fn main() {
    println!("Starting up...");

    let rpc_server = EzRpcServer::new("127.0.0.1:6000").unwrap();
    let ka = Box::new(killr_answers::ServerDispatch { server : KillrAnswersImpl::new() });
    //
    rpc_server.serve(ka);

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


<commit_before>#![feature(core)] //this should be removed before out of beta
extern crate regex;
use regex::Regex;

enum schmAtom {
    Int(i32),
    Float(f32),
    String(String),
    Symb(String)
}

fn main() {

}

fn tokenize(input: String) -> Vec<String>{
    // Split input string into smaller tokens.
    let re1 = Regex::new(r"\(").unwrap();
    let re2 = Regex::new(r"\)").unwrap();
    let mut after: String = re1.replace_all(&input,"( ");
    after = re2.replace_all(&after, " )");

    let split = after.split(" "); //split is an iterator
    split.map(|x|{x.to_string()}).collect::<Vec<String>>()
    //^to `.to_string` seems kind of hackish...
    //BUT it actaully just forces the copy and move of the string
}

fn atom(token: String) -> schmAtom {
    //Figure out what type a token is representing.

    // Probably more idiomatic way?
    let intNum = token.parse::<i32>();
    let floatNum = token.parse::<f32>();

    if intNum.is_ok() {
        let x  = match intNum {
            Ok(x) => x
        };
        return schmAtom::Int(x)
    } else if floatNum.is_ok() {
        let x = match floatNum {
            Ok(x) => x
        };
        return schmAtom::Float(x)
    } else { //must be string...
        //TODO: differe between strings and symbols
        return schmAtom::String(token)
    }

}

fn read_from_tokens(){
}

#[cfg(test)]

#[test]
fn test_tokenize() {
    let test_input: String  = "(a b c)".to_string();
    assert_eq!(tokenize(test_input),
               vec!("(","a","b","c", ")"));
}

<commit_msg>Add (working) atom and repsective tests.<commit_after>#![feature(core)] //this should be removed before out of beta
extern crate regex;
use regex::Regex;

enum schmAtom {
    Int(i32),
    Float(f32),
    String(String),
    Symb(String)
}

fn main() {

}

fn tokenize(input: String) -> Vec<String>{
    // Split input string into smaller tokens.
    let re1 = Regex::new(r"\(").unwrap();
    let re2 = Regex::new(r"\)").unwrap();
    let mut after: String = re1.replace_all(&input,"( ");
    after = re2.replace_all(&after, " )");

    let split = after.split(" "); //split is an iterator
    split.map(|x|{x.to_string()}).collect::<Vec<String>>()
    //^to `.to_string` seems kind of hackish...
    //BUT it actaully just forces the copy and move of the string
}

fn atom(token: String) -> schmAtom {
    //Figure out what type a token is representing.

    // Probably more idiomatic way?
    //Calling both from the get go seesm silly,
    //and using unwrap is proabbly bad.
    let intNum = token.parse::<i32>();
    let floatNum = token.parse::<f32>();

    if intNum.is_ok() {
        let x = intNum.unwrap();
        return schmAtom::Int(x)
    } else if floatNum.is_ok() {
        let x = floatNum.unwrap();
        return schmAtom::Float(x)
    } else { //must be string...
    //TODO: There is no way the following line is idiomatic
        if match token.as_bytes()[0] as char {'\"' => true, _ => false  } {
            return schmAtom::String(token)
        } else {
            return schmAtom::Symb(token)
        }
    }

}

fn read_from_tokens(){

}

#[cfg(test)]

#[test]
fn test_atom(){
    let test_string = "\"ab\"".to_string();
    let test_float = "1.0".to_string();
    let test_int = "1".to_string();
    let test_symb = "hi".to_string();

    let string_atom = atom(test_string);
    let float_atom = atom(test_float);
    let int_atom = atom(test_int);
    let symb_atom = atom(test_symb);

    let res = match (string_atom, float_atom, int_atom, symb_atom) {
        (schmAtom::String(x), schmAtom::Float(y), schmAtom::Int(z),
                schmAtom::Symb(l),)
            => { (x,y,z,l) == ("\"ab\"".to_string(),1.0,1,"hi".to_string())},
          _ => false
    };

    assert!(res,true)

}

#[test]
fn test_tokenize() {
    let test_input: String  = "(a b c)".to_string();
    assert_eq!(tokenize(test_input),
               vec!("(","a","b","c", ")"));
}

<|endoftext|>


<commit_before>//! Muxed. A tmux project manager with no runtime dependencies.
extern crate common;
extern crate docopt;
extern crate edit;
extern crate load;
extern crate new;
extern crate snapshot;

use common::args::Args;
use docopt::Docopt;
use std::env;
use std::process::exit;

#[macro_export]
macro_rules! try_or_err (
    ($expr: expr) => ({
        match $expr {
            Ok(val) => val,
            Err(e) => {
                println!("Muxed ran in to a problem: {}", e);
                exit(1);
            }
        }
    })
);

static DISALLOWED_SHORTHAND_PROJECT_NAMES: [&str; 2] = ["new", "edit"];

static USAGE: &str = "
Usage:
    muxed [options] <project>
    muxed edit [options] <project>
    muxed new [options] <project>
    muxed snapshot [options] <project>
    muxed load [options] <project>
    muxed (-h | --help)
    muxed (-v | --version)

Flags:
    -d                  If you want to create a muxed session without connecting to it
    -f                  Overwrite existing file if one exists
    --debug             Prints debug information while executing (project opening only)
    -h, --help          Prints help information
    -v, --version       Prints version information

Options:
    -p <project_dir>    The directory your project config files live in. Defaults to ~/.muxed/
    -t <session>        The name of the running TMUX session to codify

Args:
    <project>           The name of your project to open

Subcommands:
    edit <project>                   Edit an existing project file
    new <project>                    To create a new project file
    snapshot -t <session> <project>  Capture a running session and create a config file for it
";

/// The main execution method.
/// Currently accepts a single option. The option represents a configuration
/// file in the same naming format. Given a project file name `projectName.yml`
/// in the `~/.muxed/` directory.
///
/// # Examples
///
/// ~/.muxed/projectName.yml
///
/// ```
/// root: ~/projects/muxed/
/// windows:
///     - cargo: "cargo build"
///     - vim: "vim ."
///     - git: ""
/// ```
///
/// You can run the command:
///
/// ```
/// $ ./muxed projectName
/// ```
pub fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.deserialize())
        .unwrap_or_else(|e| e.exit());

    if args.flag_v {
        println!("Muxed {}", env!("CARGO_PKG_VERSION"));
        exit(0);
    };

    if args.cmd_new {
        try_or_err!(new::exec(args))
    } else if args.cmd_edit {
        try_or_err!(edit::exec(args))
    } else if args.cmd_snapshot {
        try_or_err!(snapshot::exec(args))
    } else if args.cmd_load {
        try_or_err!(load::exec(args))
    } else {
        if DISALLOWED_SHORTHAND_PROJECT_NAMES.contains(&args.arg_project.as_ref()) {
            println!(
                "Tried to call sub-command '{}' without a project. Please specify a project name.",
                args.arg_project
            );
            exit(1);
        }

        try_or_err!(load::exec(args))
    }
}
<commit_msg>Add the other 2 sub-commands to the list, since the same bug applies to them too<commit_after>//! Muxed. A tmux project manager with no runtime dependencies.
extern crate common;
extern crate docopt;
extern crate edit;
extern crate load;
extern crate new;
extern crate snapshot;

use common::args::Args;
use docopt::Docopt;
use std::env;
use std::process::exit;

#[macro_export]
macro_rules! try_or_err (
    ($expr: expr) => ({
        match $expr {
            Ok(val) => val,
            Err(e) => {
                println!("Muxed ran in to a problem: {}", e);
                exit(1);
            }
        }
    })
);

static DISALLOWED_SHORTHAND_PROJECT_NAMES: [&str; 4] = ["new", "edit", "load", "snapshot"];

static USAGE: &str = "
Usage:
    muxed [options] <project>
    muxed edit [options] <project>
    muxed new [options] <project>
    muxed snapshot [options] <project>
    muxed load [options] <project>
    muxed (-h | --help)
    muxed (-v | --version)

Flags:
    -d                  If you want to create a muxed session without connecting to it
    -f                  Overwrite existing file if one exists
    --debug             Prints debug information while executing (project opening only)
    -h, --help          Prints help information
    -v, --version       Prints version information

Options:
    -p <project_dir>    The directory your project config files live in. Defaults to ~/.muxed/
    -t <session>        The name of the running TMUX session to codify

Args:
    <project>           The name of your project to open

Subcommands:
    edit <project>                   Edit an existing project file
    new <project>                    To create a new project file
    snapshot -t <session> <project>  Capture a running session and create a config file for it
";

/// The main execution method.
/// Currently accepts a single option. The option represents a configuration
/// file in the same naming format. Given a project file name `projectName.yml`
/// in the `~/.muxed/` directory.
///
/// # Examples
///
/// ~/.muxed/projectName.yml
///
/// ```
/// root: ~/projects/muxed/
/// windows:
///     - cargo: "cargo build"
///     - vim: "vim ."
///     - git: ""
/// ```
///
/// You can run the command:
///
/// ```
/// $ ./muxed projectName
/// ```
pub fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.deserialize())
        .unwrap_or_else(|e| e.exit());

    if args.flag_v {
        println!("Muxed {}", env!("CARGO_PKG_VERSION"));
        exit(0);
    };

    if args.cmd_new {
        try_or_err!(new::exec(args))
    } else if args.cmd_edit {
        try_or_err!(edit::exec(args))
    } else if args.cmd_snapshot {
        try_or_err!(snapshot::exec(args))
    } else if args.cmd_load {
        try_or_err!(load::exec(args))
    } else {
        if DISALLOWED_SHORTHAND_PROJECT_NAMES.contains(&args.arg_project.as_ref()) {
            println!(
                "Tried to call sub-command '{}' without a project. Please specify a project name.",
                args.arg_project
            );
            exit(1);
        }

        try_or_err!(load::exec(args))
    }
}
<|endoftext|>


<commit_before>#![feature(plugin)]

#![plugin(clippy)]

extern crate iron;
extern crate router;
extern crate params;

use std::process::Command;
use std::path::Path;

use iron::prelude::*;
use router::{Router};
use iron::status;
use iron::{BeforeMiddleware};

mod hash;

#[macro_use]
mod config;

use hash::sha1sum;

use param_rules::{RequiredParam, get_param};

macro_rules! status_from_io_err {
  ($why:expr) => (

    match $why.kind() {
      std::io::ErrorKind::NotFound => status::NotFound,
      std::io::ErrorKind::PermissionDenied => status::Forbidden,
      _ => status::InternalServerError,
    }

  )
}

#[allow(needless_return)]
fn submit_form_file(req: &mut Request) -> IronResult<Response> {

  use std::fs::{rename,File};

  // thanks to BeforeMiddleware rules we can do unwrap safely
  let passed_sha1sum = &get_param::<String>(req,"sha1sum");
  let file_param = get_param::<params::File>(req, "filename");

  let file_path = format!("{}.ods" , file_param.path().display());

  match rename(&file_param.path(), &file_path) {
    Err(why) => {
      let status = status_from_io_err!(why);
      Ok(Response::with((status, format!("failed to elaborate the received file: {}", why))))
    },
    Ok(_) => {
      println!("elaborating the file {}", file_path);

      match File::open(&file_path) {
        Err(why) => {
          let status = status_from_io_err!(why);
          Ok(Response::with((status, format!("failed to opening the received file: {}", why))))
        },
        Ok(ref mut file) => {
          let calculated_sha1sum = &sha1sum(file);
          if calculated_sha1sum != passed_sha1sum {
            let msg = format!(
              "the sha1sum '{}' calculate for the file {} doesn't correspond to the parameter '{}'",
              calculated_sha1sum, file_path, passed_sha1sum
            );
            return Ok(Response::with((status::PreconditionRequired, msg)))
          }

          let conf = config::get_config();

          // run the cmd
          let working_dir = format!("{}",file_param.path().parent().expect("cannot access the directory of the uploaded temporary file").display());
          let cmd_name = get_config_parameter!(conf,"transformation.cmd");
          let cmd_name = cmd_name.replace("{working_dir}", &working_dir);
          let cmd_name = cmd_name.replace("{file}", &file_path);

          println!("cmd: {}", cmd_name);

          let mut cmd_args: Vec<&str> = cmd_name.split_whitespace()
                                            .collect();

          let res = Command::new(cmd_args.remove(0))
                            .args(&cmd_args)
                            .status()
                            .unwrap_or_else(|e| {
                              println!("failed to execute process: {}", e);
                              panic!("failed to execute process: {}", e);
                            });

          println!("process exited with: {}", res);

          if res.success() {
            let ref file_path = format!("{}.pdf" , file_param.path().display());
            println!("file_path: {}", file_path);
            return Ok(Response::with((status::Ok, Path::new(file_path))))
          }
          else {
            // copy the file in an error dirctory for further investigations
            let err_destination_dir = get_config_parameter!(conf,"transformation.err_destination_dir");
            //             let res = Command::new("mkdir")
            //                               .args(&["-p",err_destination_dir])
            //                               .status()
            //                               .unwrap_or_else(|e| {
            //                                 println!("failed to execute process: {}", e);
            //                                 panic!("failed to execute process: {}", e);
            //                               });

            Command::new("nice")
            .args(&["-n","20","cp","-R", &working_dir, err_destination_dir])
            .spawn()
            .unwrap_or_else(|e| {
              println!("failed to execute process: {}", e);
              panic!("failed to execute process: {}", e);
            });

            return Ok(Response::with(status::InternalServerError))

          }

        }
      }
    }
  }

}

#[macro_use]
mod param_rules;

require_param!(RequireMd5sumParam, "sha1sum", String);
require_param!(RequireFileParam, "filename", params::File);

mod logger;

use logger::Logger;
use iron::{AroundMiddleware};
fn start_server() {
   let mut router = Router::new();
   let mut chain_form_file = Chain::new(submit_form_file);

   chain_form_file.link_before(RequireMd5sumParam);
   chain_form_file.link_before(RequireFileParam);

   router.post("/openact", Logger::default().around(Box::new(chain_form_file)));

   println!("started server at http://localhost:3000/");
   Iron::new(router).http("localhost:3000").unwrap();
}

fn main() {
    println!("Hello, world!");
    start_server();
}
<commit_msg>dropped file config for unknown library error<commit_after>#![feature(plugin)]

#![plugin(clippy)]

extern crate iron;
extern crate router;
extern crate params;

use std::process::Command;
use std::path::Path;

use iron::prelude::*;
use router::{Router};
use iron::status;
use iron::{BeforeMiddleware};

mod hash;

#[macro_use]
mod config;

use hash::sha1sum;

use param_rules::{RequiredParam, get_param};

macro_rules! status_from_io_err {
  ($why:expr) => (

    match $why.kind() {
      std::io::ErrorKind::NotFound => status::NotFound,
      std::io::ErrorKind::PermissionDenied => status::Forbidden,
      _ => status::InternalServerError,
    }

  )
}

#[allow(needless_return)]
fn submit_form_file(req: &mut Request) -> IronResult<Response> {

  use std::fs::{rename,File};

  // thanks to BeforeMiddleware rules we can do unwrap safely
  let passed_sha1sum = &get_param::<String>(req,"sha1sum");
  let file_param = get_param::<params::File>(req, "filename");

  let file_path = format!("{}.ods" , file_param.path().display());

  match rename(&file_param.path(), &file_path) {
    Err(why) => {
      let status = status_from_io_err!(why);
      Ok(Response::with((status, format!("failed to elaborate the received file: {}", why))))
    },
    Ok(_) => {
      println!("elaborating the file {}", file_path);

      match File::open(&file_path) {
        Err(why) => {
          let status = status_from_io_err!(why);
          Ok(Response::with((status, format!("failed to opening the received file: {}", why))))
        },
        Ok(ref mut file) => {
          let calculated_sha1sum = &sha1sum(file);
          if calculated_sha1sum != passed_sha1sum {
            let msg = format!(
              "the sha1sum '{}' calculate for the file {} doesn't correspond to the parameter '{}'",
              calculated_sha1sum, file_path, passed_sha1sum
            );
            return Ok(Response::with((status::PreconditionRequired, msg)))
          }

          let conf = config::get_config();

          // run the cmd
          let working_dir = format!("{}",file_param.path().parent().expect("cannot access the directory of the uploaded temporary file").display());
          let cmd_name = get_config_parameter!(conf,"transformation.cmd");
          let cmd_name = cmd_name.replace("{working_dir}", &working_dir);
          let cmd_name = cmd_name.replace("{file}", &file_path);

          println!("cmd: {}", cmd_name);

          let mut cmd_args: Vec<&str> = cmd_name.split_whitespace()
                                            .collect();

          let res = Command::new(cmd_args.remove(0))
                            .args(&cmd_args)
                            .status()
                            .unwrap_or_else(|e| {
                              println!("failed to execute process: {}", e);
                              panic!("failed to execute process: {}", e);
                            });

          println!("process exited with: {}", res);

          if res.success() {
            let ref file_path = format!("{}.pdf" , file_param.path().display());
            println!("file_path: {}", file_path);
            return Ok(Response::with((status::Ok, Path::new(file_path))))
          }
          else {
            // copy the file in an error dirctory for further investigations
            let err_destination_dir = get_config_parameter!(conf,"transformation.err_destination_dir");
            //             let res = Command::new("mkdir")
            //                               .args(&["-p",err_destination_dir])
            //                               .status()
            //                               .unwrap_or_else(|e| {
            //                                 println!("failed to execute process: {}", e);
            //                                 panic!("failed to execute process: {}", e);
            //                               });

            Command::new("nice")
            .args(&["-n","20","cp","-R", &working_dir, err_destination_dir])
            .spawn()
            .unwrap_or_else(|e| {
              println!("failed to execute process: {}", e);
              panic!("failed to execute process: {}", e);
            });

            return Ok(Response::with(status::InternalServerError))

          }

        }
      }
    }
  }

}

#[macro_use]
mod param_rules;

require_param!(RequireMd5sumParam, "sha1sum", String);
require_param!(RequireFileParam, "filename", params::File);

mod logger;

use logger::Logger;
use iron::{AroundMiddleware};
fn start_server() {
   let mut router = Router::new();
   let mut chain_form_file = Chain::new(submit_form_file);

   chain_form_file.link_before(RequireMd5sumParam);
   chain_form_file.link_before(RequireFileParam);

   router.post("/openact", Logger::default().around(Box::new(chain_form_file)));

   println!("started server at http://localhost:3000/");
   Iron::new(router).http("localhost:3000").unwrap();
}

fn main() {
    println!("Hello, world!");
    start_server();
}
<|endoftext|>


<commit_before>use elsa::FrozenMap;
use fluent::{FluentBundle, FluentResource};
use fluent_fallback::Localization;
use fluent_langneg::{accepted_languages, negotiate_languages, NegotiationStrategy};
use git2::Repository;
use regex::Regex;
use std::env;
use std::fs;
use std::io;
use std::io::prelude::*;
use std::io::{Error, ErrorKind};
use std::iter;
use std::path;
use std::str;
use std::vec;
use structopt::clap::AppSettings;
use structopt::StructOpt;
use unic_langid::LanguageIdentifier;

/// The command line interface to the CaSILE toolkit, a book publishing
/// workflow employing SILE and other wizardry
#[derive(StructOpt)]
#[structopt(version = env!("VERGEN_SEMVER"))]
#[structopt(setting = AppSettings::InferSubcommands)]
struct Cli {
    /// Activate debug mode
    #[structopt(short, long, env = "DEBUG")]
    debug: bool,

    /// Set language
    #[structopt(short, long, env = "LANG")]
    language: String,

    /// Outputs verbose feedback where possible
    #[structopt(short, long)]
    verbose: bool,

    #[structopt(subcommand)]
    subcommand: Subcommand,
}

#[derive(StructOpt)]
enum Subcommand {
    /// Executes a make target
    Make {
        /// Target as defined in CaSILE makefile
        target: Vec<String>,
    },

    /// Configure a book repository
    Setup {
        /// Path to project repository
        #[structopt(parse(from_os_str), default_value = "./")]
        path: path::PathBuf,
    },

    /// Pass through other commands to shell
    #[structopt(external_subcommand)]
    Other(Vec<String>),
}

static L10N_RESOURCES: &[&str] = &["cli.ftl"];

fn main() -> io::Result<()> {
    let args = Cli::from_args();

    if args.debug {
        println!("User requested debug mode")
    }

    if args.verbose {
        println!("User requested verbose output")
    }

    let available = get_available_locales().expect("Could not find valid BCP47 resource files.");
    let re = Regex::new(r"\..*$").unwrap();
    let input = re.replace(&args.language, "");
    let requested = accepted_languages::parse(&input);
    let default: LanguageIdentifier = "en-US".parse().unwrap();
    let resolved_locales = negotiate_languages(
        &requested,
        &available,
        Some(&default),
        NegotiationStrategy::Filtering,
    );

    let resources: FrozenMap<String, Box<FluentResource>> = FrozenMap::new();
    let mut res_path_scheme = env::current_dir().expect("Failed to retireve current dir.");
    res_path_scheme.push("resources");
    res_path_scheme.push("{locale}");
    res_path_scheme.push("{res_id}");
    let res_path_scheme = res_path_scheme.to_str().unwrap();
    let generate_messages = |res_ids: &[String]| {
        let mut locales = resolved_locales.iter();
        let res_mgr = &resources;
        let res_ids = res_ids.to_vec();

        iter::from_fn(move || {
            locales.next().map(|locale| {
                let mut bundle = FluentBundle::new(vec![locale.clone()]);
                let res_path = res_path_scheme.replace("{locale}", &locale.to_string());

                for res_id in &res_ids {
                    let path = res_path.replace("{res_id}", res_id);
                    let res = res_mgr.get(&path).unwrap_or_else(|| {
                        let source = read_file(&path).unwrap();
                        let res = FluentResource::try_new(source).unwrap();
                        res_mgr.insert(path.to_string(), Box::new(res))
                    });
                    bundle.add_resource(res).unwrap();
                }
                bundle
            })
        })
    };
    let loc = Localization::new(
        L10N_RESOURCES.iter().map(|s| s.to_string()).collect(),
        generate_messages,
    );

    let value = loc.format_value("debug-shell", None);
    println!("Message is: {}", value);

    match args.subcommand {
        Subcommand::Make { target } => make(target),
        Subcommand::Setup { path } => setup(path),
        _a => shell(),
    }
}

fn make(_target: vec::Vec<String>) -> io::Result<()> {
    println!("Make make make sense or I’ll make you make makefiles.");
    Ok(())
}

fn setup(path: path::PathBuf) -> io::Result<()> {
    let metadata = fs::metadata(&path)?;
    match metadata.is_dir() {
        true => match Repository::open(path) {
            Ok(_repo) => Ok(println!(
                "Run setup, “They said you were this great colossus!”"
            )),
            Err(_error) => Err(Error::new(ErrorKind::InvalidInput, "Not a git repo!")),
        },
        false => Err(Error::new(ErrorKind::InvalidInput, "Not a dir, Frank!")),
    }
}

fn shell() -> io::Result<()> {
    println!("Ship all this off to the shell, maybe they can handle it.");
    Ok(())
}

// https://github.com/projectfluent/fluent-rs/blob/c9e45651/fluent-fallback/examples/simple-fallback.rs#L38
fn read_file(path: &str) -> Result<String, io::Error> {
    let mut f = fs::File::open(path)?;
    let mut s = String::new();
    f.read_to_string(&mut s)?;
    Ok(s)
}

// TODO: Move to build.rs?
// https://github.com/projectfluent/fluent-rs/blob/c9e45651/fluent-resmgr/examples/simple-resmgr.rs#L35
fn get_available_locales() -> Result<Vec<LanguageIdentifier>, io::Error> {
    let mut locales = vec![];
    let res_dir = fs::read_dir("./resources/")?;
    for entry in res_dir {
        if let Ok(entry) = entry {
            let path = entry.path();
            if path.is_dir() {
                if let Some(name) = path.file_name() {
                    if let Some(name) = name.to_str() {
                        let langid: LanguageIdentifier =
                            name.parse().expect("Could not parse BCP47 language tag.");
                        locales.push(langid);
                    }
                }
            }
        }
    }
    return Ok(locales);
}
<commit_msg>refactor(cli): Move structopt setup into main() so we can localize it<commit_after>use elsa::FrozenMap;
use fluent::{FluentBundle, FluentResource};
use fluent_fallback::Localization;
use fluent_langneg::{accepted_languages, negotiate_languages, NegotiationStrategy};
use git2::Repository;
use regex::Regex;
use std::env;
use std::fs;
use std::io;
use std::io::prelude::*;
use std::io::{Error, ErrorKind};
use std::iter;
use std::path;
use std::str;
use std::vec;
use structopt::clap::AppSettings;
use structopt::StructOpt;
use unic_langid::LanguageIdentifier;

static L10N_RESOURCES: &[&str] = &["cli.ftl"];

fn main() -> io::Result<()> {
    /// The command line interface to the CaSILE toolkit, a book publishing
    /// workflow employing SILE and other wizardry
    #[derive(StructOpt)]
    #[structopt(version = env!("VERGEN_SEMVER"))]
    #[structopt(setting = AppSettings::InferSubcommands)]
    struct Cli {
        /// Activate debug mode
        #[structopt(short, long, env = "DEBUG")]
        debug: bool,

        /// Set language
        #[structopt(short, long, env = "LANG")]
        language: String,

        /// Outputs verbose feedback where possible
        #[structopt(short, long)]
        verbose: bool,

        #[structopt(subcommand)]
        subcommand: Subcommand,
    }

    #[derive(StructOpt)]
    enum Subcommand {
        /// Executes a make target
        Make {
            /// Target as defined in CaSILE makefile
            target: Vec<String>,
        },

        /// Configure a book repository
        Setup {
            /// Path to project repository
            #[structopt(parse(from_os_str), default_value = "./")]
            path: path::PathBuf,
        },

        /// Pass through other commands to shell
        #[structopt(external_subcommand)]
        Other(Vec<String>),
    }

    let args = Cli::from_args();

    if args.debug {
        println!("User requested debug mode")
    }

    if args.verbose {
        println!("User requested verbose output")
    }

    let available = get_available_locales().expect("Could not find valid BCP47 resource files.");
    let re = Regex::new(r"\..*$").unwrap();
    let input = re.replace(&args.language, "");
    let requested = accepted_languages::parse(&input);
    let default: LanguageIdentifier = "en-US".parse().unwrap();
    let resolved_locales = negotiate_languages(
        &requested,
        &available,
        Some(&default),
        NegotiationStrategy::Filtering,
    );

    let resources: FrozenMap<String, Box<FluentResource>> = FrozenMap::new();
    let mut res_path_scheme = env::current_dir().expect("Failed to retireve current dir.");
    res_path_scheme.push("resources");
    res_path_scheme.push("{locale}");
    res_path_scheme.push("{res_id}");
    let res_path_scheme = res_path_scheme.to_str().unwrap();
    let generate_messages = |res_ids: &[String]| {
        let mut locales = resolved_locales.iter();
        let res_mgr = &resources;
        let res_ids = res_ids.to_vec();

        iter::from_fn(move || {
            locales.next().map(|locale| {
                let mut bundle = FluentBundle::new(vec![locale.clone()]);
                let res_path = res_path_scheme.replace("{locale}", &locale.to_string());

                for res_id in &res_ids {
                    let path = res_path.replace("{res_id}", res_id);
                    let res = res_mgr.get(&path).unwrap_or_else(|| {
                        let source = read_file(&path).unwrap();
                        let res = FluentResource::try_new(source).unwrap();
                        res_mgr.insert(path.to_string(), Box::new(res))
                    });
                    bundle.add_resource(res).unwrap();
                }
                bundle
            })
        })
    };
    let loc = Localization::new(
        L10N_RESOURCES.iter().map(|s| s.to_string()).collect(),
        generate_messages,
    );

    let value = loc.format_value("debug-shell", None);
    println!("Message is: {}", value);

    match args.subcommand {
        Subcommand::Make { target } => make(target),
        Subcommand::Setup { path } => setup(path),
        _a => shell(),
    }
}

fn make(_target: vec::Vec<String>) -> io::Result<()> {
    println!("Make make make sense or I’ll make you make makefiles.");
    Ok(())
}

fn setup(path: path::PathBuf) -> io::Result<()> {
    let metadata = fs::metadata(&path)?;
    match metadata.is_dir() {
        true => match Repository::open(path) {
            Ok(_repo) => Ok(println!(
                "Run setup, “They said you were this great colossus!”"
            )),
            Err(_error) => Err(Error::new(ErrorKind::InvalidInput, "Not a git repo!")),
        },
        false => Err(Error::new(ErrorKind::InvalidInput, "Not a dir, Frank!")),
    }
}

fn shell() -> io::Result<()> {
    println!("Ship all this off to the shell, maybe they can handle it.");
    Ok(())
}

// https://github.com/projectfluent/fluent-rs/blob/c9e45651/fluent-fallback/examples/simple-fallback.rs#L38
fn read_file(path: &str) -> Result<String, io::Error> {
    let mut f = fs::File::open(path)?;
    let mut s = String::new();
    f.read_to_string(&mut s)?;
    Ok(s)
}

// TODO: Move to build.rs?
// https://github.com/projectfluent/fluent-rs/blob/c9e45651/fluent-resmgr/examples/simple-resmgr.rs#L35
fn get_available_locales() -> Result<Vec<LanguageIdentifier>, io::Error> {
    let mut locales = vec![];
    let res_dir = fs::read_dir("./resources/")?;
    for entry in res_dir {
        if let Ok(entry) = entry {
            let path = entry.path();
            if path.is_dir() {
                if let Some(name) = path.file_name() {
                    if let Some(name) = name.to_str() {
                        let langid: LanguageIdentifier =
                            name.parse().expect("Could not parse BCP47 language tag.");
                        locales.push(langid);
                    }
                }
            }
        }
    }
    return Ok(locales);
}
<|endoftext|>