<commit_before>extern crate document;
extern crate xpath;

use std::cell::RefCell;
use std::rc::Rc;
use std::collections::HashMap;

use document::{Document,Element,Nodeset};

use xpath::XPathValue;
use xpath::{Boolean, Number, String, Nodes};
use xpath::XPathNodeTest;
use xpath::expression::XPathExpression;
use xpath::expression::{ExpressionAnd,
                        ExpressionEqual,
                        ExpressionNotEqual,
                        ExpressionFunction,
                        ExpressionLiteral,
                        ExpressionMath,
                        ExpressionPredicate,
                        ExpressionRelational,
                        ExpressionRootNode,
                        ExpressionStep,
                        ExpressionUnion,
                        ExpressionVariable};
use xpath::XPathFunction;
use xpath::XPathEvaluationContext;
use xpath::{Functions,Variables};
use xpath::axis::XPathAxis;

struct FailExpression;

impl XPathExpression for FailExpression {
    fn evaluate(&self, _: &XPathEvaluationContext) -> XPathValue {
        fail!("Should never be called");
    }
}

struct Setup {
    doc: Document,
    node: Element,
    funs: Functions,
    vars: Variables,
}

impl Setup {
    fn new() -> Setup {
        let d = Document::new();
        let n = d.new_element("test".to_string());
        Setup {
            doc: d,
            node: n,
            funs: HashMap::new(),
            vars: HashMap::new(),
        }
    }

    fn context(&self) -> XPathEvaluationContext {
        XPathEvaluationContext::new(self.node.clone(), &self.funs, &self.vars)
    }
}

#[test]
fn expression_and_returns_logical_and() {
    let setup = Setup::new();

    let left  = box ExpressionLiteral{value: Boolean(true)};
    let right = box ExpressionLiteral{value: Boolean(true)};

    let expr = ExpressionAnd{left: left, right: right};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Boolean(true));
}

#[test]
fn expression_and_short_circuits_when_left_argument_is_false() {
    let setup = Setup::new();

    let left  = box ExpressionLiteral{value: Boolean(false)};
    let right = box FailExpression;

    let expr = ExpressionAnd{left: left, right: right};

    let context = setup.context();
    expr.evaluate(&context);
    // assert_not_fail
}

#[test]
fn expression_equal_compares_as_boolean_if_one_argument_is_a_boolean() {
    let setup = Setup::new();

    let actual_bool = box ExpressionLiteral{value: Boolean(false)};
    let truthy_str = box ExpressionLiteral{value: String("hello".to_string())};

    let expr = ExpressionEqual{left: actual_bool, right: truthy_str};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Boolean(false));
}

#[test]
fn expression_equal_compares_as_number_if_one_argument_is_a_number() {
    let setup = Setup::new();

    let actual_number = box ExpressionLiteral{value: Number(-42.0)};
    let number_str = box ExpressionLiteral{value: String("-42.0".to_string())};

    let expr = ExpressionEqual{left: number_str, right: actual_number};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Boolean(true));
}

#[test]
fn expression_equal_compares_as_string_otherwise() {
    let setup = Setup::new();

    let a_str = box ExpressionLiteral{value: String("hello".to_string())};
    let b_str = box ExpressionLiteral{value: String("World".to_string())};

    let expr = ExpressionEqual{left: a_str, right: b_str};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Boolean(false));
}

#[test]
fn expression_not_equal_negates_equality() {
    let setup = Setup::new();

    let a_str = box ExpressionLiteral{value: Boolean(true)};
    let b_str = box ExpressionLiteral{value: Boolean(false)};

    let expr = ExpressionNotEqual::new(a_str, b_str);

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Boolean(true));
}

struct StubFunction {
    value: XPathValue,
}

impl XPathFunction for StubFunction {
    fn evaluate(&self,
                _: &XPathEvaluationContext,
                _: Vec<XPathValue>) -> XPathValue
    {
        self.value.clone()
    }
}

#[test]
fn expression_function_evaluates_input_arguments() {
    let mut setup = Setup::new();

    let arg_expr: Box<XPathExpression> = box ExpressionLiteral{value: Boolean(true)};
    let fun = box StubFunction{value: String("the function ran".to_string())};
    setup.funs.insert("test-fn".to_string(), fun);

    let expr = ExpressionFunction{name: "test-fn".to_string(), arguments: vec!(arg_expr)};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, String("the function ran".to_string()));
}

#[test]
fn expression_function_unknown_function_is_reported_as_an_error() {
    let setup = Setup::new();

    let expr = ExpressionFunction{name: "unknown-fn".to_string(), arguments: vec!()};

    let context = setup.context();
    expr.evaluate(&context);
    // TODO: report errors better
}

#[test]
fn expression_math_does_basic_math() {
    let setup = Setup::new();

    let left  = box ExpressionLiteral{value: Number(10.0)};
    let right = box ExpressionLiteral{value: Number(5.0)};

    let expr = ExpressionMath::multiplication(left, right);

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Number(50.0));
}

#[test]
fn expression_step_numeric_predicate_selects_that_node() {
    let setup = Setup::new();

    let input_node_1 = setup.doc.new_element("one".to_string());
    let input_node_2 = setup.doc.new_element("two".to_string());
    let mut input_nodeset = Nodeset::new();
    input_nodeset.add(input_node_1.clone());
    input_nodeset.add(input_node_2);

    let selected_nodes = box ExpressionLiteral{value: Nodes(input_nodeset)};
    let predicate = box ExpressionLiteral{value: Number(1.0)};

    let expr = ExpressionPredicate{node_selector: selected_nodes, predicate: predicate};

    let context = setup.context();
    let res = expr.evaluate(&context);

    let mut expected = Nodeset::new();
    expected.add(input_node_1);

    assert_eq!(res, Nodes(expected));
}

#[test]
fn expression_step_false_predicate_selects_no_nodes() {
    let setup = Setup::new();

    let input_node_1 = setup.doc.new_element("one".to_string());
    let input_node_2 = setup.doc.new_element("two".to_string());
    let mut input_nodeset = Nodeset::new();
    input_nodeset.add(input_node_1);
    input_nodeset.add(input_node_2);

    let selected_nodes = box ExpressionLiteral{value: Nodes(input_nodeset)};
    let predicate = box ExpressionLiteral{value: Boolean(false)};

    let expr = ExpressionPredicate{node_selector: selected_nodes, predicate: predicate};

    let context = setup.context();
    let res = expr.evaluate(&context);

    let expected = Nodeset::new();
    assert_eq!(res, Nodes(expected));
}

#[test]
fn expression_relational_does_basic_comparisons() {
    let setup = Setup::new();

    let left  = box ExpressionLiteral{value: Number(10.0)};
    let right = box ExpressionLiteral{value: Number(5.0)};

    let expr = ExpressionRelational::less_than(left, right);

    let context = setup.context();
    let res = expr.evaluate(&context);
    assert_eq!(res, Boolean(false));
}

#[test]
fn expression_root_node_finds_the_root() {
    let setup = Setup::new();

    let expr = ExpressionRootNode;

    let context = setup.context();
    let res = expr.evaluate(&context);

    let mut expected = Nodeset::new();
    expected.add(setup.doc.root());

    assert_eq!(res, Nodes(expected));
}

#[deriving(Clone)]
struct MockAxis {
    calls: Rc<RefCell<uint>>,
}

impl MockAxis {
    fn new() -> MockAxis {
        MockAxis{ calls: Rc::new(RefCell::new(0)) }
    }

    fn calls(&self) -> uint {
        *self.calls.borrow()
    }
}

impl XPathAxis for MockAxis {
    fn select_nodes(&self,
                    context:   &XPathEvaluationContext,
                    node_test: &XPathNodeTest,
                    result:    &mut Nodeset)
    {
        *self.calls.borrow_mut() += 1;
    }
}

struct DummyNodeTest;

impl XPathNodeTest for DummyNodeTest {
    fn test(&self, context: &XPathEvaluationContext, result: &mut Nodeset) {
    }
}

#[test]
fn expression_step_delegates_to_the_axis() {
    let setup = Setup::new();

    let axis = MockAxis::new();
    let node_test = DummyNodeTest;

    let expr = ExpressionStep::new(box axis.clone(), box node_test);

    let context = setup.context();
    expr.evaluate(&context);

    assert_eq!(1, axis.calls());
}

#[test]
fn expression_union_combines_nodesets() {
    let setup = Setup::new();

    let build = |name: &str| {
        let node = setup.doc.new_element(name.to_string());
        let mut nodes = Nodeset::new();
        nodes.add(node.clone());
        (node, box ExpressionLiteral{value: Nodes(nodes)})
    };

    let (left_node, left) = build("left");
    let (right_node, right) = build("right");

    let expr = ExpressionUnion{left: left, right: right};

    let context = setup.context();
    let res = expr.evaluate(&context);

    let mut expected = Nodeset::new();
    expected.add(left_node);
    expected.add(right_node);

    assert_eq!(Nodes(expected), res);
}

#[test]
fn expression_variable_looks_up_the_variable() {
    let mut setup = Setup::new();
    setup.vars.insert("foo".to_string(), Boolean(true));

    let expr = ExpressionVariable{name: "foo".to_string()};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(Boolean(true), res);
}
<commit_msg>Fix warnings in xpath-expression-test<commit_after>extern crate document;
extern crate xpath;

use std::cell::RefCell;
use std::rc::Rc;
use std::collections::HashMap;

use document::{Document,Element,Nodeset};

use xpath::XPathValue;
use xpath::{Boolean, Number, String, Nodes};
use xpath::XPathNodeTest;
use xpath::expression::XPathExpression;
use xpath::expression::{ExpressionAnd,
                        ExpressionEqual,
                        ExpressionNotEqual,
                        ExpressionFunction,
                        ExpressionLiteral,
                        ExpressionMath,
                        ExpressionPredicate,
                        ExpressionRelational,
                        ExpressionRootNode,
                        ExpressionStep,
                        ExpressionUnion,
                        ExpressionVariable};
use xpath::XPathFunction;
use xpath::XPathEvaluationContext;
use xpath::{Functions,Variables};
use xpath::axis::XPathAxis;

struct FailExpression;

impl XPathExpression for FailExpression {
    fn evaluate(&self, _: &XPathEvaluationContext) -> XPathValue {
        fail!("Should never be called");
    }
}

struct Setup {
    doc: Document,
    node: Element,
    funs: Functions,
    vars: Variables,
}

impl Setup {
    fn new() -> Setup {
        let d = Document::new();
        let n = d.new_element("test".to_string());
        Setup {
            doc: d,
            node: n,
            funs: HashMap::new(),
            vars: HashMap::new(),
        }
    }

    fn context(&self) -> XPathEvaluationContext {
        XPathEvaluationContext::new(self.node.clone(), &self.funs, &self.vars)
    }
}

#[test]
fn expression_and_returns_logical_and() {
    let setup = Setup::new();

    let left  = box ExpressionLiteral{value: Boolean(true)};
    let right = box ExpressionLiteral{value: Boolean(true)};

    let expr = ExpressionAnd{left: left, right: right};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Boolean(true));
}

#[test]
fn expression_and_short_circuits_when_left_argument_is_false() {
    let setup = Setup::new();

    let left  = box ExpressionLiteral{value: Boolean(false)};
    let right = box FailExpression;

    let expr = ExpressionAnd{left: left, right: right};

    let context = setup.context();
    expr.evaluate(&context);
    // assert_not_fail
}

#[test]
fn expression_equal_compares_as_boolean_if_one_argument_is_a_boolean() {
    let setup = Setup::new();

    let actual_bool = box ExpressionLiteral{value: Boolean(false)};
    let truthy_str = box ExpressionLiteral{value: String("hello".to_string())};

    let expr = ExpressionEqual{left: actual_bool, right: truthy_str};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Boolean(false));
}

#[test]
fn expression_equal_compares_as_number_if_one_argument_is_a_number() {
    let setup = Setup::new();

    let actual_number = box ExpressionLiteral{value: Number(-42.0)};
    let number_str = box ExpressionLiteral{value: String("-42.0".to_string())};

    let expr = ExpressionEqual{left: number_str, right: actual_number};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Boolean(true));
}

#[test]
fn expression_equal_compares_as_string_otherwise() {
    let setup = Setup::new();

    let a_str = box ExpressionLiteral{value: String("hello".to_string())};
    let b_str = box ExpressionLiteral{value: String("World".to_string())};

    let expr = ExpressionEqual{left: a_str, right: b_str};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Boolean(false));
}

#[test]
fn expression_not_equal_negates_equality() {
    let setup = Setup::new();

    let a_str = box ExpressionLiteral{value: Boolean(true)};
    let b_str = box ExpressionLiteral{value: Boolean(false)};

    let expr = ExpressionNotEqual::new(a_str, b_str);

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Boolean(true));
}

struct StubFunction {
    value: XPathValue,
}

impl XPathFunction for StubFunction {
    fn evaluate(&self,
                _: &XPathEvaluationContext,
                _: Vec<XPathValue>) -> XPathValue
    {
        self.value.clone()
    }
}

#[test]
fn expression_function_evaluates_input_arguments() {
    let mut setup = Setup::new();

    let arg_expr: Box<XPathExpression> = box ExpressionLiteral{value: Boolean(true)};
    let fun = box StubFunction{value: String("the function ran".to_string())};
    setup.funs.insert("test-fn".to_string(), fun);

    let expr = ExpressionFunction{name: "test-fn".to_string(), arguments: vec!(arg_expr)};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, String("the function ran".to_string()));
}

#[test]
fn expression_function_unknown_function_is_reported_as_an_error() {
    let setup = Setup::new();

    let expr = ExpressionFunction{name: "unknown-fn".to_string(), arguments: vec!()};

    let context = setup.context();
    expr.evaluate(&context);
    // TODO: report errors better
}

#[test]
fn expression_math_does_basic_math() {
    let setup = Setup::new();

    let left  = box ExpressionLiteral{value: Number(10.0)};
    let right = box ExpressionLiteral{value: Number(5.0)};

    let expr = ExpressionMath::multiplication(left, right);

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(res, Number(50.0));
}

#[test]
fn expression_step_numeric_predicate_selects_that_node() {
    let setup = Setup::new();

    let input_node_1 = setup.doc.new_element("one".to_string());
    let input_node_2 = setup.doc.new_element("two".to_string());
    let mut input_nodeset = Nodeset::new();
    input_nodeset.add(input_node_1.clone());
    input_nodeset.add(input_node_2);

    let selected_nodes = box ExpressionLiteral{value: Nodes(input_nodeset)};
    let predicate = box ExpressionLiteral{value: Number(1.0)};

    let expr = ExpressionPredicate{node_selector: selected_nodes, predicate: predicate};

    let context = setup.context();
    let res = expr.evaluate(&context);

    let mut expected = Nodeset::new();
    expected.add(input_node_1);

    assert_eq!(res, Nodes(expected));
}

#[test]
fn expression_step_false_predicate_selects_no_nodes() {
    let setup = Setup::new();

    let input_node_1 = setup.doc.new_element("one".to_string());
    let input_node_2 = setup.doc.new_element("two".to_string());
    let mut input_nodeset = Nodeset::new();
    input_nodeset.add(input_node_1);
    input_nodeset.add(input_node_2);

    let selected_nodes = box ExpressionLiteral{value: Nodes(input_nodeset)};
    let predicate = box ExpressionLiteral{value: Boolean(false)};

    let expr = ExpressionPredicate{node_selector: selected_nodes, predicate: predicate};

    let context = setup.context();
    let res = expr.evaluate(&context);

    let expected = Nodeset::new();
    assert_eq!(res, Nodes(expected));
}

#[test]
fn expression_relational_does_basic_comparisons() {
    let setup = Setup::new();

    let left  = box ExpressionLiteral{value: Number(10.0)};
    let right = box ExpressionLiteral{value: Number(5.0)};

    let expr = ExpressionRelational::less_than(left, right);

    let context = setup.context();
    let res = expr.evaluate(&context);
    assert_eq!(res, Boolean(false));
}

#[test]
fn expression_root_node_finds_the_root() {
    let setup = Setup::new();

    let expr = ExpressionRootNode;

    let context = setup.context();
    let res = expr.evaluate(&context);

    let mut expected = Nodeset::new();
    expected.add(setup.doc.root());

    assert_eq!(res, Nodes(expected));
}

#[deriving(Clone)]
struct MockAxis {
    calls: Rc<RefCell<uint>>,
}

impl MockAxis {
    fn new() -> MockAxis {
        MockAxis{ calls: Rc::new(RefCell::new(0)) }
    }

    fn calls(&self) -> uint {
        *self.calls.borrow()
    }
}

impl XPathAxis for MockAxis {
    fn select_nodes(&self,
                    _context:   &XPathEvaluationContext,
                    _node_test: &XPathNodeTest,
                    _result:    &mut Nodeset)
    {
        *self.calls.borrow_mut() += 1;
    }
}

struct DummyNodeTest;

impl XPathNodeTest for DummyNodeTest {
    fn test(&self, _context: &XPathEvaluationContext, _result: &mut Nodeset) {
    }
}

#[test]
fn expression_step_delegates_to_the_axis() {
    let setup = Setup::new();

    let axis = MockAxis::new();
    let node_test = DummyNodeTest;

    let expr = ExpressionStep::new(box axis.clone(), box node_test);

    let context = setup.context();
    expr.evaluate(&context);

    assert_eq!(1, axis.calls());
}

#[test]
fn expression_union_combines_nodesets() {
    let setup = Setup::new();

    let build = |name: &str| {
        let node = setup.doc.new_element(name.to_string());
        let mut nodes = Nodeset::new();
        nodes.add(node.clone());
        (node, box ExpressionLiteral{value: Nodes(nodes)})
    };

    let (left_node, left) = build("left");
    let (right_node, right) = build("right");

    let expr = ExpressionUnion{left: left, right: right};

    let context = setup.context();
    let res = expr.evaluate(&context);

    let mut expected = Nodeset::new();
    expected.add(left_node);
    expected.add(right_node);

    assert_eq!(Nodes(expected), res);
}

#[test]
fn expression_variable_looks_up_the_variable() {
    let mut setup = Setup::new();
    setup.vars.insert("foo".to_string(), Boolean(true));

    let expr = ExpressionVariable{name: "foo".to_string()};

    let context = setup.context();
    let res = expr.evaluate(&context);

    assert_eq!(Boolean(true), res);
}
<|endoftext|>


<commit_before>//! The driver trait which all drivers will implement.

use error::Error;
use query::{Condition, SortRule, Range, Query};
use schema::Type;
use value::ValueIter;

pub trait Driver {
  /// Connects to a driver and returns a driver instance. After calling this
  /// the driver is ready to roll!
  fn connect(uri: &str) -> Result<Self, Error> where Self: Sized;

  // TODO: doc.
  fn read(
    &self,
    type_: &Type,
    condition: Condition,
    sort: Vec<SortRule>,
    range: Range,
    query: Query
  ) -> Result<ValueIter, Error>;
}
<commit_msg>doc: add inline docs for driver read function<commit_after>//! The driver trait which all drivers will implement.

use error::Error;
use query::{Condition, SortRule, Range, Query};
use schema::Type;
use value::ValueIter;

pub trait Driver {
  /// Connects to a driver and returns a driver instance. After calling this
  /// the driver is ready to roll!
  fn connect(uri: &str) -> Result<Self, Error> where Self: Sized;

  /// Lazily read some values from the driver.
  ///
  /// Designed against a couple of database specifications. Including the
  /// following:
  ///
  /// - [SQL `SELECT` statement][1].
  /// - [MongoDB `find` command][2].
  ///
  /// [1]: http://www.postgresql.org/docs/current/static/sql-select.html
  /// [2]: https://docs.mongodb.org/manual/reference/command/find/
  fn read(
    &self,
    type_: &Type,
    condition: Condition,
    sort: Vec<SortRule>,
    range: Range,
    query: Query
  ) -> Result<ValueIter, Error>;
}
<|endoftext|>


<commit_before>#![crate_id = "graphics_impl"]
extern crate sdl;

pub struct Screen {
    surface :sdl::video::Surface,
    on_color : sdl::video::Color,
    off_color :sdl::video::Color,
    width: uint,
    height: uint,
    x_max :uint,
    y_max :uint

}

impl Screen {

    pub fn new(width :int, height :int, x_max :uint, y_max :uint) -> Screen {
        sdl::init([sdl::InitVideo]);
        sdl::wm::set_caption("CHIP-8 Emulator", "sdl");

        let surface =
            match sdl::video::set_video_mode(width, height, 32,
            [sdl::video::HWSurface], [sdl::video::DoubleBuf]) {

                Ok(screen) => screen,
                Err(err) => fail!("failed to set video mode: {}", err)
            };

        Screen { surface:surface,
                 on_color:  sdl::video::RGB(0, 255, 0), /* Green */
                 off_color: sdl::video::RGB(0, 0,   0), /* Black */
                 width:width as uint,
                 height:height as uint,
                 x_max:x_max,
                 y_max:y_max
               }
        }

    pub fn set_x_max(&mut self, x:uint) {
        self.x_max = x;
    }

    pub fn set_y_max(&mut self, y:uint) {
        self.y_max = y;
    }

    pub fn draw_pix(&mut self, x_pos :int, y_pos :int, set:bool) {
        let x_unit = (self.width/self.x_max) as u16;
        let y_unit = (self.height/self.y_max) as u16;

        self.surface.fill_rect(Some(sdl::Rect {
            x: x_pos as i16 * x_unit as i16,
            y: y_pos as i16 * y_unit as i16,
            w: x_unit,
            h: y_unit,
        }), match set { true => self.on_color, false => self.off_color });

    }

    pub fn clear_screen(&mut self) {
        self.surface.fill_rect(Some(sdl::Rect {
            x: 0,
            y: 0,
            w: self.width as u16,
            h: self.height as u16,
        }), self.off_color);
    }

    pub fn show(&self) {
        self.surface.flip();
    }

}

/*
  // Note: You'll want to put this and the flip call inside the main loop
  // but we don't as to not startle epileptics
  for i in range(0, 10) {
      for j in range(0, 10) {
          screen.fill_rect(Some(sdl::Rect {
              x: (i as i16) * 800 / 10,
              y: (j as i16) * 600 / 10,
              w: 800 / 10,
              h: 600 / 10
          }), rng.gen::<sdl::video::Color>());
      }
  }

  screen.flip();

  'main : loop {
      'event : loop {
          match sdl::event::poll_event() {
              sdl::event::QuitEvent => break 'main,
              sdl::event::NoEvent => break 'event,
              sdl::event::KeyEvent(k, _, _, _)
                  if k == sdl::event::EscapeKey
                      => break 'main,
              _ => {}
          }
      }
  }

  sdl::quit();
}
*/
<commit_msg>Removed block of commented code<commit_after>#![crate_id = "graphics_impl"]
extern crate sdl;

pub struct Screen {
    surface :sdl::video::Surface,
    on_color : sdl::video::Color,
    off_color :sdl::video::Color,
    width: uint,
    height: uint,
    x_max :uint,
    y_max :uint

}

impl Screen {

    pub fn new(width :int, height :int, x_max :uint, y_max :uint) -> Screen {
        sdl::init([sdl::InitVideo]);
        sdl::wm::set_caption("CHIP-8 Emulator", "sdl");

        let surface =
            match sdl::video::set_video_mode(width, height, 32,
            [sdl::video::HWSurface], [sdl::video::DoubleBuf]) {

                Ok(screen) => screen,
                Err(err) => fail!("failed to set video mode: {}", err)
            };

        Screen { surface:surface,
                 on_color:  sdl::video::RGB(0, 255, 0), /* Green */
                 off_color: sdl::video::RGB(0, 0,   0), /* Black */
                 width:width as uint,
                 height:height as uint,
                 x_max:x_max,
                 y_max:y_max
               }
        }

    pub fn set_x_max(&mut self, x:uint) {
        self.x_max = x;
    }

    pub fn set_y_max(&mut self, y:uint) {
        self.y_max = y;
    }

    pub fn draw_pix(&mut self, x_pos :int, y_pos :int, set:bool) {
        let x_unit = (self.width/self.x_max) as u16;
        let y_unit = (self.height/self.y_max) as u16;

        self.surface.fill_rect(Some(sdl::Rect {
            x: x_pos as i16 * x_unit as i16,
            y: y_pos as i16 * y_unit as i16,
            w: x_unit,
            h: y_unit,
        }), match set { true => self.on_color, false => self.off_color });

    }

    pub fn clear_screen(&mut self) {
        self.surface.fill_rect(Some(sdl::Rect {
            x: 0,
            y: 0,
            w: self.width as u16,
            h: self.height as u16,
        }), self.off_color);
    }

    pub fn show(&self) {
        self.surface.flip();
    }

}
<|endoftext|>


<commit_before>extern crate libc;
extern crate notify;

use notify::{RecommendedWatcher, Error, Watcher, Event};
use std::sync::mpsc::{channel, Receiver, RecvError};

use std::collections::HashMap;
use std::io;
use std::path::PathBuf;

use actions::Action;

pub struct FilesWatcher {
    watcher: Box<RecommendedWatcher>,
    rx: Receiver<Event>,
    watches: HashMap<PathBuf, Vec<Box<Action>>>,
}

impl FilesWatcher {
    pub fn new() -> FilesWatcher {
        let (tx, rx) = channel();
        let watcher: Result<RecommendedWatcher, Error> = Watcher::new(tx);

        FilesWatcher {
            watcher: Box::new(watcher.unwrap()),
            rx: rx,
            watches: HashMap::new(),
        }
    }

    pub fn add_file(&mut self, path: PathBuf, actions: Vec<Box<Action>>) {
        let result = self.watcher.watch(&path);

        if result.is_ok() {
            println!("Watching file: {:?}", path);
            self.watches.insert(path, actions);
        } else {
            println!("Error adding watch for file: {:?}", result.err());
        }
    }

    pub fn wait_for_events(&mut self) -> Result<Event, RecvError> {
        self.rx.recv()
    }

    pub fn wait_and_execute(&mut self) -> Result<i32, io::Error> {
        let mut num_actions = 0;
        let event_result = self.rx.recv();

        match event_result {
            Err(_) => Err(io::Error::new(io::ErrorKind::Other, "Error receiving event")),
            Ok(event) => {
                match event.path {
                    None => println!("Warning: event has no path"),
                    Some(ref path) => {
                        let actions = self.watches.get(path);
                        if actions.is_some() {
                            for action in actions.unwrap() {
                                match action.handle_change(&event) {
                                    Ok(_) => num_actions += 1,
                                    Err(_) => {}
                                }
                            }
                        } else {
                            println!("Error: no actions found for path: {:?}", path.display());
                        }
                    }
                }

                Ok(num_actions)
            }
        }
    }
}

#[cfg(test)]
mod test {
    extern crate rand;

    use super::*;

    use self::rand::{thread_rng, Rng};
    use std::env::temp_dir;
    use std::fs::File;
    use std::fs::remove_file;
    use std::io::Write;
    use std::path::Path;
    use std::path::PathBuf;
    use actions::Action;
    use actions::print::PrintAction;

    #[test]
    fn watch_a_single_file() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();
        let actions: Vec<Box<Action + 'static>> = Vec::new();
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath, event_path);
                }
            }
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_two_files() {
        let (path1, mut file1) = create_temp_file();
        let (path2, mut file2) = create_temp_file();

        let filepath1 = path1.clone();
        let filepath2 = path2.clone();
        let actions1: Vec<Box<Action + 'static>> = Vec::new();
        let actions2: Vec<Box<Action + 'static>> = Vec::new();

        let mut fw = FilesWatcher::new();
        fw.add_file(path1, actions1);
        fw.add_file(path2, actions2);

        write_to(&mut file1);
        write_to(&mut file2);

        {
            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath1, event_path);
                }
            }

            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath2, event_path);
                }
            }
        }

        remove_temp_file(&filepath1);
        remove_temp_file(&filepath2);
    }

    #[test]
    fn watch_file_and_execute_no_actions() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();
        let actions: Vec<Box<Action + 'static>> = Vec::new();
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(0, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_file_and_execute_one_print_action() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();

        let print = PrintAction::new();
        let actions: Vec<Box<Action + 'static>> = vec![Box::new(print)];
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(1, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_file_and_execute_five_print_actions() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();

        let print1 = PrintAction::new();
        let print2 = PrintAction::new();
        let print3 = PrintAction::new();
        let print4 = PrintAction::new();
        let print5 = PrintAction::new();

        let actions: Vec<Box<Action + 'static>> = vec![Box::new(print1),
                                                       Box::new(print2),
                                                       Box::new(print3),
                                                       Box::new(print4),
                                                       Box::new(print5)];
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(5, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    fn create_temp_file() -> (PathBuf, File) {
        let rand_part: String = thread_rng()
                                    .gen_ascii_chars()
                                    .take(8)
                                    .collect();

        let filename = "eagleeye-test-".to_string() + &rand_part;
        let path = temp_dir().join(filename);
        let file = File::create(&path).unwrap_or_else(|error| {
            panic!("Failed to create temporary file: {}", error)
        });
        let path_buf = PathBuf::from(path);

        (path_buf, file)
    }

    fn remove_temp_file(path: &Path) {
        remove_file(path)
            .unwrap_or_else(|error| panic!("Failed to create temporary file: {}", error));
    }

    fn write_to(file: &mut File) {
        file.write_all(b"This should trigger an inotify event.")
            .unwrap_or_else(|error| panic!("Failed to write to file: {}", error));

        file.flush()
            .unwrap();
    }

}
<commit_msg>Add TODO to FilesWatcher<commit_after>extern crate libc;
extern crate notify;

use notify::{RecommendedWatcher, Error, Watcher, Event};
use std::sync::mpsc::{channel, Receiver, RecvError};

use std::collections::HashMap;
use std::io;
use std::path::PathBuf;

use actions::Action;

pub struct FilesWatcher {
    watcher: Box<RecommendedWatcher>,
    rx: Receiver<Event>,
    watches: HashMap<PathBuf, Vec<Box<Action>>>,
}

impl FilesWatcher {
    pub fn new() -> FilesWatcher {
        let (tx, rx) = channel();
        let watcher: Result<RecommendedWatcher, Error> = Watcher::new(tx);

        FilesWatcher {
            watcher: Box::new(watcher.unwrap()),
            rx: rx,
            watches: HashMap::new(),
        }
    }

    // TODO: accept a Vec of paths
    pub fn add_file(&mut self, path: PathBuf, actions: Vec<Box<Action>>) {
        let result = self.watcher.watch(&path);

        if result.is_ok() {
            println!("Watching file: {:?}", path);
            self.watches.insert(path, actions);
        } else {
            println!("Error adding watch for file: {:?}", result.err());
        }
    }

    pub fn wait_for_events(&mut self) -> Result<Event, RecvError> {
        self.rx.recv()
    }

    pub fn wait_and_execute(&mut self) -> Result<i32, io::Error> {
        let mut num_actions = 0;
        let event_result = self.rx.recv();

        match event_result {
            Err(_) => Err(io::Error::new(io::ErrorKind::Other, "Error receiving event")),
            Ok(event) => {
                match event.path {
                    None => println!("Warning: event has no path"),
                    Some(ref path) => {
                        let actions = self.watches.get(path);
                        if actions.is_some() {
                            for action in actions.unwrap() {
                                match action.handle_change(&event) {
                                    Ok(_) => num_actions += 1,
                                    Err(_) => {}
                                }
                            }
                        } else {
                            println!("Error: no actions found for path: {:?}", path.display());
                        }
                    }
                }

                Ok(num_actions)
            }
        }
    }
}

#[cfg(test)]
mod test {
    extern crate rand;

    use super::*;

    use self::rand::{thread_rng, Rng};
    use std::env::temp_dir;
    use std::fs::File;
    use std::fs::remove_file;
    use std::io::Write;
    use std::path::Path;
    use std::path::PathBuf;
    use actions::Action;
    use actions::print::PrintAction;

    #[test]
    fn watch_a_single_file() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();
        let actions: Vec<Box<Action + 'static>> = Vec::new();
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath, event_path);
                }
            }
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_two_files() {
        let (path1, mut file1) = create_temp_file();
        let (path2, mut file2) = create_temp_file();

        let filepath1 = path1.clone();
        let filepath2 = path2.clone();
        let actions1: Vec<Box<Action + 'static>> = Vec::new();
        let actions2: Vec<Box<Action + 'static>> = Vec::new();

        let mut fw = FilesWatcher::new();
        fw.add_file(path1, actions1);
        fw.add_file(path2, actions2);

        write_to(&mut file1);
        write_to(&mut file2);

        {
            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath1, event_path);
                }
            }

            let event = fw.wait_for_events().unwrap();
            match event.path {
                None => assert!(false, "Error: event has no path"),
                Some(event_path) => {
                    assert_eq!(filepath2, event_path);
                }
            }
        }

        remove_temp_file(&filepath1);
        remove_temp_file(&filepath2);
    }

    #[test]
    fn watch_file_and_execute_no_actions() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();
        let actions: Vec<Box<Action + 'static>> = Vec::new();
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(0, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_file_and_execute_one_print_action() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();

        let print = PrintAction::new();
        let actions: Vec<Box<Action + 'static>> = vec![Box::new(print)];
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(1, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    #[test]
    fn watch_file_and_execute_five_print_actions() {
        let (path, mut file) = create_temp_file();
        let filepath = path.clone();

        let mut fw = FilesWatcher::new();

        let print1 = PrintAction::new();
        let print2 = PrintAction::new();
        let print3 = PrintAction::new();
        let print4 = PrintAction::new();
        let print5 = PrintAction::new();

        let actions: Vec<Box<Action + 'static>> = vec![Box::new(print1),
                                                       Box::new(print2),
                                                       Box::new(print3),
                                                       Box::new(print4),
                                                       Box::new(print5)];
        fw.add_file(path, actions);

        write_to(&mut file);

        {
            let actions_executed = fw.wait_and_execute().unwrap();
            assert_eq!(5, actions_executed);
        }

        remove_temp_file(&filepath);
    }

    fn create_temp_file() -> (PathBuf, File) {
        let rand_part: String = thread_rng()
                                    .gen_ascii_chars()
                                    .take(8)
                                    .collect();

        let filename = "eagleeye-test-".to_string() + &rand_part;
        let path = temp_dir().join(filename);
        let file = File::create(&path).unwrap_or_else(|error| {
            panic!("Failed to create temporary file: {}", error)
        });
        let path_buf = PathBuf::from(path);

        (path_buf, file)
    }

    fn remove_temp_file(path: &Path) {
        remove_file(path)
            .unwrap_or_else(|error| panic!("Failed to create temporary file: {}", error));
    }

    fn write_to(file: &mut File) {
        file.write_all(b"This should trigger an inotify event.")
            .unwrap_or_else(|error| panic!("Failed to write to file: {}", error));

        file.flush()
            .unwrap();
    }

}
<|endoftext|>


<commit_before>fn main() {
    let strings = vec![
        String::from("1001110011"),
        String::from("1110111011"),
        String::from("0010010010"),
        String::from("1010101010"),
        String::from("1111111111"),
        String::from("0100101101"),
        String::from("0100100"),
        String::from("101"),
        String::from("11"),
        String::from("00"),
        String::from("1"),
    ];
    for string in strings {
        match rep_string(&string) {
            Some(rep_string) => println!(
                "Longest rep-string for '{}' is '{}' ({} chars)",
                string,
                rep_string,
                rep_string.len(),
            ),
            None => println!("No rep-string found for '{}'", string),
        };
    }
}

fn rep_string(string: &str) -> Option<&str> {
    let index = string.len() / 2;

    for split_index in (1..=index).rev() {
        let mut is_rep_string = true;
        let (first, last) = string.split_at(split_index);

        let inter = last.chars().collect::<Vec<char>>();
        let mut iter = inter.chunks_exact(split_index);
        for chunk in iter.by_ref() {
            if first != chunk.iter().collect::<String>() {
                is_rep_string = false;
                break;
            }
        }
        let rmnd = iter.remainder().iter().collect::<String>();

        // Check that the remainder starts with the rep-string
        if !first.starts_with(rmnd.as_str()) {
            is_rep_string = false;
        }

        if is_rep_string {
            return Some(first);
        }
    }
    None
}

#[cfg(test)]
mod tests {
    use super::rep_string;
    use std::collections::HashMap;

    #[test]
    fn test_rep_string() {
        let mut results = HashMap::new();
        results.insert(String::from("1001110011"), Some("10011"));
        results.insert(String::from("1110111011"), Some("1110"));
        results.insert(String::from("0010010010"), Some("001"));
        results.insert(String::from("1010101010"), Some("1010"));
        results.insert(String::from("1111111111"), Some("11111"));
        results.insert(String::from("0100101101"), None);
        results.insert(String::from("0100100"), Some("010"));
        results.insert(String::from("101"), None);
        results.insert(String::from("11"), Some("1"));
        results.insert(String::from("00"), Some("0"));
        results.insert(String::from("1"), None);

        for (input, expected) in results {
            assert_eq!(expected, rep_string(&input));
        }
    }
}
<commit_msg>remove String allocations, style tweaks<commit_after>fn main() {
    for a_slice in vec![
        "1001110011",
        "1110111011",
        "0010010010",
        "1010101010",
        "1111111111",
        "0100101101",
        "0100100",
        "101",
        "11",
        "00",
        "1",
    ] {
        match rep_string(&a_slice) {
            Some(repeated) => println!(
                "Longest rep-string for '{}' is '{}' ({} chars)",
                a_slice,
                repeated,
                repeated.len(),
            ),
            None => println!("No rep-string found for '{}'", a_slice),
        };
    }
}

fn rep_string(string: &str) -> Option<&str> {
    let index = string.len() / 2;

    for split_index in (1..=index).rev() {
        let mut is_rep_string = true;
        let (first, last) = string.split_at(split_index);

        let inter = last.chars().collect::<Vec<char>>();
        let mut iter = inter.chunks_exact(split_index);
        for chunk in iter.by_ref() {
            if first != chunk.iter().collect::<String>() {
                is_rep_string = false;
                break;
            }
        }
        let rmnd = iter.remainder().iter().collect::<String>();

        // Check that the remainder starts with the rep-string
        if !first.starts_with(rmnd.as_str()) {
            is_rep_string = false;
        }

        if is_rep_string {
            return Some(first);
        }
    }
    None
}

#[cfg(test)]
mod tests {
    use super::rep_string;
    use std::collections::HashMap;

    #[test]
    fn test_rep_string() {
        let mut results = HashMap::new();
        results.insert(String::from("1001110011"), Some("10011"));
        results.insert(String::from("1110111011"), Some("1110"));
        results.insert(String::from("0010010010"), Some("001"));
        results.insert(String::from("1010101010"), Some("1010"));
        results.insert(String::from("1111111111"), Some("11111"));
        results.insert(String::from("0100101101"), None);
        results.insert(String::from("0100100"), Some("010"));
        results.insert(String::from("101"), None);
        results.insert(String::from("11"), Some("1"));
        results.insert(String::from("00"), Some("0"));
        results.insert(String::from("1"), None);

        for (input, expected) in results {
            assert_eq!(expected, rep_string(&input));
        }
    }
}
<|endoftext|>


<commit_before>//! Tests for various types of file (video, image, compressed, etc).
//!
//! Currently this is dependent on the file’s name and extension, because
//! those are the only metadata that we have access to without reading the
//! file’s contents.

use ansi_term::Style;

use fs::File;
use output::file_name::FileColours;

#[derive(Debug, Default, PartialEq)]
pub struct FileExtensions;

impl FileExtensions {

    /// An “immediate” file is something that can be run or activated somehow
    /// in order to kick off the build of a project. It’s usually only present
    /// in directories full of source code.
    fn is_immediate(&self, file: &File) -> bool {
        file.name.starts_with("README") || file.name_is_one_of( &[
            "Makefile", "Cargo.toml", "SConstruct", "CMakeLists.txt",
            "build.gradle", "Rakefile", "Gruntfile.js",
            "Gruntfile.coffee",
        ])
    }

    fn is_image(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "png", "jpeg", "jpg", "gif", "bmp", "tiff", "tif",
            "ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw",
            "svg", "stl", "eps", "dvi", "ps", "cbr",
            "cbz", "xpm", "ico", "cr2", "orf", "nef",
        ])
    }

    fn is_video(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "avi", "flv", "m2v", "mkv", "mov", "mp4", "mpeg",
            "mpg", "ogm", "ogv", "vob", "wmv", "webm", "m2ts",
            "ts",
        ])
    }

    fn is_music(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "aac", "m4a", "mp3", "ogg", "wma", "mka", "opus",
        ])
    }

    // Lossless music, rather than any other kind of data...
    fn is_lossless(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "alac", "ape", "flac", "wav",
        ])
    }

    fn is_crypto(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "asc", "enc", "gpg", "pgp", "sig", "signature", "pfx", "p12",
        ])
    }

    fn is_document(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "djvu", "doc", "docx", "dvi", "eml", "eps", "fotd",
            "odp", "odt", "pdf", "ppt", "pptx", "rtf",
            "xls", "xlsx",
        ])
    }

    fn is_compressed(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "zip", "tar", "Z", "z", "gz", "bz2", "a", "ar", "7z",
            "iso", "dmg", "tc", "rar", "par", "tgz", "xz", "txz",
            "lzma", "deb", "rpm"
        ])
    }

    fn is_temp(&self, file: &File) -> bool {
        file.name.ends_with('~')
            || (file.name.starts_with('#') && file.name.ends_with('#'))
            || file.extension_is_one_of( &[ "tmp", "swp", "swo", "swn", "bak", "bk" ])
    }

    fn is_compiled(&self, file: &File) -> bool {
        if file.extension_is_one_of( &[ "class", "elc", "hi", "o", "pyc" ]) {
            true
        }
        else if let Some(dir) = file.parent_dir {
            file.get_source_files().iter().any(|path| dir.contains(path))
        }
        else {
            false
        }
    }
}

impl FileColours for FileExtensions {
    fn colour_file(&self, file: &File) -> Option<Style> {
        use ansi_term::Colour::*;

        Some(match file {
            f if self.is_immediate(f)   => Yellow.bold().underline(),
            f if self.is_image(f)       => Fixed(133).normal(),
            f if self.is_video(f)       => Fixed(135).normal(),
            f if self.is_music(f)       => Fixed(92).normal(),
            f if self.is_lossless(f)    => Fixed(93).normal(),
            f if self.is_crypto(f)      => Fixed(109).normal(),
            f if self.is_document(f)    => Fixed(105).normal(),
            f if self.is_compressed(f)  => Red.normal(),
            f if self.is_temp(f)        => Fixed(244).normal(),
            f if self.is_compiled(f)    => Fixed(137).normal(),
            _                           => return None,
        })
    }
}
<commit_msg>Case insensitive README.* files are immediate<commit_after>//! Tests for various types of file (video, image, compressed, etc).
//!
//! Currently this is dependent on the file’s name and extension, because
//! those are the only metadata that we have access to without reading the
//! file’s contents.

use ansi_term::Style;

use fs::File;
use output::file_name::FileColours;

#[derive(Debug, Default, PartialEq)]
pub struct FileExtensions;

impl FileExtensions {

    /// An “immediate” file is something that can be run or activated somehow
    /// in order to kick off the build of a project. It’s usually only present
    /// in directories full of source code.
    fn is_immediate(&self, file: &File) -> bool {
        file.name.to_lowercase().starts_with("readme") || file.name_is_one_of( &[
            "Makefile", "Cargo.toml", "SConstruct", "CMakeLists.txt",
            "build.gradle", "Rakefile", "Gruntfile.js",
            "Gruntfile.coffee",
        ])
    }

    fn is_image(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "png", "jpeg", "jpg", "gif", "bmp", "tiff", "tif",
            "ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw",
            "svg", "stl", "eps", "dvi", "ps", "cbr",
            "cbz", "xpm", "ico", "cr2", "orf", "nef",
        ])
    }

    fn is_video(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "avi", "flv", "m2v", "mkv", "mov", "mp4", "mpeg",
            "mpg", "ogm", "ogv", "vob", "wmv", "webm", "m2ts",
            "ts",
        ])
    }

    fn is_music(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "aac", "m4a", "mp3", "ogg", "wma", "mka", "opus",
        ])
    }

    // Lossless music, rather than any other kind of data...
    fn is_lossless(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "alac", "ape", "flac", "wav",
        ])
    }

    fn is_crypto(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "asc", "enc", "gpg", "pgp", "sig", "signature", "pfx", "p12",
        ])
    }

    fn is_document(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "djvu", "doc", "docx", "dvi", "eml", "eps", "fotd",
            "odp", "odt", "pdf", "ppt", "pptx", "rtf",
            "xls", "xlsx",
        ])
    }

    fn is_compressed(&self, file: &File) -> bool {
        file.extension_is_one_of( &[
            "zip", "tar", "Z", "z", "gz", "bz2", "a", "ar", "7z",
            "iso", "dmg", "tc", "rar", "par", "tgz", "xz", "txz",
            "lzma", "deb", "rpm"
        ])
    }

    fn is_temp(&self, file: &File) -> bool {
        file.name.ends_with('~')
            || (file.name.starts_with('#') && file.name.ends_with('#'))
            || file.extension_is_one_of( &[ "tmp", "swp", "swo", "swn", "bak", "bk" ])
    }

    fn is_compiled(&self, file: &File) -> bool {
        if file.extension_is_one_of( &[ "class", "elc", "hi", "o", "pyc" ]) {
            true
        }
        else if let Some(dir) = file.parent_dir {
            file.get_source_files().iter().any(|path| dir.contains(path))
        }
        else {
            false
        }
    }
}

impl FileColours for FileExtensions {
    fn colour_file(&self, file: &File) -> Option<Style> {
        use ansi_term::Colour::*;

        Some(match file {
            f if self.is_immediate(f)   => Yellow.bold().underline(),
            f if self.is_image(f)       => Fixed(133).normal(),
            f if self.is_video(f)       => Fixed(135).normal(),
            f if self.is_music(f)       => Fixed(92).normal(),
            f if self.is_lossless(f)    => Fixed(93).normal(),
            f if self.is_crypto(f)      => Fixed(109).normal(),
            f if self.is_document(f)    => Fixed(105).normal(),
            f if self.is_compressed(f)  => Red.normal(),
            f if self.is_temp(f)        => Fixed(244).normal(),
            f if self.is_compiled(f)    => Fixed(137).normal(),
            _                           => return None,
        })
    }
}
<|endoftext|>


<commit_before>//! Functions for computing [integral images](https://en.wikipedia.org/wiki/Summed_area_table)
//! and running sums of rows and columns.

extern crate image;

use image::{
    Luma,
    GenericImage,
    ImageBuffer
};

use definitions::{
    VecBuffer
};

/// Computes the integral image of an 8bpp grayscale image.
/// I is the integral image of an image F if I(x, y) is the
/// sum of F(x', y') for x' <= x, y' <= y. i.e. each pixel
/// in the integral image contains the sum of the pixel intensities
/// of all input pixels that are above it and to its left.
/// The integral image has the helpful property that it lets us
/// compute the sum of pixel intensities from any rectangular region
/// in the input image in constant time.
/// Specifically, given a rectangle in F with clockwise corners
/// A, B, C, D, with A at the upper left, the total pixel intensity
/// of this rectangle is I(C) - I(B) - I(D) + I(A).
// TODO: Support more formats.
// TODO: This is extremely slow. Fix that!
pub fn integral_image<I>(image: &I) -> VecBuffer<Luma<u32>>
    where I: GenericImage<Pixel=Luma<u8>> {
    padded_integral_image(image, 0, 0)
}

/// Computes the integral image of the result of padding image
/// with its boundary pixels for x_padding columns on either
/// side and y_padding rows at its top and bottom.
/// Returned image has width image.width() + 2 * x_padding
/// and height image.height() + 2 * y_padding.
pub fn padded_integral_image<I>(image: &I, x_padding: u32, y_padding: u32)
        -> VecBuffer<Luma<u32>>
    where I: GenericImage<Pixel=Luma<u8>> {

    let (in_width, in_height) = image.dimensions();
    let out_width = in_width + 2 * x_padding;
    let out_height = in_height + 2 * y_padding;

    let mut out: ImageBuffer<Luma<u32>, Vec<u32>>
        = ImageBuffer::new(out_width, out_height);

    for y in 0..out_height {
        for x in 0..out_width {

            let y_in: u32;
            if y < y_padding {
                y_in = 0;
            }
            else if y >= in_height + y_padding {
                y_in = in_height - 1;
            }
            else {
                y_in = y - y_padding;
            }
            let x_in: u32;
            if x < x_padding {
                x_in = 0;
            }
            else if x >= in_width + x_padding {
                x_in = in_width - 1;
            }
            else {
                x_in = x - x_padding;
            }

            unsafe {
                let p = image.unsafe_get_pixel(x_in, y_in);
                out.unsafe_put_pixel(x, y, Luma([p[0] as u32]));
            }
        }
    }

    for x in 1..out_width {
        (*out.get_pixel_mut(x, 0))[0] += unsafe { out.unsafe_get_pixel(x - 1, 0)[0] };
    }

    for y in 1..out_height {
        (*out.get_pixel_mut(0, y))[0] += unsafe { out.unsafe_get_pixel(0, y - 1)[0] };

        for x in 1..out_width {
            (*out.get_pixel_mut(x, y))[0] += unsafe { out.unsafe_get_pixel(x, y - 1)[0] };
            (*out.get_pixel_mut(x, y))[0] += unsafe { out.unsafe_get_pixel(x - 1, y)[0] };
            (*out.get_pixel_mut(x, y))[0] -= unsafe { out.unsafe_get_pixel(x - 1, y - 1)[0] };
        }
    }

    out
}

/// Computes the running sum of one row of image, padded
/// at the beginning and end. The padding is by continuity.
/// Takes a reference to buffer so that this can be reused
/// for all rows in an image.
// TODO: faster, more formats
pub fn row_running_sum<I>(image: &I, row: u32, buffer: &mut [u32], padding: u32)
    where I: GenericImage<Pixel=Luma<u8>> {

    let width = image.width();
    assert!(buffer.len() >= (width + 2 * padding) as usize,
        format!("Buffer length {} is less than {} + 2 * {}", buffer.len(), width, padding));
    assert!(row < image.height(),
        format!("row out of bound: {} >= {}", row, image.height()));

    for x in 0..padding {
        buffer[x as usize] = unsafe { image.unsafe_get_pixel(0, row)[0] as u32 };
    }

    for x in 0..width {
        let idx = (x + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(x, row)[0] as u32 };
    }

    for x in 0..padding {
        let idx = (x + width + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(width - 1, row)[0] as u32 };
    }

    for x in 1..width + 2 * padding {
        buffer[x as usize] += buffer[(x - 1) as usize] as u32;
    }
}

/// Computes the running sum of one column of image, padded
/// at the top and bottom. The padding is by continuity.
/// Takes a reference to buffer so that this can be reused
/// for all columns in an image.
// TODO: faster, more formats
pub fn column_running_sum<I>(image: &I, column: u32, buffer: &mut [u32], padding: u32)
    where I: GenericImage<Pixel=Luma<u8>> {

    let height = image.height();
    assert!(buffer.len() >= (height + 2 * padding) as usize,
        format!("Buffer length {} is less than {} + 2 * {}", buffer.len(), height, padding));
    assert!(column < image.width(),
        format!("column out of bound: {} >= {}", column, image.width()));

    for y in 0..padding {
        buffer[y as usize] = unsafe { image.unsafe_get_pixel(column, 0)[0] as u32 };
    }

    for y in 0..height {
        let idx = (y + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(column, y)[0] as u32 };
    }

    for y in 0..padding {
        let idx = (y + height + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(column, height - 1)[0] as u32 };
    }

    for y in 1..height + 2 * padding {
        buffer[y as usize] += buffer[(y - 1) as usize] as u32;
    }
}

#[cfg(test)]
mod test {

    use super::{
        column_running_sum,
        integral_image,
        padded_integral_image,
        row_running_sum
    };
    use utils::{
        gray_bench_image
    };
    use image::{
        GrayImage,
        ImageBuffer,
        Luma
    };
    use test;

    #[test]
    fn test_integral_image() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(3, 2, vec![
            1,  3,  6,
            5, 12, 21]).unwrap();

        assert_pixels_eq!(integral_image(&image), expected);
    }

    #[bench]
    fn bench_integral_image(b: &mut test::Bencher) {
        let image = gray_bench_image(500, 500);
        b.iter(|| {
            let integral = integral_image(&image);
            test::black_box(integral);
            });
    }

    #[test]
    fn test_padded_integral_image() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(5, 4, vec![
              1,  2,   4,   7,  10,
              2,  4,   8,  14,  20,
              6, 12,  21,  33,  45,
             10, 20,  34,  52,  70]).unwrap();

        assert_pixels_eq!(padded_integral_image(&image, 1, 1), expected);
    }

    #[test]
    fn test_row_running_sum() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected = [1, 2, 4, 7, 10];

        let mut buffer = [0; 5];
        row_running_sum(&image, 0, &mut buffer, 1);

        assert_eq!(buffer, expected);
    }

    #[bench]
    fn bench_row_running_sum(b: &mut test::Bencher) {
        let image = gray_bench_image(1000, 1);
        let mut buffer = [0; 1010];
        b.iter(|| {
            row_running_sum(&image, 0, &mut buffer, 5);
            });
    }

    #[test]
    fn test_column_running_sum() {
        let image: GrayImage = ImageBuffer::from_raw(2, 3, vec![
            1, 4,
            2, 5,
            3, 6]).unwrap();

        let expected = [1, 2, 4, 7, 10];

        let mut buffer = [0; 5];
        column_running_sum(&image, 0, &mut buffer, 1);

        assert_eq!(buffer, expected);
    }

    #[bench]
    fn bench_column_running_sum(b: &mut test::Bencher) {
        let image = gray_bench_image(100, 1000);
        let mut buffer = [0; 1010];
        b.iter(|| {
            column_running_sum(&image, 0, &mut buffer, 5);
            });
    }
}
<commit_msg>Move work out of inner loop<commit_after>//! Functions for computing [integral images](https://en.wikipedia.org/wiki/Summed_area_table)
//! and running sums of rows and columns.

extern crate image;

use image::{
    Luma,
    GenericImage,
    ImageBuffer
};

use definitions::{
    VecBuffer
};

/// Computes the integral image of an 8bpp grayscale image.
/// I is the integral image of an image F if I(x, y) is the
/// sum of F(x', y') for x' <= x, y' <= y. i.e. each pixel
/// in the integral image contains the sum of the pixel intensities
/// of all input pixels that are above it and to its left.
/// The integral image has the helpful property that it lets us
/// compute the sum of pixel intensities from any rectangular region
/// in the input image in constant time.
/// Specifically, given a rectangle in F with clockwise corners
/// A, B, C, D, with A at the upper left, the total pixel intensity
/// of this rectangle is I(C) - I(B) - I(D) + I(A).
// TODO: Support more formats.
// TODO: This is extremely slow. Fix that!
pub fn integral_image<I>(image: &I) -> VecBuffer<Luma<u32>>
    where I: GenericImage<Pixel=Luma<u8>> {
    padded_integral_image(image, 0, 0)
}

/// Computes the integral image of the result of padding image
/// with its boundary pixels for x_padding columns on either
/// side and y_padding rows at its top and bottom.
/// Returned image has width image.width() + 2 * x_padding
/// and height image.height() + 2 * y_padding.
pub fn padded_integral_image<I>(image: &I, x_padding: u32, y_padding: u32)
        -> VecBuffer<Luma<u32>>
    where I: GenericImage<Pixel=Luma<u8>> {

    let (in_width, in_height) = image.dimensions();
    let out_width = in_width + 2 * x_padding;
    let out_height = in_height + 2 * y_padding;

    let mut out: ImageBuffer<Luma<u32>, Vec<u32>>
        = ImageBuffer::new(out_width, out_height);

    for y in 0..out_height {
        let y_in: u32;
        if y < y_padding {
            y_in = 0;
        }
        else if y >= in_height + y_padding {
            y_in = in_height - 1;
        }
        else {
            y_in = y - y_padding;
        }

        for x in 0..out_width {
            let x_in: u32;
            if x < x_padding {
                x_in = 0;
            }
            else if x >= in_width + x_padding {
                x_in = in_width - 1;
            }
            else {
                x_in = x - x_padding;
            }

            unsafe {
                let p = image.unsafe_get_pixel(x_in, y_in);
                out.unsafe_put_pixel(x, y, Luma([p[0] as u32]));
            }
        }
    }

    for x in 1..out_width {
        (*out.get_pixel_mut(x, 0))[0] += unsafe { out.unsafe_get_pixel(x - 1, 0)[0] };
    }

    for y in 1..out_height {
        (*out.get_pixel_mut(0, y))[0] += unsafe { out.unsafe_get_pixel(0, y - 1)[0] };

        for x in 1..out_width {
            (*out.get_pixel_mut(x, y))[0] += unsafe { out.unsafe_get_pixel(x, y - 1)[0] };
            (*out.get_pixel_mut(x, y))[0] += unsafe { out.unsafe_get_pixel(x - 1, y)[0] };
            (*out.get_pixel_mut(x, y))[0] -= unsafe { out.unsafe_get_pixel(x - 1, y - 1)[0] };
        }
    }

    out
}

/// Computes the running sum of one row of image, padded
/// at the beginning and end. The padding is by continuity.
/// Takes a reference to buffer so that this can be reused
/// for all rows in an image.
// TODO: faster, more formats
pub fn row_running_sum<I>(image: &I, row: u32, buffer: &mut [u32], padding: u32)
    where I: GenericImage<Pixel=Luma<u8>> {

    let width = image.width();
    assert!(buffer.len() >= (width + 2 * padding) as usize,
        format!("Buffer length {} is less than {} + 2 * {}", buffer.len(), width, padding));
    assert!(row < image.height(),
        format!("row out of bound: {} >= {}", row, image.height()));

    for x in 0..padding {
        buffer[x as usize] = unsafe { image.unsafe_get_pixel(0, row)[0] as u32 };
    }

    for x in 0..width {
        let idx = (x + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(x, row)[0] as u32 };
    }

    for x in 0..padding {
        let idx = (x + width + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(width - 1, row)[0] as u32 };
    }

    for x in 1..width + 2 * padding {
        buffer[x as usize] += buffer[(x - 1) as usize] as u32;
    }
}

/// Computes the running sum of one column of image, padded
/// at the top and bottom. The padding is by continuity.
/// Takes a reference to buffer so that this can be reused
/// for all columns in an image.
// TODO: faster, more formats
pub fn column_running_sum<I>(image: &I, column: u32, buffer: &mut [u32], padding: u32)
    where I: GenericImage<Pixel=Luma<u8>> {

    let height = image.height();
    assert!(buffer.len() >= (height + 2 * padding) as usize,
        format!("Buffer length {} is less than {} + 2 * {}", buffer.len(), height, padding));
    assert!(column < image.width(),
        format!("column out of bound: {} >= {}", column, image.width()));

    for y in 0..padding {
        buffer[y as usize] = unsafe { image.unsafe_get_pixel(column, 0)[0] as u32 };
    }

    for y in 0..height {
        let idx = (y + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(column, y)[0] as u32 };
    }

    for y in 0..padding {
        let idx = (y + height + padding) as usize;
        buffer[idx] = unsafe { image.unsafe_get_pixel(column, height - 1)[0] as u32 };
    }

    for y in 1..height + 2 * padding {
        buffer[y as usize] += buffer[(y - 1) as usize] as u32;
    }
}

#[cfg(test)]
mod test {

    use super::{
        column_running_sum,
        integral_image,
        padded_integral_image,
        row_running_sum
    };
    use utils::{
        gray_bench_image
    };
    use image::{
        GrayImage,
        ImageBuffer,
        Luma
    };
    use test;

    #[test]
    fn test_integral_image() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(3, 2, vec![
            1,  3,  6,
            5, 12, 21]).unwrap();

        assert_pixels_eq!(integral_image(&image), expected);
    }

    #[bench]
    fn bench_integral_image(b: &mut test::Bencher) {
        let image = gray_bench_image(500, 500);
        b.iter(|| {
            let integral = integral_image(&image);
            test::black_box(integral);
            });
    }

    #[test]
    fn test_padded_integral_image() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected: ImageBuffer<Luma<u32>, Vec<u32>>
            = ImageBuffer::from_raw(5, 4, vec![
              1,  2,   4,   7,  10,
              2,  4,   8,  14,  20,
              6, 12,  21,  33,  45,
             10, 20,  34,  52,  70]).unwrap();

        assert_pixels_eq!(padded_integral_image(&image, 1, 1), expected);
    }

    #[test]
    fn test_row_running_sum() {
        let image: GrayImage = ImageBuffer::from_raw(3, 2, vec![
            1, 2, 3,
            4, 5, 6]).unwrap();

        let expected = [1, 2, 4, 7, 10];

        let mut buffer = [0; 5];
        row_running_sum(&image, 0, &mut buffer, 1);

        assert_eq!(buffer, expected);
    }

    #[bench]
    fn bench_row_running_sum(b: &mut test::Bencher) {
        let image = gray_bench_image(1000, 1);
        let mut buffer = [0; 1010];
        b.iter(|| {
            row_running_sum(&image, 0, &mut buffer, 5);
            });
    }

    #[test]
    fn test_column_running_sum() {
        let image: GrayImage = ImageBuffer::from_raw(2, 3, vec![
            1, 4,
            2, 5,
            3, 6]).unwrap();

        let expected = [1, 2, 4, 7, 10];

        let mut buffer = [0; 5];
        column_running_sum(&image, 0, &mut buffer, 1);

        assert_eq!(buffer, expected);
    }

    #[bench]
    fn bench_column_running_sum(b: &mut test::Bencher) {
        let image = gray_bench_image(100, 1000);
        let mut buffer = [0; 1010];
        b.iter(|| {
            column_running_sum(&image, 0, &mut buffer, 5);
            });
    }
}
<|endoftext|>


<commit_before>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Alex Lyon <arcterus@mail.com>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) delim

use clap::{crate_version, App, AppSettings, Arg};
use std::fs::File;
use std::io::{stdin, stdout, BufRead, BufReader, Read, Write};
use std::path::Path;
use uucore::error::{FromIo, UResult};

static ABOUT: &str = "Write lines consisting of the sequentially corresponding lines from each
FILE, separated by TABs, to standard output.";

mod options {
    pub const DELIMITER: &str = "delimiters";
    pub const SERIAL: &str = "serial";
    pub const FILE: &str = "file";
}

// Wraps BufReader and stdin
fn read_line<R: Read>(
    reader: Option<&mut BufReader<R>>,
    buf: &mut String,
) -> std::io::Result<usize> {
    match reader {
        Some(reader) => reader.read_line(buf),
        None => stdin().read_line(buf),
    }
}

#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
    let matches = uu_app().get_matches_from(args);

    let serial = matches.is_present(options::SERIAL);
    let delimiters = matches.value_of(options::DELIMITER).unwrap();
    let files = matches
        .values_of(options::FILE)
        .unwrap()
        .map(|s| s.to_owned())
        .collect();
    paste(files, serial, delimiters)
}

pub fn uu_app<'a>() -> App<'a> {
    App::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .setting(AppSettings::InferLongArgs)
        .arg(
            Arg::new(options::SERIAL)
                .long(options::SERIAL)
                .short('s')
                .help("paste one file at a time instead of in parallel"),
        )
        .arg(
            Arg::new(options::DELIMITER)
                .long(options::DELIMITER)
                .short('d')
                .help("reuse characters from LIST instead of TABs")
                .value_name("LIST")
                .default_value("\t")
                .hide_default_value(true),
        )
        .arg(
            Arg::new(options::FILE)
                .value_name("FILE")
                .multiple_occurrences(true)
                .default_value("-"),
        )
}

fn paste(filenames: Vec<String>, serial: bool, delimiters: &str) -> UResult<()> {
    let mut files = Vec::with_capacity(filenames.len());
    for name in filenames {
        let file = if name == "-" {
            None
        } else {
            let path = Path::new(&name);
            let r = File::open(path).map_err_context(String::new)?;
            Some(BufReader::new(r))
        };
        files.push(file);
    }

    let delimiters: Vec<char> = unescape(delimiters).chars().collect();
    let mut delim_count = 0;
    let stdout = stdout();
    let mut stdout = stdout.lock();

    let mut line = String::new();
    let mut output = String::new();
    if serial {
        for file in &mut files {
            output.clear();
            loop {
                line.clear();
                match read_line(file.as_mut(), &mut line) {
                    Ok(0) => break,
                    Ok(_) => {
                        output.push_str(line.trim_end());
                        output.push(delimiters[delim_count % delimiters.len()]);
                    }
                    Err(e) => return Err(e.map_err_context(String::new)),
                }
                delim_count += 1;
            }
            output.pop();
            writeln!(stdout, "{}", output)?;
        }
    } else {
        let mut eof = vec![false; files.len()];
        loop {
            output.clear();
            let mut eof_count = 0;
            for (i, file) in files.iter_mut().enumerate() {
                if eof[i] {
                    eof_count += 1;
                } else {
                    line.clear();
                    match read_line(file.as_mut(), &mut line) {
                        Ok(0) => {
                            eof[i] = true;
                            eof_count += 1;
                        }
                        Ok(_) => output.push_str(line.trim_end()),
                        Err(e) => return Err(e.map_err_context(String::new)),
                    }
                }
                output.push(delimiters[delim_count % delimiters.len()]);
                delim_count += 1;
            }
            if files.len() == eof_count {
                break;
            }
            // Remove final delimiter
            output.pop();
            writeln!(stdout, "{}", output)?;
            delim_count = 0;
        }
    }
    Ok(())
}

// Unescape all special characters
// TODO: this will need work to conform to GNU implementation
fn unescape(s: &str) -> String {
    s.replace("\\n", "\n")
        .replace("\\t", "\t")
        .replace("\\\\", "\\")
        .replace('\\', "")
}
<commit_msg>paste: Use a single buffer<commit_after>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Alex Lyon <arcterus@mail.com>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) delim

use clap::{crate_version, App, AppSettings, Arg};
use std::fs::File;
use std::io::{stdin, stdout, BufRead, BufReader, Read, Write};
use std::path::Path;
use uucore::error::{FromIo, UResult};

static ABOUT: &str = "Write lines consisting of the sequentially corresponding lines from each
FILE, separated by TABs, to standard output.";

mod options {
    pub const DELIMITER: &str = "delimiters";
    pub const SERIAL: &str = "serial";
    pub const FILE: &str = "file";
}

// Wraps BufReader and stdin
fn read_line<R: Read>(
    reader: Option<&mut BufReader<R>>,
    buf: &mut String,
) -> std::io::Result<usize> {
    match reader {
        Some(reader) => reader.read_line(buf),
        None => stdin().read_line(buf),
    }
}

#[uucore::main]
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
    let matches = uu_app().get_matches_from(args);

    let serial = matches.is_present(options::SERIAL);
    let delimiters = matches.value_of(options::DELIMITER).unwrap();
    let files = matches
        .values_of(options::FILE)
        .unwrap()
        .map(|s| s.to_owned())
        .collect();
    paste(files, serial, delimiters)
}

pub fn uu_app<'a>() -> App<'a> {
    App::new(uucore::util_name())
        .version(crate_version!())
        .about(ABOUT)
        .setting(AppSettings::InferLongArgs)
        .arg(
            Arg::new(options::SERIAL)
                .long(options::SERIAL)
                .short('s')
                .help("paste one file at a time instead of in parallel"),
        )
        .arg(
            Arg::new(options::DELIMITER)
                .long(options::DELIMITER)
                .short('d')
                .help("reuse characters from LIST instead of TABs")
                .value_name("LIST")
                .default_value("\t")
                .hide_default_value(true),
        )
        .arg(
            Arg::new(options::FILE)
                .value_name("FILE")
                .multiple_occurrences(true)
                .default_value("-"),
        )
}

fn paste(filenames: Vec<String>, serial: bool, delimiters: &str) -> UResult<()> {
    let mut files = Vec::with_capacity(filenames.len());
    for name in filenames {
        let file = if name == "-" {
            None
        } else {
            let path = Path::new(&name);
            let r = File::open(path).map_err_context(String::new)?;
            Some(BufReader::new(r))
        };
        files.push(file);
    }

    let delimiters: Vec<char> = unescape(delimiters).chars().collect();
    let mut delim_count = 0;
    let stdout = stdout();
    let mut stdout = stdout.lock();

    let mut output = String::new();
    if serial {
        for file in &mut files {
            output.clear();
            loop {
                match read_line(file.as_mut(), &mut output) {
                    Ok(0) => break,
                    Ok(_) => {
                        if output.ends_with('\n') {
                            output.pop();
                        }
                        output.push(delimiters[delim_count % delimiters.len()]);
                    }
                    Err(e) => return Err(e.map_err_context(String::new)),
                }
                delim_count += 1;
            }
            output.pop();
            writeln!(stdout, "{}", output)?;
        }
    } else {
        let mut eof = vec![false; files.len()];
        loop {
            output.clear();
            let mut eof_count = 0;
            for (i, file) in files.iter_mut().enumerate() {
                if eof[i] {
                    eof_count += 1;
                } else {
                    match read_line(file.as_mut(), &mut output) {
                        Ok(0) => {
                            eof[i] = true;
                            eof_count += 1;
                        }
                        Ok(_) => {
                            if output.ends_with('\n') {
                                output.pop();
                            }
                        }
                        Err(e) => return Err(e.map_err_context(String::new)),
                    }
                }
                output.push(delimiters[delim_count % delimiters.len()]);
                delim_count += 1;
            }
            if files.len() == eof_count {
                break;
            }
            // Remove final delimiter
            output.pop();
            writeln!(stdout, "{}", output)?;
            delim_count = 0;
        }
    }
    Ok(())
}

// Unescape all special characters
// TODO: this will need work to conform to GNU implementation
fn unescape(s: &str) -> String {
    s.replace("\\n", "\n")
        .replace("\\t", "\t")
        .replace("\\\\", "\\")
        .replace('\\', "")
}
<|endoftext|>


<commit_before>use std::thread;

use anyhow::Result;
use laminar::{Packet, Socket, SocketEvent};
use legion::*;
use log::{info, LevelFilter};
use macroquad::prelude::*;
use simplelog::{Config, TermLogger, TerminalMode};

use zombenum_shared::components::GameEntityId;
use zombenum_shared::messages::client::ClientMessage;
use zombenum_shared::*;

mod input;
mod network;
mod systems;

use input::get_input_events;
use network::send_input_events;

const SERVER: &str = "127.0.0.1:14191";

fn window_conf() -> Conf {
    Conf {
        window_title: "Zombenum".to_string(),
        ..Default::default()
    }
}

#[macroquad::main(window_conf)]
async fn main() {
    run().await.expect("Error in run()");
}

async fn run() -> Result<()> {
    TermLogger::init(LevelFilter::Info, Config::default(), TerminalMode::Mixed)?;

    info!("Starting client");

    let mut socket = Socket::bind_any()?;
    info!("Bound on {}", socket.local_addr()?.to_string());

    let (sender, receiver) = (socket.get_packet_sender(), socket.get_event_receiver());
    let _thread = thread::spawn(move || socket.start_polling());

    info!("Server is {}", SERVER);
    let server = SERVER.parse()?;

    let mut world = World::default();
    let registry = get_registry();
    let mut resources = Resources::default();
    let mut schedule = Schedule::builder()
        .add_system(systems::draw_system())
        .build();

    info!("Send JoinGame");
    let deserializer = registry.as_deserialize_into_world(&mut world);
    let join_game_msg = ClientMessage::JoinGame(GameEntityId::new());
    sender.send(Packet::reliable_unordered(
        server,
        bincode::serialize(&join_game_msg)?,
    ))?;

    loop {
        if let Ok(event) = receiver.recv() {
            match event {
                SocketEvent::Packet(packet) => {
                    let payload = packet.payload();

                    deserializer.deserialize(&mut bincode::Deserializer::with_reader(
                        payload,
                        DefaultOptions::new(),
                    ))?;
                    break;
                }
                _ => continue,
            }
        }
    }
    info!("Initial state has been transferred");
    info!("{:?}", world.len());

    info!("Start main loop");
    loop {
        // Get a list of all input events issued by the user
        let input_events = get_input_events();

        // Send those input events to the server
        send_input_events(&input_events, &sender, server)?;

        if let Ok(event) = receiver.try_recv() {
            match event {
                SocketEvent::Packet(packet) => {
                    // dbg!(packet.addr(), server);
                    if packet.addr() == server {
                        // info!("Server sent: {}", String::from_utf8_lossy(packet.payload()));
                    } else {
                        info!("Unknown sender.");
                    }
                }
                SocketEvent::Timeout(_) => {}
                _ => (),
            }
        }

        clear_background(WHITE);
        schedule.execute(&mut world, &mut resources);
        next_frame().await
    }
}
<commit_msg>Remove initial state transfer<commit_after>use std::thread;

use anyhow::Result;
use laminar::{Packet, Socket, SocketEvent};
use legion::*;
use log::{info, LevelFilter};
use macroquad::prelude::*;
use simplelog::{Config, TermLogger, TerminalMode};

use zombenum_shared::components::GameEntityId;
use zombenum_shared::messages::client::ClientMessage;
use zombenum_shared::*;

mod input;
mod network;
mod systems;

use input::get_input_events;
use network::send_input_events;

const SERVER: &str = "127.0.0.1:14191";

fn window_conf() -> Conf {
    Conf {
        window_title: "Zombenum".to_string(),
        ..Default::default()
    }
}

#[macroquad::main(window_conf)]
async fn main() {
    run().await.expect("Error in run()");
}

async fn run() -> Result<()> {
    TermLogger::init(LevelFilter::Info, Config::default(), TerminalMode::Mixed)?;

    info!("Starting client");

    let mut socket = Socket::bind_any()?;
    info!("Bound on {}", socket.local_addr()?.to_string());

    let (sender, receiver) = (socket.get_packet_sender(), socket.get_event_receiver());
    let _thread = thread::spawn(move || socket.start_polling());

    info!("Server is {}", SERVER);
    let server = SERVER.parse()?;

    let mut world = World::default();
    let mut resources = Resources::default();
    let mut schedule = Schedule::builder()
        .add_system(systems::draw_system())
        .build();

    info!("Send JoinGame");
    let join_game_msg = ClientMessage::JoinGame(GameEntityId::new());
    sender.send(Packet::reliable_unordered(
        server,
        bincode::serialize(&join_game_msg)?,
    ))?;

    info!("Start main loop");
    loop {
        // Get a list of all input events issued by the user
        let input_events = get_input_events();

        // Send those input events to the server
        send_input_events(&input_events, &sender, server)?;

        if let Ok(event) = receiver.try_recv() {
            match event {
                SocketEvent::Packet(packet) => {
                    // dbg!(packet.addr(), server);
                    if packet.addr() == server {
                        // info!("Server sent: {}", String::from_utf8_lossy(packet.payload()));
                    } else {
                        info!("Unknown sender.");
                    }
                }
                SocketEvent::Timeout(_) => {}
                _ => (),
            }
        }

        clear_background(WHITE);
        schedule.execute(&mut world, &mut resources);
        next_frame().await
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
use std::cmp;
use std::mem;
use std::ptr;
use libc::c_int;
use num::complex::{
    Complex32,
    Complex64,
};
use error::Error;
use ll::*;
use matrix::{
    Matrix,
};
use scalar::Scalar;
use types::Layout;
use util::transpose_data;

pub trait Gels: Sized {
    fn gels(layout: Layout, a: &mut Matrix<Self>, b: &mut Matrix<Self>) -> Result<(), Error>;
    fn gels_work(layout: Layout, a: &mut Matrix<Self>, b: &mut Matrix<Self>, work: &mut [Self]) -> Result<(), Error>;
    fn gels_work_len(a: &mut Matrix<Self>, b: &mut Matrix<Self>) -> Result<usize, Error>;
}

macro_rules! least_sq_impl(($($t: ident), +) => ($(
    impl Gels for $t {
        fn gels(layout: Layout, a: &mut Matrix<Self>, b: &mut Matrix<Self>) -> Result<(), Error> {
            //TODO: nancheck

            let work_len = try!(Gels::gels_work_len(a, b));
            let mut work: Vec<$t> = Vec::with_capacity(work_len as usize);
            unsafe {
                work.set_len(work_len as usize);
            }

            print!("{:?}", work_len);

            Gels::gels_work(layout, a, b, &mut work[..])
        }

        fn gels_work(layout: Layout, a: &mut Matrix<Self>, b: &mut Matrix<Self>, work: &mut [Self]) -> Result<(), Error> {
            let mut info: c_int = 0;

            let m = a.rows();
            let n = a.cols();
            let nrhs = b.cols();
            let lda = m;
            let ldb = b.rows();

            match layout {
                Layout::ColMajor => unsafe {
                    prefix!($t, gels_)(
                        a.transpose().as_i8().as_mut(),
                        m.as_mut(), n.as_mut(),
                        nrhs.as_mut(),
                        a.as_mut_ptr(), lda.as_mut(),
                        b.as_mut_ptr(), ldb.as_mut(),
                        work.as_mut_ptr(), (work.len() as c_int).as_mut(),
                        &mut info as *mut c_int);
                },
                Layout::RowMajor => {
                    let mrhs = cmp::max(m, n);

                    let lda_t = cmp::max(1, m);
                    let ldb_t = cmp::max(1, mrhs);

                    let a_t_len = (lda_t * cmp::max(1, n)) as usize;
                    let b_t_len = (ldb_t * cmp::max(1, nrhs)) as usize;
                    let mut a_t = Vec::with_capacity(a_t_len);
                    let mut b_t = Vec::with_capacity(b_t_len);

                    unsafe {
                        a_t.set_len(a_t_len);
                        b_t.set_len(b_t_len);

                        transpose_data(Layout::RowMajor, m as isize, n as isize, a.as_ptr(), m as isize, a_t.as_mut_ptr(), lda_t as isize);
                        transpose_data(Layout::RowMajor, mrhs as isize, nrhs as isize, b.as_ptr(), mrhs as isize, b_t.as_mut_ptr(), ldb_t as isize);

                        prefix!($t, gels_)(
                            a.transpose().as_i8().as_mut(),
                            m.as_mut(), n.as_mut(),
                            nrhs.as_mut(),
                            a_t.as_mut_ptr(), lda_t.as_mut(),
                            b_t.as_mut_ptr(), ldb_t.as_mut(),
                            work.as_mut_ptr(), (work.len() as c_int).as_mut(),
                            &mut info as *mut c_int);

                        transpose_data(Layout::ColMajor, m as isize, n as isize, a_t.as_ptr(), lda_t as isize, a.as_mut_ptr(), m as isize);
                        transpose_data(Layout::ColMajor, mrhs as isize, nrhs as isize, b_t.as_ptr(), ldb_t as isize, b.as_mut_ptr(), mrhs as isize);
                    }
                }
            }

            match info {
                0 => Ok(()),
                x if x < 0 => Err(Error::IllegalParameter(-x as usize)),
                x => Err(Error::DiagonalElementZero(x as usize)),
            }
        }

        fn gels_work_len(a: &mut Matrix<Self>, b: &mut Matrix<Self>) -> Result<usize, Error> {
            let mut info: c_int = 0;
            let mut len_info: $t = unsafe { mem::zeroed() };
            let len_ptr = (&mut len_info) as *mut $t;

            let m = a.rows();
            let n = a.cols();
            let nrhs = b.cols();
            let lda_t = cmp::max(1, m);
            let ldb_t = cmp::max(1, cmp::max(m, n));

            unsafe {
                prefix!($t, gels_)(
                    a.transpose().as_i8().as_mut(),
                    m.as_mut(), n.as_mut(),
                    nrhs.as_mut(),
                    a.as_mut_ptr(), lda_t.as_mut(),
                    b.as_mut_ptr(), ldb_t.as_mut(),
                    len_ptr, (-1 as c_int).as_mut(),
                    &mut info as *mut c_int);
            };

            match info {
                0 => Ok(len_info.as_work()),
                x if x < 0 => Err(Error::IllegalParameter(-x as usize)),
                x => Err(Error::DiagonalElementZero(x as usize)),
            }
        }
    }
)+));

least_sq_impl!(f32, f64, Complex32, Complex64);

#[cfg(test)]
mod gesv_tests {
    use types::Layout::*;
    use least_squares::Gels;

    #[test]
    fn col_major() {
        let mut a = (3i32, 2i32, vec![2.0f32,4.0,7.0,3.0,9.0,4.0]);
        let mut b = (3i32, 2i32, vec![2.0f32,4.0,7.0,6.0,18.0,8.0]);

        Gels::gels(ColMajor, &mut a, &mut b).unwrap();

        let (_, _, x) = b;
        println!("{:?}", x);
        assert_eq!(x, vec![1.0, 0.0, 0.0, 0.0, 2.0, 0.0]);
    }
}
<commit_msg>Remove print statements<commit_after>// Copyright 2014 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
use std::cmp;
use std::mem;
use std::ptr;
use libc::c_int;
use num::complex::{
    Complex32,
    Complex64,
};
use error::Error;
use ll::*;
use matrix::{
    Matrix,
};
use scalar::Scalar;
use types::Layout;
use util::transpose_data;

pub trait Gels: Sized {
    fn gels(layout: Layout, a: &mut Matrix<Self>, b: &mut Matrix<Self>) -> Result<(), Error>;
    fn gels_work(layout: Layout, a: &mut Matrix<Self>, b: &mut Matrix<Self>, work: &mut [Self]) -> Result<(), Error>;
    fn gels_work_len(a: &mut Matrix<Self>, b: &mut Matrix<Self>) -> Result<usize, Error>;
}

macro_rules! least_sq_impl(($($t: ident), +) => ($(
    impl Gels for $t {
        fn gels(layout: Layout, a: &mut Matrix<Self>, b: &mut Matrix<Self>) -> Result<(), Error> {
            //TODO: nancheck

            let work_len = try!(Gels::gels_work_len(a, b));
            let mut work: Vec<$t> = Vec::with_capacity(work_len as usize);
            unsafe {
                work.set_len(work_len as usize);
            }

            Gels::gels_work(layout, a, b, &mut work[..])
        }

        fn gels_work(layout: Layout, a: &mut Matrix<Self>, b: &mut Matrix<Self>, work: &mut [Self]) -> Result<(), Error> {
            let mut info: c_int = 0;

            let m = a.rows();
            let n = a.cols();
            let nrhs = b.cols();
            let lda = m;
            let ldb = b.rows();

            match layout {
                Layout::ColMajor => unsafe {
                    prefix!($t, gels_)(
                        a.transpose().as_i8().as_mut(),
                        m.as_mut(), n.as_mut(),
                        nrhs.as_mut(),
                        a.as_mut_ptr(), lda.as_mut(),
                        b.as_mut_ptr(), ldb.as_mut(),
                        work.as_mut_ptr(), (work.len() as c_int).as_mut(),
                        &mut info as *mut c_int);
                },
                Layout::RowMajor => {
                    let mrhs = cmp::max(m, n);

                    let lda_t = cmp::max(1, m);
                    let ldb_t = cmp::max(1, mrhs);

                    let a_t_len = (lda_t * cmp::max(1, n)) as usize;
                    let b_t_len = (ldb_t * cmp::max(1, nrhs)) as usize;
                    let mut a_t = Vec::with_capacity(a_t_len);
                    let mut b_t = Vec::with_capacity(b_t_len);

                    unsafe {
                        a_t.set_len(a_t_len);
                        b_t.set_len(b_t_len);

                        transpose_data(Layout::RowMajor, m as isize, n as isize, a.as_ptr(), m as isize, a_t.as_mut_ptr(), lda_t as isize);
                        transpose_data(Layout::RowMajor, mrhs as isize, nrhs as isize, b.as_ptr(), mrhs as isize, b_t.as_mut_ptr(), ldb_t as isize);

                        prefix!($t, gels_)(
                            a.transpose().as_i8().as_mut(),
                            m.as_mut(), n.as_mut(),
                            nrhs.as_mut(),
                            a_t.as_mut_ptr(), lda_t.as_mut(),
                            b_t.as_mut_ptr(), ldb_t.as_mut(),
                            work.as_mut_ptr(), (work.len() as c_int).as_mut(),
                            &mut info as *mut c_int);

                        transpose_data(Layout::ColMajor, m as isize, n as isize, a_t.as_ptr(), lda_t as isize, a.as_mut_ptr(), m as isize);
                        transpose_data(Layout::ColMajor, mrhs as isize, nrhs as isize, b_t.as_ptr(), ldb_t as isize, b.as_mut_ptr(), mrhs as isize);
                    }
                }
            }

            match info {
                0 => Ok(()),
                x if x < 0 => Err(Error::IllegalParameter(-x as usize)),
                x => Err(Error::DiagonalElementZero(x as usize)),
            }
        }

        fn gels_work_len(a: &mut Matrix<Self>, b: &mut Matrix<Self>) -> Result<usize, Error> {
            let mut info: c_int = 0;
            let mut len_info: $t = unsafe { mem::zeroed() };
            let len_ptr = (&mut len_info) as *mut $t;

            let m = a.rows();
            let n = a.cols();
            let nrhs = b.cols();
            let lda_t = cmp::max(1, m);
            let ldb_t = cmp::max(1, cmp::max(m, n));

            unsafe {
                prefix!($t, gels_)(
                    a.transpose().as_i8().as_mut(),
                    m.as_mut(), n.as_mut(),
                    nrhs.as_mut(),
                    a.as_mut_ptr(), lda_t.as_mut(),
                    b.as_mut_ptr(), ldb_t.as_mut(),
                    len_ptr, (-1 as c_int).as_mut(),
                    &mut info as *mut c_int);
            };

            match info {
                0 => Ok(len_info.as_work()),
                x if x < 0 => Err(Error::IllegalParameter(-x as usize)),
                x => Err(Error::DiagonalElementZero(x as usize)),
            }
        }
    }
)+));

least_sq_impl!(f32, f64, Complex32, Complex64);

#[cfg(test)]
mod gesv_tests {
    use types::Layout::*;
    use least_squares::Gels;

    #[test]
    fn col_major() {
        let mut a = (3i32, 2i32, vec![2.0f32,4.0,7.0,3.0,9.0,4.0]);
        let mut b = (3i32, 2i32, vec![2.0f32,4.0,7.0,6.0,18.0,8.0]);

        Gels::gels(ColMajor, &mut a, &mut b).unwrap();

        let (_, _, x) = b;
        assert_eq!(x, vec![1.0, 0.0, 0.0, 0.0, 2.0, 0.0]);
    }
}
<|endoftext|>