<commit_before>//! [tui](https://github.com/fdehau/tui-rs) is a library used to build rich
//! terminal users interfaces and dashboards.
//!
//! ![](https://raw.githubusercontent.com/fdehau/tui-rs/master/assets/demo.gif)
//!
//! # Get started
//!
//! ## Creating a `Terminal`
//!
//! Every application using `tui` should start by instantiating a `Terminal`. It is
//! a light abstraction over available backends that provides basic functionalities
//! such as clearing the screen, hiding the cursor, etc. By default only the `termion`
//! backend is available.
//!
//! ```rust,no_run
//! use std::io;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use termion::raw::IntoRawMode;
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     Ok(())
//! }
//! ```
//!
//! If for some reason, you might want to use the `rustbox` backend instead, you
//! need the to replace your `tui` dependency specification by:
//!
//! ```toml
//! [dependencies.tui]
//! version = "0.3.0"
//! default-features = false
//! features = ['rustbox']
//! ```
//!
//! and then create the terminal in a similar way:
//!
//! ```rust,ignore
//!
//! use tui::Terminal;
//! use tui::backend::RustboxBackend;
//!
//! fn main() -> Result<(), io::Error> {
//!     let backend = RustboxBackend::new()?;
//!     let mut terminal = Terminal::new(backend);
//!     Ok(())
//! }
//! ```
//!
//! ## Building a User Interface (UI)
//!
//! Every component of your interface will be implementing the `Widget` trait.
//! The library comes with a predefined set of widgets that should met most of
//! your use cases. You are also free to implement your owns.
//!
//! Each widget follows a builder pattern API providing a default configuration
//! along with methods to customize them. The widget is then registered using
//! its `render` method that take a `Frame` instance and an area to draw
//! to.
//!
//! The following example renders a block of the size of the terminal:
//!
//! ```rust,no_run
//!
//! use std::io;
//! use termion::raw::IntoRawMode;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use tui::widgets::{Widget, Block, Borders};
//! use tui::layout::{Layout, Constraint, Direction};
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     terminal.draw(|mut f| {
//!         let size = f.size();
//!         Block::default()
//!             .title("Block")
//!             .borders(Borders::ALL)
//!             .render(&mut f, size);
//!     })
//! }
//! ```
//!
//! ## Layout
//!
//! The library comes with a basic yet useful layout management object called `Layout`. As you may
//! see below and in the examples, the library makes heavy use of the builder pattern to provide
//! full customization. And `Layout` is no exception:
//!
//! ```rust,no_run
//!
//! use std::io;
//! use termion::raw::IntoRawMode;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use tui::widgets::{Widget, Block, Borders};
//! use tui::layout::{Layout, Constraint, Direction};
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     terminal.draw(|mut f| {
//!         let chunks = Layout::default()
//!             .direction(Direction::Vertical)
//!             .margin(1)
//!             .constraints(
//!                 [
//!                     Constraint::Percentage(10),
//!                     Constraint::Percentage(80),
//!                     Constraint::Percentage(10)
//!                 ].as_ref()
//!             )
//!             .split(f.size());
//!         Block::default()
//!              .title("Block")
//!              .borders(Borders::ALL)
//!              .render(&mut f, chunks[0]);
//!         Block::default()
//!              .title("Block 2")
//!              .borders(Borders::ALL)
//!              .render(&mut f, chunks[2]);
//!     })
//! }
//! ```
//!
//! This let you describe responsive terminal UI by nesting layouts. You should note
//! that by default the computed layout tries to fill the available space
//! completely. So if for any reason you might need a blank space somewhere, try to
//! pass an additional constraint and don't use the corresponding area.

pub mod backend;
pub mod buffer;
pub mod layout;
pub mod style;
pub mod symbols;
pub mod terminal;
pub mod widgets;

pub use self::terminal::{Frame, Terminal};
<commit_msg>Improve onboarding in documentation<commit_after>//! [tui](https://github.com/fdehau/tui-rs) is a library used to build rich
//! terminal users interfaces and dashboards.
//!
//! ![](https://raw.githubusercontent.com/fdehau/tui-rs/master/assets/demo.gif)
//!
//! # Get started
//!
//! ## Adding `tui` as a dependency
//!
//! ```toml
//! [dependencies]
//! tui = "0.5"
//! termion = "1.5"
//! ```
//!
//! The crate is using the `termion` backend by default but if for some reason you might want to use
//! the `rustbox` backend instead, you need the to replace your dependency specification by:
//!
//! ```toml
//! [dependencies]
//! rustbox = "0.11"
//!
//! [dependencies.tui]
//! version = "0.5"
//! default-features = false
//! features = ['rustbox']
//! ```
//!
//! The same logic applies for all other available backends.
//!
//! ## Creating a `Terminal`
//!
//! Every application using `tui` should start by instantiating a `Terminal`. It is a light
//! abstraction over available backends that provides basic functionalities such as clearing the
//! screen, hiding the cursor, etc.
//!
//! ```rust,no_run
//! use std::io;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use termion::raw::IntoRawMode;
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     Ok(())
//! }
//! ```
//!
//! If you had previously chosen `rustbox` as a backend, the terminal can be created in a similar
//! way:
//!
//! ```rust,ignore
//! use tui::Terminal;
//! use tui::backend::RustboxBackend;
//!
//! fn main() -> Result<(), io::Error> {
//!     let backend = RustboxBackend::new()?;
//!     let mut terminal = Terminal::new(backend);
//!     Ok(())
//! }
//! ```
//!
//! You may also refer to the examples to find out how to create a `Terminal` for each available
//! backend.
//!
//! ## Building a User Interface (UI)
//!
//! Every component of your interface will be implementing the `Widget` trait.  The library comes
//! with a predefined set of widgets that should met most of your use cases. You are also free to
//! implement your owns.
//!
//! Each widget follows a builder pattern API providing a default configuration along with methods
//! to customize them. The widget is then registered using its `render` method that take a `Frame`
//! instance and an area to draw to.
//!
//! The following example renders a block of the size of the terminal:
//!
//! ```rust,no_run
//! use std::io;
//! use termion::raw::IntoRawMode;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use tui::widgets::{Widget, Block, Borders};
//! use tui::layout::{Layout, Constraint, Direction};
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     terminal.draw(|mut f| {
//!         let size = f.size();
//!         Block::default()
//!             .title("Block")
//!             .borders(Borders::ALL)
//!             .render(&mut f, size);
//!     })
//! }
//! ```
//!
//! ## Layout
//!
//! The library comes with a basic yet useful layout management object called `Layout`. As you may
//! see below and in the examples, the library makes heavy use of the builder pattern to provide
//! full customization. And `Layout` is no exception:
//!
//! ```rust,no_run
//! use std::io;
//! use termion::raw::IntoRawMode;
//! use tui::Terminal;
//! use tui::backend::TermionBackend;
//! use tui::widgets::{Widget, Block, Borders};
//! use tui::layout::{Layout, Constraint, Direction};
//!
//! fn main() -> Result<(), io::Error> {
//!     let stdout = io::stdout().into_raw_mode()?;
//!     let backend = TermionBackend::new(stdout);
//!     let mut terminal = Terminal::new(backend)?;
//!     terminal.draw(|mut f| {
//!         let chunks = Layout::default()
//!             .direction(Direction::Vertical)
//!             .margin(1)
//!             .constraints(
//!                 [
//!                     Constraint::Percentage(10),
//!                     Constraint::Percentage(80),
//!                     Constraint::Percentage(10)
//!                 ].as_ref()
//!             )
//!             .split(f.size());
//!         Block::default()
//!              .title("Block")
//!              .borders(Borders::ALL)
//!              .render(&mut f, chunks[0]);
//!         Block::default()
//!              .title("Block 2")
//!              .borders(Borders::ALL)
//!              .render(&mut f, chunks[2]);
//!     })
//! }
//! ```
//!
//! This let you describe responsive terminal UI by nesting layouts. You should note that by
//! default the computed layout tries to fill the available space completely. So if for any reason
//! you might need a blank space somewhere, try to pass an additional constraint and don't use the
//! corresponding area.

pub mod backend;
pub mod buffer;
pub mod layout;
pub mod style;
pub mod symbols;
pub mod terminal;
pub mod widgets;

pub use self::terminal::{Frame, Terminal};
<|endoftext|>


<commit_before>#![feature(box_syntax)]
#![feature(core)]
extern crate core;
use core::fmt::Debug;

pub struct Expectation<Lhs: Debug>(Lhs);

pub struct To<Lhs: Debug>(Lhs);

pub trait Matcher<Lhs> {
    fn matches(&self, rhs: &Lhs) -> bool;
    fn fail_msg(&self, rhs: &Lhs) -> String;
}

pub trait WithLen {
    fn match_len(&self) -> usize;
}

impl<T> WithLen for Vec<T> {
    fn match_len(&self) -> usize { self.len() }
}

impl WithLen for String {
    fn match_len(&self) -> usize { self.chars().count() }
}

impl<'a> WithLen for &'a str {
    fn match_len(&self) -> usize { self.chars().count() }
}

pub struct Contains<T>(T);

impl<T: Debug + PartialEq> Matcher<Vec<T>> for Contains<T> {
    fn matches(&self, lhs: &Vec<T>) -> bool {
        lhs.iter().any(|i| *i == self.0)
    }

    fn fail_msg(&self, lhs: &Vec<T>) -> String {
        format!("expected {:?} to contain {:?}", lhs, self.0)
    }
}

impl Matcher<String> for Contains<char> {
    fn matches(&self, lhs: &String) -> bool {
        lhs.chars().any(|i| i == self.0)
    }

    fn fail_msg(&self, lhs: &String) -> String {
        format!("expected \"{:?}\" to contain '{:?}'", lhs, self.0)
    }
}

impl Matcher<String> for Contains<String> {
    fn matches(&self, lhs: &String) -> bool {
        lhs.contains(&*self.0)
    }

    fn fail_msg(&self, lhs: &String) -> String {
        format!("expected \"{:?}\" to contain \"{:?}\"", lhs, self.0)
    }
}

pub struct Empty;

impl<Lhs: Debug + WithLen> Matcher<Lhs> for Empty {
    fn matches(&self, rhs: &Lhs) -> bool {
        rhs.match_len() == 0
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("expected {:?} to be empty", rhs)
    }
}

pub struct LessThan<Lhs: Debug>(Lhs);

impl<Lhs: Debug + PartialOrd> Matcher<Lhs> for LessThan<Lhs> {
    fn matches(&self, lhs: &Lhs) -> bool {
        *lhs < self.0
    }

    fn fail_msg(&self, lhs: &Lhs) -> String {
        format!("expected {:?} to be less than {:?}", self.0, lhs)
    }
}

pub struct GreaterThan<Lhs: Debug>(Lhs);

impl<Lhs: Debug + PartialOrd> Matcher<Lhs> for GreaterThan<Lhs> {
    fn matches(&self, lhs: &Lhs) -> bool {
        *lhs > self.0
    }

    fn fail_msg(&self, lhs: &Lhs) -> String {
        format!("expected {:?} to be greater than {:?}", self.0, lhs)
    }
}

pub struct Equal<Lhs: Debug>(Lhs);

impl<Lhs: Debug + PartialEq> Matcher<Lhs> for Equal<Lhs> {
    fn matches(&self, rhs: &Lhs) -> bool {
        &self.0 == rhs
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("expected {:?} to equal {:?}", rhs, self.0)
    }
}

pub struct AllOf<A: Debug>(Vec<Box<Matcher<A>>>);

impl<Lhs: Debug> Matcher<Lhs> for AllOf<Lhs> {
    fn matches(&self, lhs: &Lhs) -> bool {
        self.0.iter().all(|bm| bm.matches(lhs))
    }

    fn fail_msg(&self, lhs: &Lhs) -> String {
        format!("expected all of {:?}",
                self.0.iter().map(|m| m.fail_msg(lhs)).collect::<Vec<String>>())
    }
}

pub struct AnyOf<A: Debug>(Vec<Box<Matcher<A>>>);

impl<Lhs: Debug> Matcher<Lhs> for AnyOf<Lhs> {
    fn matches(&self, lhs: &Lhs) -> bool {
        self.0.iter().any(|bm| bm.matches(lhs))
    }

    fn fail_msg(&self, lhs: &Lhs) -> String {
        format!("expected one of {:?}",
                self.0.iter().map(|m| m.fail_msg(lhs)).collect::<Vec<String>>())
    }
}

pub struct Not<A>(Box<Matcher<A>>);

impl<Lhs: Debug> Matcher<Lhs> for Not<Lhs> {
    fn matches(&self, rhs: &Lhs) -> bool {
        !self.0.matches(rhs)
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("not {}", self.0.fail_msg(rhs))
    }
}

impl<Lhs: Debug> Expectation<Lhs> {
    pub fn is<T>(&self, matcher: Box<T>) where T: Matcher<Lhs> {
        self.to(matcher)
    }

    pub fn to<T>(&self, matcher: Box<T>) where T: Matcher<Lhs> {
        if !matcher.matches(&self.0) {
            panic!(matcher.fail_msg(&self.0))
        }
    }
}

pub fn expect<T: Debug>(lhs: T) -> Expectation<T> {
    Expectation(lhs)
}

pub fn equal<T: Debug>(rhs: T) -> Box<Equal<T>> {
    box Equal(rhs)
}

pub fn not<T: Debug>(rhs: Box<Matcher<T>>) -> Box<Not<T>> {
    box Not(rhs)
}

pub fn empty() -> Box<Empty> {
    box Empty
}

pub fn contain<T: Debug>(rhs: T) -> Box<Contains<T>> {
    box Contains(rhs)
}

pub fn greater_than<T: Debug>(rhs: T) -> Box<GreaterThan<T>> {
    box GreaterThan(rhs)
}

pub fn less_than<T: Debug>(rhs: T) -> Box<LessThan<T>> {
    box LessThan(rhs)
}

pub fn any_of<T: Debug>(rhs: Vec<Box<Matcher<T>>>) -> Box<AnyOf<T>> {
    box AnyOf(rhs)
}

pub fn all_of<T: Debug>(rhs: Vec<Box<Matcher<T>>>) -> Box<AllOf<T>> {
    box AllOf(rhs)
}

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

    #[test]
    fn test_expect_equality() {
        expect(1).to(equal(1));
    }

    #[test]
    #[should_panic(expected="expected 1 to equal 2")]
    fn test_expect_not_equality_to_fail() {
        expect(1).to(equal(2));
    }

    #[test]
    fn test_partial_eq_equality() {
        #[derive(PartialEq, Debug)]
        struct Foo { a: u16, b: String }

        expect(Foo{ a: 10u16, b: "Hello".to_string()})
            .to(equal(Foo{ a: 10u16, b: "Hello".to_string()}));
    }

    #[test]
    fn test_invert_equality() {
        expect(1).to(not(equal(2)));
    }

    #[test]
    fn test_invert_invert_equality() {
        expect(1).to(not(not(equal(1))));
    }

    #[test]
    #[should_panic(expected="not expected 1 to equal 1")]
    fn test_invert_equality_equal_to_fail() {
        expect(1).to(not(equal(1)));
    }

    #[test]
    fn test_empty() {
        let v: Vec<usize> = Vec::new();
        expect(v).is(empty());
    }

    #[test]
    fn test_not_empty() {
        let v = vec![1, 2, 3];
        expect(v).is(not(empty()));
    }

    #[test]
    fn test_empty_string() {
        expect("".to_string()).is(empty());
    }

    #[test]
    fn test_not_empty_string() {
        expect("not-empty".to_string()).is(not(empty()));
    }

    #[test]
    fn test_empty_str() {
        expect("").is(empty());
    }

    #[test]
    fn test_not_empty_str() {
        expect("not-empty").is(not(empty()));
    }

    #[test]
    fn test_contains() {
        expect(vec![1, 2, 3]).to(contain(1));
    }

    #[test]
    fn test_not_contains() {
        expect(vec![1, 2, 3]).to(not(contain(10)));
    }

    #[test]
    fn test_contains_string_char() {
        expect("Hello, world!".to_string()).to(contain('H'));
    }

    #[test]
    fn test_not_contains_string_char() {
        expect("Hello, world!".to_string()).to(not(contain('Z')));
    }

    #[test]
    fn test_contains_string_substring() {
        expect("Hello, world!".to_string()).to(contain("Hello".to_string()));
    }

    #[test]
    fn test_not_contains_string_substring() {
        expect("Hello, world!".to_string()).to(not(contain("not-in-there".to_string())));
    }

    #[test]
    fn test_greater_than_int() {
        expect(5).is(greater_than(1));
    }

    #[test]
    fn test_not_greater_than_int() {
        expect(5).is(not(greater_than(10)));
    }

    #[test]
    fn test_less_than_int() {
        expect(5).is(less_than(10));
    }

    #[test]
    fn test_not_less_than_int() {
        expect(5).is(not(less_than(1)));
    }

    #[test]
    fn test_any_of() {
        expect(5).is(any_of(vec![less_than(0),
                                 greater_than(1)]))
    }

    #[test]
    fn test_any_of_none() {
        expect(5).is(not(any_of(vec![less_than(0),
                                     greater_than(100)])))
    }

    #[test]
    fn test_all_of() {
        expect(5).is(all_of(vec![less_than(1000),
                                 greater_than(1)]))
    }

    #[test]
    fn test_not_all_of() {
        expect(5).is(not(all_of(vec![less_than(1000),
                                     greater_than(10)])))
    }
}
<commit_msg>Add tests for msg strings<commit_after>#![feature(box_syntax)]
#![feature(core)]
extern crate core;
use core::fmt::Debug;

pub struct Expectation<Lhs: Debug>(Lhs);

pub struct To<Lhs: Debug>(Lhs);

pub trait Matcher<Lhs> {
    fn matches(&self, rhs: &Lhs) -> bool;
    fn fail_msg(&self, rhs: &Lhs) -> String;
}

pub trait WithLen {
    fn match_len(&self) -> usize;
}

impl<T> WithLen for Vec<T> {
    fn match_len(&self) -> usize { self.len() }
}

impl WithLen for String {
    fn match_len(&self) -> usize { self.chars().count() }
}

impl<'a> WithLen for &'a str {
    fn match_len(&self) -> usize { self.chars().count() }
}

pub struct Contains<T>(T);

impl<T: Debug + PartialEq> Matcher<Vec<T>> for Contains<T> {
    fn matches(&self, lhs: &Vec<T>) -> bool {
        lhs.iter().any(|i| *i == self.0)
    }

    fn fail_msg(&self, lhs: &Vec<T>) -> String {
        format!("expected {:?} to contain {:?}", lhs, self.0)
    }
}

impl Matcher<String> for Contains<char> {
    fn matches(&self, lhs: &String) -> bool {
        lhs.chars().any(|i| i == self.0)
    }

    fn fail_msg(&self, lhs: &String) -> String {
        format!("expected {:?} to contain {:?}", lhs, self.0)
    }
}

impl Matcher<String> for Contains<String> {
    fn matches(&self, lhs: &String) -> bool {
        lhs.contains(&*self.0)
    }

    fn fail_msg(&self, lhs: &String) -> String {
        format!("expected {:?} to contain {:?}", lhs, self.0)
    }
}

pub struct Empty;

impl<Lhs: Debug + WithLen> Matcher<Lhs> for Empty {
    fn matches(&self, rhs: &Lhs) -> bool {
        rhs.match_len() == 0
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("expected {:?} to be empty", rhs)
    }
}

pub struct LessThan<Lhs: Debug>(Lhs);

impl<Lhs: Debug + PartialOrd> Matcher<Lhs> for LessThan<Lhs> {
    fn matches(&self, lhs: &Lhs) -> bool {
        *lhs < self.0
    }

    fn fail_msg(&self, lhs: &Lhs) -> String {
        format!("expected {:?} to be less than {:?}", lhs, self.0)
    }
}

pub struct GreaterThan<Lhs: Debug>(Lhs);

impl<Lhs: Debug + PartialOrd> Matcher<Lhs> for GreaterThan<Lhs> {
    fn matches(&self, lhs: &Lhs) -> bool {
        *lhs > self.0
    }

    fn fail_msg(&self, lhs: &Lhs) -> String {
        format!("expected {:?} to be greater than {:?}", lhs, self.0)
    }
}

pub struct Equal<Lhs: Debug>(Lhs);

impl<Lhs: Debug + PartialEq> Matcher<Lhs> for Equal<Lhs> {
    fn matches(&self, rhs: &Lhs) -> bool {
        &self.0 == rhs
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("expected {:?} to equal {:?}", rhs, self.0)
    }
}

pub struct AllOf<A: Debug>(Vec<Box<Matcher<A>>>);

impl<Lhs: Debug> Matcher<Lhs> for AllOf<Lhs> {
    fn matches(&self, lhs: &Lhs) -> bool {
        self.0.iter().all(|bm| bm.matches(lhs))
    }

    fn fail_msg(&self, lhs: &Lhs) -> String {
        format!("expected all of {:?}",
                self.0.iter().map(|m| m.fail_msg(lhs)).collect::<Vec<String>>())
    }
}

pub struct AnyOf<A: Debug>(Vec<Box<Matcher<A>>>);

impl<Lhs: Debug> Matcher<Lhs> for AnyOf<Lhs> {
    fn matches(&self, lhs: &Lhs) -> bool {
        self.0.iter().any(|bm| bm.matches(lhs))
    }

    fn fail_msg(&self, lhs: &Lhs) -> String {
        format!("expected one of {:?}",
                self.0.iter().map(|m| m.fail_msg(lhs)).collect::<Vec<String>>())
    }
}

pub struct Not<A>(Box<Matcher<A>>);

impl<Lhs: Debug> Matcher<Lhs> for Not<Lhs> {
    fn matches(&self, rhs: &Lhs) -> bool {
        !self.0.matches(rhs)
    }

    fn fail_msg(&self, rhs: &Lhs) -> String {
        format!("not {}", self.0.fail_msg(rhs))
    }
}

impl<Lhs: Debug> Expectation<Lhs> {
    pub fn is<T>(&self, matcher: Box<T>) where T: Matcher<Lhs> {
        self.to(matcher)
    }

    pub fn to<T>(&self, matcher: Box<T>) where T: Matcher<Lhs> {
        if !matcher.matches(&self.0) {
            panic!(matcher.fail_msg(&self.0))
        }
    }
}

pub fn expect<T: Debug>(lhs: T) -> Expectation<T> {
    Expectation(lhs)
}

pub fn equal<T: Debug>(rhs: T) -> Box<Equal<T>> {
    box Equal(rhs)
}

pub fn not<T: Debug>(rhs: Box<Matcher<T>>) -> Box<Not<T>> {
    box Not(rhs)
}

pub fn empty() -> Box<Empty> {
    box Empty
}

pub fn contain<T: Debug>(rhs: T) -> Box<Contains<T>> {
    box Contains(rhs)
}

pub fn greater_than<T: Debug>(rhs: T) -> Box<GreaterThan<T>> {
    box GreaterThan(rhs)
}

pub fn less_than<T: Debug>(rhs: T) -> Box<LessThan<T>> {
    box LessThan(rhs)
}

pub fn any_of<T: Debug>(rhs: Vec<Box<Matcher<T>>>) -> Box<AnyOf<T>> {
    box AnyOf(rhs)
}

pub fn all_of<T: Debug>(rhs: Vec<Box<Matcher<T>>>) -> Box<AllOf<T>> {
    box AllOf(rhs)
}

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

    #[test]
    fn test_expect_equality() {
        expect(1).to(equal(1));
    }

    #[test]
    #[should_panic(expected="expected 1 to equal 2")]
    fn test_expect_not_equality_to_fail() {
        expect(1).to(equal(2));
    }

    #[test]
    fn test_partial_eq_equality() {
        #[derive(PartialEq, Debug)]
        struct Foo { a: u16, b: String }

        expect(Foo{ a: 10u16, b: "Hello".to_string()})
            .to(equal(Foo{ a: 10u16, b: "Hello".to_string()}));
    }

    #[test]
    fn test_invert_equality() {
        expect(1).to(not(equal(2)));
    }

    #[test]
    fn test_invert_invert_equality() {
        expect(1).to(not(not(equal(1))));
    }

    #[test]
    #[should_panic(expected="not expected 1 to equal 1")]
    fn test_invert_equality_equal_to_fail() {
        expect(1).to(not(equal(1)));
    }

    #[test]
    fn test_empty() {
        let v: Vec<usize> = Vec::new();
        expect(v).is(empty());
    }

    #[test]
    fn test_not_empty() {
        let v = vec![1, 2, 3];
        expect(v).is(not(empty()));
    }

    #[test]
    #[should_panic(expected="expected [1, 2, 3] to be empty")]
    fn test_not_empty_vec_fails() {
        expect(vec![1, 2, 3]).is(empty());
    }

    #[test]
    fn test_empty_string() {
        expect("".to_string()).is(empty());
    }

    #[test]
    fn test_not_empty_string() {
        expect("not-empty".to_string()).is(not(empty()));
    }

    #[test]
    fn test_empty_str() {
        expect("").is(empty());
    }

    #[test]
    #[should_panic(expected="expected \"hey diddle diddle\" to be empty")]
    fn test_not_empty_str_fails() {
        expect("hey diddle diddle").is(empty())
    }

    #[test]
    fn test_not_empty_str() {
        expect("not-empty").is(not(empty()));
    }

    #[test]
    fn test_contains() {
        expect(vec![1, 2, 3]).to(contain(1));
    }

    #[test]
    fn test_not_contains() {
        expect(vec![1, 2, 3]).to(not(contain(10)));
    }

    #[test]
    #[should_panic(expected="expected [1, 2, 3] to contain 5")]
    fn test_not_contains_fails() {
        expect(vec![1, 2, 3]).to(contain(5));
    }

    #[test]
    fn test_contains_string_char() {
        expect("Hello, world!".to_string()).to(contain('H'));
    }

    #[test]
    fn test_not_contains_string_char() {
        expect("Hello, world!".to_string()).to(not(contain('Z')));
    }

    #[test]
    #[should_panic(expected="expected \"fe fi fo fum\" to contain 'z'")]
    fn test_not_contains_char_fails() {
        expect("fe fi fo fum".to_string()).to(contain('z'));
    }

    #[test]
    fn test_contains_string_substring() {
        expect("Hello, world!".to_string()).to(contain("Hello".to_string()));
    }

    #[test]
    fn test_not_contains_string_substring() {
        expect("Hello, world!".to_string()).to(not(contain("not-in-there".to_string())));
    }

    #[test]
    #[should_panic(expected="expected \"fe fi fo fum\" to contain \"substring\"")]
    fn test_not_contains_substring_fails() {
        expect("fe fi fo fum".to_string()).to(contain("substring".to_string()));
    }

    #[test]
    fn test_greater_than_int() {
        expect(5).is(greater_than(1));
    }

    #[test]
    fn test_not_greater_than_int() {
        expect(5).is(not(greater_than(10)));
    }

    #[test]
    #[should_panic(expected="expected 5 to be greater than 6")]
    fn test_not_greater_than_fails() {
        expect(5).is(greater_than(6));
    }

    #[test]
    fn test_less_than_int() {
        expect(5).is(less_than(10));
    }

    #[test]
    fn test_not_less_than_int() {
        expect(5).is(not(less_than(1)));
    }

    #[test]
    #[should_panic(expected="expected 10 to be less than 6")]
    fn test_not_less_than_fails() {
        expect(10).is(less_than(6));
    }

    #[test]
    fn test_any_of() {
        expect(5).is(any_of(vec![less_than(0),
                                 greater_than(1)]))
    }

    #[test]
    fn test_any_of_none() {
        expect(5).is(not(any_of(vec![less_than(0),
                                     greater_than(100)])))
    }

    #[test]
    fn test_all_of() {
        expect(5).is(all_of(vec![less_than(1000),
                                 greater_than(1)]))
    }

    #[test]
    fn test_not_all_of() {
        expect(5).is(not(all_of(vec![less_than(1000),
                                     greater_than(10)])))
    }
}
<|endoftext|>


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

//! Rurel is a flexible, reusable reinforcement learning (Q learning) implementation in Rust.
//!
//! Implement the [Agent](mdp/trait.Agent.html) and [State](mdp/trait.State.html) traits for your
//! model, then create an [AgentTrainer](struct.AgentTrainer.html) and train it for your model.
//!
//! # Basic Example
//!
//! The following example defines the `State` as a position on a 21x21 2D matrix. The `Action`s
//! that can be taken are: go up, go down, go left and go right. Positions closer to (10, 10) are
//! assigned a higher reward.
//!
//! After training, the AgentTrainer will have assigned higher values to actions which move closer
//! to (10, 10).
//!
//! ```
//! use rurel::mdp::{State, Agent};
//!
//! #[derive(PartialEq, Eq, Hash, Clone)]
//! struct MyState { x: i32, y: i32 }
//! #[derive(PartialEq, Eq, Hash, Clone)]
//! struct MyAction { dx: i32, dy: i32 }
//!
//! impl State for MyState {
//!     type Action = MyAction;
//!     fn reward(&self) -> f64 {
//!         // Negative Euclidean distance
//!         -((((10 - self.x).pow(2) + (10 - self.y).pow(2)) as f64).sqrt())
//!     }
//!     fn actions(&self) -> Vec<MyAction> {
//!         vec![MyAction { dx: 0, dy: -1 },    // up
//!              MyAction { dx: 0, dy: 1 }, // down
//!              MyAction { dx: -1, dy: 0 },    // left
//!              MyAction { dx: 1, dy: 0 }, // right
//!         ]
//!     }
//! }
//!
//! use rurel::AgentTrainer;
//! use rurel::strategy::learn::q::QLearning;
//! use rurel::strategy::explore::random::RandomExploration;
//!
//! struct MyAgent { state: MyState }
//! impl Agent<MyState> for MyAgent {
//!     fn current_state(&self) -> &MyState {
//!         &self.state
//!     }
//!     fn take_action(&mut self, action: &MyAction) -> () {
//!         match action {
//!             &MyAction { dx, dy } => {
//!                 self.state = MyState {
//!                     x: (((self.state.x + dx) % 21) + 21) % 21, // (x+dx) mod 21
//!                     y: (((self.state.y + dy) % 21) + 21) % 21, // (y+dy) mod 21
//!                 }
//!             }
//!         }
//!     }
//! }
//!
//! let mut trainer = AgentTrainer::new();
//! let mut agent = MyAgent { state: MyState { x: 0, y: 0 }};
//! trainer.train(&RandomExploration::new(), &QLearning::new(0.2, 0.01, 2.), &mut agent, 100000);
//!
//! // Test to see if it worked
//! let test_state = MyState { x: 10, y: 9 };
//! let go_up = MyAction { dx: 0, dy: -1 };
//! let go_down = MyAction { dx: 0, dy: 1};
//! // Going down is better than going up
//! assert!(trainer.expected_value(&test_state, &go_down)
//!     > trainer.expected_value(&test_state, &go_up));
//! ```

pub mod mdp;
pub mod strategy;

use std::collections::HashMap;
use mdp::{Agent, State};
use strategy::explore::ExplorationStrategy;
use strategy::learn::LearningStrategy;

/// An `AgentTrainer` can be trained for using a certain [Agent](mdp/trait.Agent.html). After
/// training, the `AgentTrainer` contains learned knowledge about the model, and can be queried for
/// this. For example, you can ask the `AgentTrainer` the expected values of all possible actions
/// in a given state.
pub struct AgentTrainer<S>
    where S: State
{
    q: HashMap<S, HashMap<S::Action, f64>>,
}

impl<S> AgentTrainer<S>
    where S: State
{
    pub fn new() -> AgentTrainer<S> {
        AgentTrainer { q: HashMap::new() }
    }
    /// Fetches the learned values for the given state, by `Action`, or `None` if no value was
    /// learned.
    pub fn expected_values(&self, state: &S) -> Option<&HashMap<S::Action, f64>> {
        // XXX: make associated const with empty map and remove Option?
        self.q.get(state)
    }
    /// Fetches the learned value for the given `Action` in the given `State`, or `None` if no
    /// value was learned.
    pub fn expected_value(&self, state: &S, action: &S::Action) -> Option<f64> {
        self.q
            .get(state)
            .and_then(|m| {
                m.get(action)
                    .and_then(|&v| Some(v))
            })
    }
    /// Trains this `AgentTrainer` using the given `ExplorationStrategy`, `LearningStrategy` and
    /// `Agent` for `iters` iterations.
    pub fn train(&mut self,
                 exploration_strategy: &ExplorationStrategy<S>,
                 learning_strategy: &LearningStrategy<S>,
                 agent: &mut Agent<S>,
                 iters: u32)
                 -> () {
        for _ in 1..iters {
            let s_t = agent.current_state().clone();
            let action = exploration_strategy.take_action(agent);

            // current action value
            let s_t_next = agent.current_state();
            let r_t_next = s_t_next.reward();

            let v = {
                let old_value = self.q.get(&s_t).and_then(|m| m.get(&action));
                learning_strategy.value(&self.q.get(s_t_next), &old_value, r_t_next)
            };

            self.q.entry(s_t).or_insert_with(|| HashMap::new()).insert(action, v);
        }
    }
}
<commit_msg>Replace "model" by "process" in documentation<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Rurel is a flexible, reusable reinforcement learning (Q learning) implementation in Rust.
//!
//! Implement the [Agent](mdp/trait.Agent.html) and [State](mdp/trait.State.html) traits for your
//! process, then create an [AgentTrainer](struct.AgentTrainer.html) and train it for your process.
//!
//! # Basic Example
//!
//! The following example defines the `State` as a position on a 21x21 2D matrix. The `Action`s
//! that can be taken are: go up, go down, go left and go right. Positions closer to (10, 10) are
//! assigned a higher reward.
//!
//! After training, the AgentTrainer will have assigned higher values to actions which move closer
//! to (10, 10).
//!
//! ```
//! use rurel::mdp::{State, Agent};
//!
//! #[derive(PartialEq, Eq, Hash, Clone)]
//! struct MyState { x: i32, y: i32 }
//! #[derive(PartialEq, Eq, Hash, Clone)]
//! struct MyAction { dx: i32, dy: i32 }
//!
//! impl State for MyState {
//!     type Action = MyAction;
//!     fn reward(&self) -> f64 {
//!         // Negative Euclidean distance
//!         -((((10 - self.x).pow(2) + (10 - self.y).pow(2)) as f64).sqrt())
//!     }
//!     fn actions(&self) -> Vec<MyAction> {
//!         vec![MyAction { dx: 0, dy: -1 },    // up
//!              MyAction { dx: 0, dy: 1 }, // down
//!              MyAction { dx: -1, dy: 0 },    // left
//!              MyAction { dx: 1, dy: 0 }, // right
//!         ]
//!     }
//! }
//!
//! use rurel::AgentTrainer;
//! use rurel::strategy::learn::q::QLearning;
//! use rurel::strategy::explore::random::RandomExploration;
//!
//! struct MyAgent { state: MyState }
//! impl Agent<MyState> for MyAgent {
//!     fn current_state(&self) -> &MyState {
//!         &self.state
//!     }
//!     fn take_action(&mut self, action: &MyAction) -> () {
//!         match action {
//!             &MyAction { dx, dy } => {
//!                 self.state = MyState {
//!                     x: (((self.state.x + dx) % 21) + 21) % 21, // (x+dx) mod 21
//!                     y: (((self.state.y + dy) % 21) + 21) % 21, // (y+dy) mod 21
//!                 }
//!             }
//!         }
//!     }
//! }
//!
//! let mut trainer = AgentTrainer::new();
//! let mut agent = MyAgent { state: MyState { x: 0, y: 0 }};
//! trainer.train(&RandomExploration::new(), &QLearning::new(0.2, 0.01, 2.), &mut agent, 100000);
//!
//! // Test to see if it worked
//! let test_state = MyState { x: 10, y: 9 };
//! let go_up = MyAction { dx: 0, dy: -1 };
//! let go_down = MyAction { dx: 0, dy: 1};
//! // Going down is better than going up
//! assert!(trainer.expected_value(&test_state, &go_down)
//!     > trainer.expected_value(&test_state, &go_up));
//! ```

pub mod mdp;
pub mod strategy;

use std::collections::HashMap;
use mdp::{Agent, State};
use strategy::explore::ExplorationStrategy;
use strategy::learn::LearningStrategy;

/// An `AgentTrainer` can be trained for using a certain [Agent](mdp/trait.Agent.html). After
/// training, the `AgentTrainer` contains learned knowledge about the process, and can be queried
/// for this. For example, you can ask the `AgentTrainer` the expected values of all possible
/// actions in a given state.
pub struct AgentTrainer<S>
    where S: State
{
    q: HashMap<S, HashMap<S::Action, f64>>,
}

impl<S> AgentTrainer<S>
    where S: State
{
    pub fn new() -> AgentTrainer<S> {
        AgentTrainer { q: HashMap::new() }
    }
    /// Fetches the learned values for the given state, by `Action`, or `None` if no value was
    /// learned.
    pub fn expected_values(&self, state: &S) -> Option<&HashMap<S::Action, f64>> {
        // XXX: make associated const with empty map and remove Option?
        self.q.get(state)
    }
    /// Fetches the learned value for the given `Action` in the given `State`, or `None` if no
    /// value was learned.
    pub fn expected_value(&self, state: &S, action: &S::Action) -> Option<f64> {
        self.q
            .get(state)
            .and_then(|m| {
                m.get(action)
                    .and_then(|&v| Some(v))
            })
    }
    /// Trains this `AgentTrainer` using the given `ExplorationStrategy`, `LearningStrategy` and
    /// `Agent` for `iters` iterations.
    pub fn train(&mut self,
                 exploration_strategy: &ExplorationStrategy<S>,
                 learning_strategy: &LearningStrategy<S>,
                 agent: &mut Agent<S>,
                 iters: u32)
                 -> () {
        for _ in 1..iters {
            let s_t = agent.current_state().clone();
            let action = exploration_strategy.take_action(agent);

            // current action value
            let s_t_next = agent.current_state();
            let r_t_next = s_t_next.reward();

            let v = {
                let old_value = self.q.get(&s_t).and_then(|m| m.get(&action));
                learning_strategy.value(&self.q.get(s_t_next), &old_value, r_t_next)
            };

            self.q.entry(s_t).or_insert_with(|| HashMap::new()).insert(action, v);
        }
    }
}
<|endoftext|>


<commit_before>use std::ops::*;

pub mod abs;
pub use abs::Abs;

pub mod pi;
pub use pi::PI;

pub mod from_primitive;
pub use from_primitive::FromPrimitive;

pub mod min;
pub use min::Min;

pub mod max;
pub use max::Max;

pub mod signum;
pub use signum::Signum;

pub mod one;
pub use one::One;

pub mod zero;
pub use zero::Zero;

pub mod sqrt;
pub use sqrt::Sqrt;

pub mod trig;
pub use trig::Trig;

pub trait Num:
    Copy + One + Zero + Sqrt
    + Min + Max + Signum
    + Abs
    + PI
    + FromPrimitive
    + Trig
    + PartialEq
    + PartialOrd
    + ToString

    + BitAnd<Output=Self>
    + BitOr<Output=Self>
    + BitXor<Output=Self>
    + Shl<usize, Output=Self>
    + Shr<usize, Output=Self>

    + Add<Self, Output = Self>
    + Mul<Self, Output = Self>
    + Sub<Self, Output = Self>
    + Div<Self, Output = Self>
    + Rem<Self, Output = Self>
    + Neg<Output = Self> {}

impl<T> Num for T where T:
    Copy + One + Zero + Sqrt
    + Min + Max + Signum
    + Abs
    + PI
    + FromPrimitive
    + Trig
    + PartialEq
    + PartialOrd
    + ToString

    + BitAnd<Output=T>
    + BitOr<Output=T>
    + BitXor<Output=T>
    + Shl<usize, Output=T>
    + Shr<usize, Output=T>

    + Add<T, Output = T>
    + Mul<T, Output = T>
    + Sub<T, Output = T>
    + Div<T, Output = T>
    + Rem<T, Output = T>
    + Neg<Output = T> {}
<commit_msg>updates<commit_after>use std::ops::*;

pub mod abs;
pub use abs::Abs;

pub mod pi;
pub use pi::PI;

pub mod from_primitive;
pub use from_primitive::FromPrimitive;

pub mod min;
pub use min::Min;

pub mod max;
pub use max::Max;

pub mod signum;
pub use signum::Signum;

pub mod one;
pub use one::One;

pub mod zero;
pub use zero::Zero;

pub mod sqrt;
pub use sqrt::Sqrt;

pub mod trig;
pub use trig::Trig;

pub trait Num:
    Copy + One + Zero + Sqrt
    + Min + Max + Signum
    + Abs
    + PI
    + FromPrimitive
    + Trig
    + PartialEq
    + PartialOrd
    + ToString

    + Add<Self, Output = Self>
    + Mul<Self, Output = Self>
    + Sub<Self, Output = Self>
    + Div<Self, Output = Self>
    + Rem<Self, Output = Self>
    + Neg<Output = Self> {}

impl<T> Num for T where T:
    Copy + One + Zero + Sqrt
    + Min + Max + Signum
    + Abs
    + PI
    + FromPrimitive
    + Trig
    + PartialEq
    + PartialOrd
    + ToString

    + Add<T, Output = T>
    + Mul<T, Output = T>
    + Sub<T, Output = T>
    + Div<T, Output = T>
    + Rem<T, Output = T>
    + Neg<Output = T> {}
<|endoftext|>


<commit_before>#![allow(dead_code)]
<commit_msg>solved task 1<commit_after>#![allow(dead_code)]

mod task1 {
	fn sum_multiples_3_or_5_below(below: u64) -> u64 {
		let mut s = 0;
		for i in 1..below {
			if i % 5 == 0 || i % 3 == 0 {
				s += i;
			}
		}
		s
	}

	#[test]
	fn test() {
		assert_eq!(sum_multiples_3_or_5_below(1000), 233168);
	}
}
<|endoftext|>


<commit_before>use std::io;
use std::io::prelude::*;
use std::io::{BufReader};
use std::fs::File;
use std::process::{ChildStdout, Command, Stdio, ExitStatus};
use std::path::Path;
use std::thread;
use std::sync::Mutex;
use std::ops::DerefMut;

pub enum Output {
    Parent,
    Ignore,
    FailOnOutput,
    LogToFile(Box<Path>),
}

pub fn output() -> DealWithOutput {
    DealWithOutput { stdout: None, stderr: Output::Parent }
}

impl DealWithOutput {
    pub fn stderr(&mut self, stderr: Output) -> &mut Self {
        self.stderr = stderr;
        self
    }

    pub fn stdout(&mut self, stdout: Output) -> &mut Self {
        self.stdout = Some(stdout);
        self
    }
}

pub struct DealWithOutput { stderr: Output, stdout: Option<Output> }

// Feed the input as stdin to the process and wait for the process to finish
pub fn process_as_consumer<R>(deal_with: &mut DealWithOutput, mut input: R, cmd_args: (String, Vec<String>)) -> io::Result<ExitStatus>
    where R: Read
{
    let mut cmd = build_command(cmd_args);

    cmd.stdin(Stdio::piped());
    setup_stderr(&deal_with.stderr, &mut cmd);
    match deal_with.stdout {
        None => {}
        Some(ref stdout) => {
            setup_stdout(&stdout, &mut cmd);
        }
    }

    let mut process = cmd.spawn()?;
    let mut stdin = process.stdin.take().expect("impossible! no stdin");

    output_optional_handle(&deal_with.stderr, &mut process.stderr)?;
    match deal_with.stdout {
        None => {}
        Some(ref stdout) => {
            output_optional_handle(&stdout, &mut process.stderr)?;
        }
    }

    io::copy(&mut input, &mut stdin)
      .expect("error writing stdin");

    let status = process.wait()?;
    Ok(status)
}

// Provide an iterator interface to a process
//
// Start a process for the given exe and args.
// Return a buffer or the error encountered when starting the process
//
// Feed input (if given) to its stdin (in a separate thread)
// Return a reader of the stdout
//
// Check stder, and wiat for the exit code on separate threads
//
// If any of the threads have failures, including if the proces has a non-zero exit code,
// panic in the that separate thread.
// TODO: the caller should be signalled about the error
pub fn process_as_iterator<R>(deal_with: &mut DealWithOutput, input_opt: Option<R>, cmd_args: (String, Vec<String>)) -> io::Result<BufReader<ChildStdout>>
    where R: Read + Send + 'static
{
    let mut cmd = build_command(cmd_args);

    // setup stdout
    cmd.stdout(Stdio::piped());
    if let Some(_) = input_opt {
        cmd.stdin(Stdio::piped());
    }

    setup_stderr(&deal_with.stderr, &mut cmd);

    let mut process = cmd.spawn()?;
    let stdout = process.stdout.take().expect("impossible! no stdout");

    output_optional_handle(&deal_with.stderr, &mut process.stderr)?;

    // feed input to stdin
    if let Some(input) = input_opt {
        let mut stdin = process.stdin.take().expect("impossible! no stdin");
        let input_mutex = Mutex::new(input);
        thread::spawn(move || {
            let mut inp = input_mutex.lock().expect("locking stdin input");
            io::copy(inp.deref_mut(), &mut stdin)
              .expect("error writing stdin");
        });
    }

    // wait for the process to exit successfully
    thread::spawn(move || {
        // assert that the process exits successfully
        let result = process.wait()
              .expect("error writing for the process to stop");
        if !result.success() {
            panic!("non-zero exit code {:?}", result.code());
        }
    });

    Ok(BufReader::new(stdout))
}

fn setup_stderr(deal_with_stderr: &Output, cmd: &mut Command) -> () {
    // setup stderr
    match deal_with_stderr {
      &Output::Parent => {}
      &Output::Ignore => {
          // connecting to /dev/null would be better, but stderr should be small anyways
          cmd.stderr(Stdio::piped());
      }
      &Output::FailOnOutput => { cmd.stderr(Stdio::piped()); }
      &Output::LogToFile(_) => { cmd.stderr(Stdio::piped()); }
    }
}

fn setup_stdout(deal_with_stdout: &Output, cmd: &mut Command) -> () {
    // setup stderr
    match deal_with_stdout {
      &Output::Parent => {}
      &Output::Ignore => {
          // connecting to /dev/null would be better, but stderr should be small anyways
          cmd.stdout(Stdio::piped());
      }
      &Output::FailOnOutput => { cmd.stdout(Stdio::piped()); }
      &Output::LogToFile(_) => { cmd.stdout(Stdio::piped()); }
    }
}

// Build up the command from the arguments
fn build_command(cmd_args: (String, Vec<String>)) -> Command {
    // Build up the command from the arguments
    let (exe, args) = cmd_args;
    let mut cmd = Command::new(exe);
    for arg in args { cmd.arg(arg); }
    return cmd
}

fn output_optional_handle<R: Read + Send + 'static>(deal_with_output: &Output, opt_handle: &mut Option<R>) -> io::Result<()> {
    if let &Output::FailOnOutput = deal_with_output {
        let handle = opt_handle.take().expect("impossible! no stderr");
        let _ = thread::spawn(move || {
            let mut stderr_output = Vec::new();
            let size = handle.take(1).read_to_end(&mut stderr_output).expect("error reading stdout");
            if size > 0 {
              panic!("got unexpected stderr");
            }
        });
    } else {
        if let &Output::LogToFile(ref path) = deal_with_output {
            let mut handle = opt_handle.take().expect("impossible! no stderr");
            let mut file = File::open(path)?;
            let _ = thread::spawn(move || {
                io::copy(&mut handle, &mut file)
                  .expect("error writing stderr to a log file");
            });
        }
    }

    Ok(())
}
<commit_msg>use Stdio::null<commit_after>use std::io;
use std::io::prelude::*;
use std::io::{BufReader};
use std::fs::File;
use std::process::{ChildStdout, Command, Stdio, ExitStatus};
use std::path::Path;
use std::thread;
use std::sync::Mutex;
use std::ops::DerefMut;

pub enum Output {
    Parent,
    Ignore,
    FailOnOutput,
    LogToFile(Box<Path>),
}

pub fn output() -> DealWithOutput {
    DealWithOutput { stdout: None, stderr: Output::Parent }
}

impl DealWithOutput {
    pub fn stderr(&mut self, stderr: Output) -> &mut Self {
        self.stderr = stderr;
        self
    }

    pub fn stdout(&mut self, stdout: Output) -> &mut Self {
        self.stdout = Some(stdout);
        self
    }
}

pub struct DealWithOutput { stderr: Output, stdout: Option<Output> }

// Feed the input as stdin to the process and wait for the process to finish
pub fn process_as_consumer<R>(deal_with: &mut DealWithOutput, mut input: R, cmd_args: (String, Vec<String>)) -> io::Result<ExitStatus>
    where R: Read
{
    let mut cmd = build_command(cmd_args);

    cmd.stdin(Stdio::piped());
    setup_stderr(&deal_with.stderr, &mut cmd);
    match deal_with.stdout {
        None => {}
        Some(ref stdout) => {
            setup_stdout(&stdout, &mut cmd);
        }
    }

    let mut process = cmd.spawn()?;
    let mut stdin = process.stdin.take().expect("impossible! no stdin");

    output_optional_handle(&deal_with.stderr, &mut process.stderr)?;
    match deal_with.stdout {
        None => {}
        Some(ref stdout) => {
            output_optional_handle(&stdout, &mut process.stderr)?;
        }
    }

    io::copy(&mut input, &mut stdin)
      .expect("error writing stdin");

    let status = process.wait()?;
    Ok(status)
}

// Provide an iterator interface to a process
//
// Start a process for the given exe and args.
// Return a buffer or the error encountered when starting the process
//
// Feed input (if given) to its stdin (in a separate thread)
// Return a reader of the stdout
//
// Check stder, and wiat for the exit code on separate threads
//
// If any of the threads have failures, including if the proces has a non-zero exit code,
// panic in the that separate thread.
// TODO: the caller should be signalled about the error
pub fn process_as_iterator<R>(deal_with: &mut DealWithOutput, input_opt: Option<R>, cmd_args: (String, Vec<String>)) -> io::Result<BufReader<ChildStdout>>
    where R: Read + Send + 'static
{
    let mut cmd = build_command(cmd_args);

    // setup stdout
    cmd.stdout(Stdio::piped());
    if let Some(_) = input_opt {
        cmd.stdin(Stdio::piped());
    }

    setup_stderr(&deal_with.stderr, &mut cmd);

    let mut process = cmd.spawn()?;
    let stdout = process.stdout.take().expect("impossible! no stdout");

    output_optional_handle(&deal_with.stderr, &mut process.stderr)?;

    // feed input to stdin
    if let Some(input) = input_opt {
        let mut stdin = process.stdin.take().expect("impossible! no stdin");
        let input_mutex = Mutex::new(input);
        thread::spawn(move || {
            let mut inp = input_mutex.lock().expect("locking stdin input");
            io::copy(inp.deref_mut(), &mut stdin)
              .expect("error writing stdin");
        });
    }

    // wait for the process to exit successfully
    thread::spawn(move || {
        // assert that the process exits successfully
        let result = process.wait()
              .expect("error writing for the process to stop");
        if !result.success() {
            panic!("non-zero exit code {:?}", result.code());
        }
    });

    Ok(BufReader::new(stdout))
}

fn setup_stderr(deal_with_stderr: &Output, cmd: &mut Command) -> () {
    // setup stderr
    match deal_with_stderr {
      &Output::Parent => {}
      &Output::Ignore => {
          cmd.stderr(Stdio::null());
      }
      &Output::FailOnOutput => { cmd.stderr(Stdio::piped()); }
      &Output::LogToFile(_) => { cmd.stderr(Stdio::piped()); }
    }
}

fn setup_stdout(deal_with_stdout: &Output, cmd: &mut Command) -> () {
    // setup stderr
    match deal_with_stdout {
      &Output::Parent => {}
      &Output::Ignore => {
          cmd.stdout(Stdio::null());
      }
      &Output::FailOnOutput => { cmd.stdout(Stdio::piped()); }
      &Output::LogToFile(_) => { cmd.stdout(Stdio::piped()); }
    }
}

// Build up the command from the arguments
fn build_command(cmd_args: (String, Vec<String>)) -> Command {
    // Build up the command from the arguments
    let (exe, args) = cmd_args;
    let mut cmd = Command::new(exe);
    for arg in args { cmd.arg(arg); }
    return cmd
}

fn output_optional_handle<R: Read + Send + 'static>(deal_with_output: &Output, opt_handle: &mut Option<R>) -> io::Result<()> {
    if let &Output::FailOnOutput = deal_with_output {
        let handle = opt_handle.take().expect("impossible! no stderr");
        let _ = thread::spawn(move || {
            let mut stderr_output = Vec::new();
            let size = handle.take(1).read_to_end(&mut stderr_output).expect("error reading stdout");
            if size > 0 {
              panic!("got unexpected stderr");
            }
        });
    } else {
        if let &Output::LogToFile(ref path) = deal_with_output {
            let mut handle = opt_handle.take().expect("impossible! no stderr");
            let mut file = File::open(path)?;
            let _ = thread::spawn(move || {
                io::copy(&mut handle, &mut file)
                  .expect("error writing stderr to a log file");
            });
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>
#![crate_name = "tcc"]
#![crate_type = "lib"]

extern crate time;
use std::default::Default;

pub static EPOCH: i64 = 864000;

pub struct Yearbase(pub Option<u64>);

pub struct Timestamp {
    ts: i64,
}

#[derive(Clone,Default)]
pub struct Calendar {
    year_sign: bool,
    delim_month: char,
    delim_day: char,
    delim_hour: char,
    delim_minute: char,
    delim_second: char,
    delim_desig: Option<char>,

    mod_quarter: i64,
    mod_month: i64,
    mod_week: i64,
    mod_day: i64,
    mod_hour: i64,
    mod_minute: i64,
    mod_second: i64,
}

pub struct Time {
    year: i64,
    month: i8,
    day: i8,
    hour: i8,
    minute: i8,
    second: i8,
    nano_second: i32,
    year_base: Yearbase,
}

pub fn now() -> Timestamp {
    let utc = time::get_time();
    Timestamp {ts:utc.sec - EPOCH}
}

pub fn at(utc : time::Timespec) -> Timestamp {
    Timestamp {ts : utc.sec - EPOCH}
}

impl Calendar {
    pub fn new() -> Calendar {
        let cal: Calendar = Default::default();
        cal
    }

    pub fn at(&self, t : Time) -> String {
        t.to_string()
    }

    pub fn force_year_sign(&mut self, force : bool) -> Calendar {
        self.year_sign = force;
        (*self).clone()
    }

    pub fn month_delimiter(&mut self, delim: char) -> Calendar {
        self.delim_month = delim;
        (*self).clone()
    }

    pub fn designator_delimiter(&mut self, delim: Option<char>) -> Calendar {
        self.delim_desig = delim;
        (*self).clone()
    }
}

/* TODO see http://internals.rust-lang.org/t/orphan-rules/1322
impl collections::string::ToString for Calendar {
    pub fn to_string(&self) -> String {
        self.at(Time::at(time::Timespec{sec: EPOCH, nsec: 0},Yearbase(None)));
    }
}
*/

impl Time {
    fn new(utc : time::Timespec, year_base : Yearbase) -> Time {
        let mut ts : i64 = utc.sec -864000;
        let year = ts / (60*60*24*28*13);
        ts = ts - year*13*28*24*60*60;
        let mon = ts / (60*60*24*28);
        ts = ts - mon*28*24*60*60;
        let day = ts / (60*60*24);
        ts = ts - day*24*60*60;
        let hour = ts / (60*60);
        ts = ts - hour*60*60;
        let min = ts / 60;
        ts = ts - min*60;

        Time{year: year as i64,
             month: mon as i8,
             day: day as i8,
             hour: hour as i8,
             minute: min as i8,
             second: ts as i8,
             nano_second: utc.nsec as i32,
             year_base: year_base}
    }

    pub fn now(year_base : Yearbase) -> Time {
        let utc = time::get_time();
        Time::new(utc,year_base)
    }

    pub fn at (utc : time::Timespec, year_base : Yearbase) -> Time {
        Time::new(utc,year_base)
    }
}

impl std::fmt::Display for Timestamp {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f,"TC+{}",self.ts)
    }
}

impl std::fmt::Display for Time {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {

        let Yearbase(ybo) = self.year_base;
        let yb = match ybo {
            Some(value) => format!("TC{}",value),
            None        => "".to_string(),
        };

        let sec = self.second as f64 + 1e-9*(self.nano_second as f64);

        write!(f,"{}.{}.{},{}.{}.{} TC{}",
                 self.year,
                 self.month,
                 self.day,
                 self.hour,
                 self.minute,
                 sec,
                 yb)
    }
}

impl std::fmt::Display for Calendar {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        // TODO: insert formatting function here
        write!(f,"{}",self.at(Time::at(time::Timespec{sec: EPOCH, nsec: 0},Yearbase(None))))
    }
}
<commit_msg>add delimiter set functions<commit_after>
#![crate_name = "tcc"]
#![crate_type = "lib"]

extern crate time;
use std::default::Default;

pub static EPOCH: i64 = 864000;

pub struct Yearbase(pub Option<u64>);

pub struct Timestamp {
    ts: i64,
}

#[derive(Clone,Default)]
/// Object for formatting TCC timestamps
pub struct Calendar {
    /// Indicates if the sign (+/-) should always be displayed before the year feild.
    year_sign: bool,
    delim_month: char,
    delim_day: char,
    delim_hour: char,
    delim_minute: char,
    delim_second: char,
    delim_desig: Option<char>,

    mod_quarter: i64,
    mod_month: i64,
    mod_week: i64,
    mod_day: i64,
    mod_hour: i64,
    mod_minute: i64,
    mod_second: i64,
}

pub struct Time {
    year: i64,
    month: i8,
    day: i8,
    hour: i8,
    minute: i8,
    second: i8,
    nano_second: i32,
    year_base: Yearbase,
}

pub fn now() -> Timestamp {
    let utc = time::get_time();
    Timestamp {ts:utc.sec - EPOCH}
}

pub fn at(utc : time::Timespec) -> Timestamp {
    Timestamp {ts : utc.sec - EPOCH}
}

    fn acceptable_delimiter(delim: char) -> bool {
        match delim {
            ','|'/'|' '|'_'|':'|'.' => true,
                                  _ => false,
        }
    }

impl Calendar {
    pub fn new() -> Calendar {
        let cal: Calendar = Default::default();
        cal
    }

    pub fn at(&self, t : Time) -> String {
        t.to_string()
    }

    pub fn force_year_sign(&mut self, force : bool) -> Calendar {
        self.year_sign = force;
        (*self).clone()
    }

    pub fn month_delimiter(&mut self, delim: char) -> Calendar {
        if acceptable_delimiter(delim) {
            self.delim_month = delim;
        }
        (*self).clone()
    }

    pub fn day_delimiter(&mut self, delim: char) -> Calendar {
        if acceptable_delimiter(delim) {
            self.delim_day = delim;
        }
        (*self).clone()
    }

    pub fn hour_delimiter(&mut self, delim: char) -> Calendar {
        if acceptable_delimiter(delim) {
            self.delim_hour = delim;
        }
        (*self).clone()
    }

    pub fn minute_delimiter(&mut self, delim: char) -> Calendar {
        if acceptable_delimiter(delim) {
            self.delim_minute = delim;
        }
        (*self).clone()
    }

    pub fn second_delimiter(&mut self, delim: char) -> Calendar {
        if acceptable_delimiter(delim) {
            self.delim_second = delim;
        }
        (*self).clone()
    }

    pub fn designator_delimiter(&mut self, delim: Option<char>) -> Calendar {
        self.delim_desig = match delim {
            Some(d) => match acceptable_delimiter(d) {
                true => delim,
                false => self.delim_desig,
            },
            None => delim,
        };
        (*self).clone()
    }

}

/* TODO see http://internals.rust-lang.org/t/orphan-rules/1322
impl collections::string::ToString for Calendar {
    pub fn to_string(&self) -> String {
        self.at(Time::at(time::Timespec{sec: EPOCH, nsec: 0},Yearbase(None)));
    }
}
*/

impl Time {
    fn new(utc : time::Timespec, year_base : Yearbase) -> Time {
        let mut ts : i64 = utc.sec -864000;
        let year = ts / (60*60*24*28*13);
        ts = ts - year*13*28*24*60*60;
        let mon = ts / (60*60*24*28);
        ts = ts - mon*28*24*60*60;
        let day = ts / (60*60*24);
        ts = ts - day*24*60*60;
        let hour = ts / (60*60);
        ts = ts - hour*60*60;
        let min = ts / 60;
        ts = ts - min*60;

        Time{year: year as i64,
             month: mon as i8,
             day: day as i8,
             hour: hour as i8,
             minute: min as i8,
             second: ts as i8,
             nano_second: utc.nsec as i32,
             year_base: year_base}
    }

    pub fn now(year_base : Yearbase) -> Time {
        let utc = time::get_time();
        Time::new(utc,year_base)
    }

    pub fn at (utc : time::Timespec, year_base : Yearbase) -> Time {
        Time::new(utc,year_base)
    }
}

impl std::fmt::Display for Timestamp {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f,"TC+{}",self.ts)
    }
}

impl std::fmt::Display for Time {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {

        let Yearbase(ybo) = self.year_base;
        let yb = match ybo {
            Some(value) => format!("TC{}",value),
            None        => "".to_string(),
        };

        let sec = self.second as f64 + 1e-9*(self.nano_second as f64);

        write!(f,"{}.{}.{},{}.{}.{} TC{}",
                 self.year,
                 self.month,
                 self.day,
                 self.hour,
                 self.minute,
                 sec,
                 yb)
    }
}

impl std::fmt::Display for Calendar {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        // TODO: insert formatting function here
        write!(f,"{}",self.at(Time::at(time::Timespec{sec: EPOCH, nsec: 0},Yearbase(None))))
    }
}
<|endoftext|>


<commit_before>//! High level bindings to [libxdo](http://www.semicomplete.com/files/xdotool/docs/html/)

#![warn(missing_docs)]

extern crate libxdo_sys as sys;
extern crate libc;

use std::ffi::{CString, NulError};
use std::convert::From;
use libc::c_int;
use std::ptr::null;

/// An XDo instance
pub struct XDo {
    handle: *mut sys::xdo_t
}

/// An error that can happen when trying to create an XDo instance.
#[derive(Debug)]
pub enum XDoCreationError {
    /// The parameter passed in contained a nul character.
    NulError(NulError),
    /// Unknown error
    Unknown
}

impl From<NulError> for XDoCreationError {
    fn from(err: NulError) -> XDoCreationError {
        XDoCreationError::NulError(err)
    }
}

#[derive(Debug)]
enum XDoOperationErrorKind {
    NulError(NulError),
    OperationFailed
}

/// An error originating from an XDo operation.
#[derive(Debug)]
struct XDoOperationError {
    kind: XDoOperationErrorKind
}

impl From<NulError> for XDoOperationError {
    fn from(err: NulError) -> XDoOperationError {
        XDoOperationError {
            kind: XDoOperationErrorKind::NulError(err)
        }
    }
}

/// Result of an XDo operation.
pub type OpResult = Result<(), XDoOperationError>;

macro_rules! xdo (
    ($fncall: expr) => {
        unsafe {
            match $fncall {
                0 => Ok(()),
                _ => Err(XDoOperationError{ kind: XDoOperationErrorKind::OperationFailed })
            }
        }
    }
);

impl XDo {
    /// Creates a new XDo instance.
    ///
    /// # Parameters
    ///
    /// display - An optional string display name, such as ":0". If None, uses the environment
    /// DISPLAY.
    ///
    /// # Returns
    ///
    /// Returns a new XDo instance, or an XDoCreationError on error.
    pub fn new(display: Option<&str>) -> Result<XDo, XDoCreationError> {
        let display = match display {
            Some(display) => {
                let cstr = try!(CString::new(display));
                cstr.as_ptr()
            },
            None => null()
        };
        let handle = unsafe { sys::xdo_new(display) };
        if handle.is_null() {
            return Err(XDoCreationError::Unknown);
        }
        Ok(XDo {
            handle: handle
        })
    }
    /// Moves the mouse to the specified position.
    pub fn move_mouse(&self, x: i32, y: i32, screen: i32) -> OpResult {
        xdo!(sys::xdo_move_mouse(self.handle, x as c_int, y as c_int, screen as c_int))
    }
    /// Moves the mouse relative to the current position.
    pub fn move_mouse_relative(&self, x: i32, y: i32) -> OpResult {
        xdo!(sys::xdo_move_mouse_relative(self.handle, x as c_int, y as c_int))
    }
    /// Does a mouse click.
    pub fn click(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_click_window(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Holds a mouse button down.
    pub fn mouse_down(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_mouse_down(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Releases a mouse button.
    pub fn mouse_up(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_mouse_up(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Types the specified text.
    pub fn enter_text(&self, text: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(text));
        xdo!(sys::xdo_enter_text_window(self.handle, sys::CURRENTWINDOW, string.as_ptr(),
                                        delay_microsecs))
    }
    /// Does the specified key sequence.
    pub fn send_keysequence(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window(self.handle, sys::CURRENTWINDOW, string.as_ptr(),
                                              delay_microsecs))
    }
    /// Releases the specified key sequence.
    pub fn send_keysequence_up(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window_up(self.handle, sys::CURRENTWINDOW, string.as_ptr(),
                                                 delay_microsecs))
    }
    /// Presses the specified key sequence down.
    pub fn send_keysequence_down(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window_down(self.handle, sys::CURRENTWINDOW,
                                                   string.as_ptr(), delay_microsecs))
    }
}

impl Drop for XDo {
    fn drop(&mut self) {
        unsafe { sys::xdo_free(self.handle); }
    }
}
<commit_msg>Format with rustfmt<commit_after>//! High level bindings to [libxdo](http://www.semicomplete.com/files/xdotool/docs/html/)

#![warn(missing_docs)]

extern crate libxdo_sys as sys;
extern crate libc;

use std::ffi::{CString, NulError};
use std::convert::From;
use libc::c_int;
use std::ptr::null;

/// An XDo instance
pub struct XDo {
    handle: *mut sys::xdo_t,
}

/// An error that can happen when trying to create an XDo instance.
#[derive(Debug)]
pub enum XDoCreationError {
    /// The parameter passed in contained a nul character.
    NulError(NulError),
    /// Unknown error
    Unknown,
}

impl From<NulError> for XDoCreationError {
    fn from(err: NulError) -> XDoCreationError {
        XDoCreationError::NulError(err)
    }
}

#[derive(Debug)]
enum XDoOperationErrorKind {
    NulError(NulError),
    OperationFailed,
}

/// An error originating from an XDo operation.
#[derive(Debug)]
struct XDoOperationError {
    kind: XDoOperationErrorKind,
}

impl From<NulError> for XDoOperationError {
    fn from(err: NulError) -> XDoOperationError {
        XDoOperationError { kind: XDoOperationErrorKind::NulError(err) }
    }
}

/// Result of an XDo operation.
pub type OpResult = Result<(), XDoOperationError>;

macro_rules! xdo (
    ($fncall: expr) => {
        unsafe {
            match $fncall {
                0 => Ok(()),
                _ => Err(XDoOperationError{ kind: XDoOperationErrorKind::OperationFailed })
            }
        }
    }
);

impl XDo {
    /// Creates a new XDo instance.
    ///
    /// # Parameters
    ///
    /// display - An optional string display name, such as ":0". If None, uses the environment
    /// DISPLAY.
    ///
    /// # Returns
    ///
    /// Returns a new XDo instance, or an XDoCreationError on error.
    pub fn new(display: Option<&str>) -> Result<XDo, XDoCreationError> {
        let display = match display {
            Some(display) => {
                let cstr = try!(CString::new(display));
                cstr.as_ptr()
            }
            None => null(),
        };
        let handle = unsafe { sys::xdo_new(display) };
        if handle.is_null() {
            return Err(XDoCreationError::Unknown);
        }
        Ok(XDo { handle: handle })
    }
    /// Moves the mouse to the specified position.
    pub fn move_mouse(&self, x: i32, y: i32, screen: i32) -> OpResult {
        xdo!(sys::xdo_move_mouse(self.handle, x as c_int, y as c_int, screen as c_int))
    }
    /// Moves the mouse relative to the current position.
    pub fn move_mouse_relative(&self, x: i32, y: i32) -> OpResult {
        xdo!(sys::xdo_move_mouse_relative(self.handle, x as c_int, y as c_int))
    }
    /// Does a mouse click.
    pub fn click(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_click_window(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Holds a mouse button down.
    pub fn mouse_down(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_mouse_down(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Releases a mouse button.
    pub fn mouse_up(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_mouse_up(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Types the specified text.
    pub fn enter_text(&self, text: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(text));
        xdo!(sys::xdo_enter_text_window(self.handle,
                                        sys::CURRENTWINDOW,
                                        string.as_ptr(),
                                        delay_microsecs))
    }
    /// Does the specified key sequence.
    pub fn send_keysequence(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window(self.handle,
                                              sys::CURRENTWINDOW,
                                              string.as_ptr(),
                                              delay_microsecs))
    }
    /// Releases the specified key sequence.
    pub fn send_keysequence_up(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window_up(self.handle,
                                                 sys::CURRENTWINDOW,
                                                 string.as_ptr(),
                                                 delay_microsecs))
    }
    /// Presses the specified key sequence down.
    pub fn send_keysequence_down(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window_down(self.handle,
                                                   sys::CURRENTWINDOW,
                                                   string.as_ptr(),
                                                   delay_microsecs))
    }
}

impl Drop for XDo {
    fn drop(&mut self) {
        unsafe {
            sys::xdo_free(self.handle);
        }
    }
}
<|endoftext|>


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

extern crate image;
extern crate rand;
extern crate rayon;

pub mod geometrify;

use image::RgbaImage;
use rand::Rng;

#[derive(Clone, Copy, Debug)]
pub struct Point {
    x: i32,
    y: i32,
}

impl Point {
    pub fn cross_product(&self, b: Point) -> i32 {
        self.x * b.y - self.y * b.x
    }
}

#[derive(Debug, Copy, Clone)]
struct BoundingBox {
    top_left: Point,
    bottom_right: Point,
}

pub trait PointGenerator {
    fn next_point(&mut self, width: u32, height: u32) -> Point;
}

pub struct RandomPointGenerator {
    rng: Box<Rng>,
}

impl RandomPointGenerator {
    pub fn new() -> RandomPointGenerator {
        RandomPointGenerator { rng: Box::new(::rand::weak_rng()) }
    }
}

impl Default for RandomPointGenerator {
    fn default() -> Self {
        RandomPointGenerator::new()
    }
}

impl PointGenerator for RandomPointGenerator {
    fn next_point(&mut self, width: u32, height: u32) -> Point {
        Point {
            x: self.rng.gen_range(0, width as i32),
            y: self.rng.gen_range(0, height as i32),
        }
    }
}

pub trait ProgressReporter {
    fn init(&mut self, count: u64);
    fn step(&mut self);
    fn finish(&mut self);
}

pub struct SilentProgressReporter;

impl SilentProgressReporter {
    pub fn new() -> SilentProgressReporter {
        SilentProgressReporter {}
    }
}

impl ProgressReporter for SilentProgressReporter {
    fn init(&mut self, _: u64) {}
    fn step(&mut self) {}
    fn finish(&mut self) {}
}

pub trait Filter {
    fn apply(&mut self, image: &RgbaImage, progress: &mut ProgressReporter) -> RgbaImage;
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<commit_msg>Remove empty test.<commit_after>/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

extern crate image;
extern crate rand;
extern crate rayon;

pub mod geometrify;

use image::RgbaImage;
use rand::Rng;

#[derive(Clone, Copy, Debug)]
pub struct Point {
    x: i32,
    y: i32,
}

impl Point {
    pub fn cross_product(&self, b: Point) -> i32 {
        self.x * b.y - self.y * b.x
    }
}

#[derive(Debug, Copy, Clone)]
struct BoundingBox {
    top_left: Point,
    bottom_right: Point,
}

pub trait PointGenerator {
    fn next_point(&mut self, width: u32, height: u32) -> Point;
}

pub struct RandomPointGenerator {
    rng: Box<Rng>,
}

impl RandomPointGenerator {
    pub fn new() -> RandomPointGenerator {
        RandomPointGenerator { rng: Box::new(::rand::weak_rng()) }
    }
}

impl Default for RandomPointGenerator {
    fn default() -> Self {
        RandomPointGenerator::new()
    }
}

impl PointGenerator for RandomPointGenerator {
    fn next_point(&mut self, width: u32, height: u32) -> Point {
        Point {
            x: self.rng.gen_range(0, width as i32),
            y: self.rng.gen_range(0, height as i32),
        }
    }
}

pub trait ProgressReporter {
    fn init(&mut self, count: u64);
    fn step(&mut self);
    fn finish(&mut self);
}

pub struct SilentProgressReporter;

impl SilentProgressReporter {
    pub fn new() -> SilentProgressReporter {
        SilentProgressReporter {}
    }
}

impl ProgressReporter for SilentProgressReporter {
    fn init(&mut self, _: u64) {}
    fn step(&mut self) {}
    fn finish(&mut self) {}
}

pub trait Filter {
    fn apply(&mut self, image: &RgbaImage, progress: &mut ProgressReporter) -> RgbaImage;
}
<|endoftext|>


<commit_before>//! `tzdata` uses the IANA Time Zone Database to provide conversion between timezones.
extern crate time;

mod parse;

pub use time::*;
use std::rc::Rc;
use std::io;
use std::fmt;
use std::cmp::{Eq, PartialEq, Ord, PartialOrd, Ordering};

/// A named timezone from the [`IANA Time Zone Database`](https://www.iana.org/time-zones)
///
/// # Example
///
/// ```rust
/// let utc = tzdata::Timezone::utc();
/// let now = utc.now();
///
/// for tzname in &["Europe/Paris", "America/New_York", "Asia/Seoul"] {
///     let tz = tzdata::Timezone::new(tzname).unwrap();
///     let now = now.project(&tz);
///     println!("it is now {:?} in {}", now, tz.name);
/// }
/// ```
pub struct Timezone {
    /// The timezone name e.g. `Europe/Paris`.
    pub name: String,
    /// The UTC offset transitions
    trans: Vec<Transition>,
}

#[derive(Debug)]
struct Transition {
    utc: i64,
    ttype: Rc<Type>,
}

#[derive(Debug)]
struct Type {
    utc_off_sec: i32,
    is_dst: bool,
    abbr: String,
}

impl Timezone {
    /// Try to load a new `Timezone`.
    /// It assumes that the zoneinfo data are located
    /// under `/usr/share/zoneinfo`.
    pub fn new(timezone: &str) -> io::Result<Self> {
        parse::load_timezone(timezone)
    }

    /// Load the local `Timezone` set by the system,
    /// disregarding the `TZ` environment variable.
    pub fn local() -> io::Result<Self> {
        parse::load_timezone("localtime")
    }

    /// Returns the `UTC` timezone.
    pub fn utc() -> Self {
        Self::fixed(0)
    }

    /// Returns a fixed offset to `UTC` timezone.
    /// The provided offset is in seconds.
    pub fn fixed(sec: i32) -> Self {
        Timezone {
            name: "UTC".to_owned(),
            trans: vec![
                Transition {
                    utc: std::i64::MIN,
                    ttype: Rc::new(Type {
                        utc_off_sec: sec,
                        is_dst: false,
                        abbr: "".to_owned(),
                    }),
                }
            ],
        }
    }

    /// Compute the UTC offset in this `Timezone` for unix timestamp `t`.
    fn offset(&self, stamp: i64) -> i32 {
        let idx = match self.trans.binary_search_by(|t| t.utc.cmp(&stamp)) {
            Err(0) => return 0, // FIXME?
            Err(i) => i - 1,
            Ok(i) => i,
        };

        self.trans[idx].ttype.utc_off_sec
    }

    /// Return the `Datetime` representing now, relative to this `Timezone`.
    pub fn now(&self) -> Datetime {
        Datetime {
            tz: self,
            stamp: time::get_time(),
            is_60th_sec: false,
        }
    }

    /// Create a new `Datetime` relative to this `Timezone`.
    /// Panics if the following constraints do not hold:
    ///
    /// - `month` ∊ [1, 12]
    /// - `day` ∊ [1, 31] and is valid within the month
    /// - `hour` ∊ [0, 23]
    /// - `minute` ∊ [0, 59]
    /// - `second` ∊ [0, 59]
    /// - `nano` ∊ [0, 999999999]
    pub fn datetime(&self, year: i32, month: i32, day: i32, hour: i32, minute: i32, second: i32, nano: i32) -> Datetime {
        let is_leap_year = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

        // Panics if constaints described in documentation do not hold.
        assert!(month >= 1 && month <= 12);
        assert!(hour <= 23);
        assert!(minute <= 59);
        assert!(second <= 59); // TODO: handle leap second
        assert!(nano <= 999_999_999);
        let max_day = match month {
            1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
            4 | 6 | 9 | 11 => 30,
            2 if is_leap_year => 30,
            2 => 29,
            _ => unreachable!(),
        };
        assert!(day >= 1 && day <= max_day);

        // Let the time crate do the heavy lifting.
        let utc_dt = time::Tm {
            tm_sec: second as i32,
            tm_min: minute as i32,
            tm_hour: hour as i32,
            tm_mday: day as i32,
            tm_mon: (month - 1) as i32,
            tm_year: (year - 1900) as i32,
            tm_wday: 0,
            tm_yday: 0,
            tm_isdst: 0,
            tm_utcoff: 0,
            tm_nsec: nano as i32,
        };
        let mut stamp = utc_dt.to_timespec();
        let utc_offset = self.offset(stamp.sec);
        stamp.sec -= utc_offset as i64;

        println!("stamp: {}", stamp.sec);
        Datetime {
            tz: self,
            stamp: stamp,
            is_60th_sec: false, // Always false because of ambiguity
        }
    }
}

/// A precise point in time along associated to a `Timezone`.
///
/// The `Datetime` cannot be created on its own as it depends on
/// a `Timezone`. `tzdata` does not expose a naive flavor of Datetime.
/// To build a `Datetime`, instanciate a `Timezone` first and call
/// the desired method.
///
/// ```rust
/// let paris = tzdata::Timezone::new("Europe/Paris").unwrap();
/// let midnight_in_paris = paris.datetime(2015, 12, 25, 0, 0, 0, 0);
///
/// let utc = tzdata::Timezone::utc();
/// let t = midnight_in_paris.project(&utc);
///
/// assert_eq!(t.date(), (2015, 12, 24));
/// assert_eq!(t.time(), (23, 0, 0, 0));
/// ```
pub struct Datetime<'a> {
    /// The associated timezone.
    tz: &'a Timezone,
    /// The offset since Unix Epoch. This is *not* the number
    /// of SI seconds since Unix Epoch because of leap seconds.
    stamp: time::Timespec,
    /// Remove ambiguous datetime on leap. When stamp
    /// corresponds to a leap second, use this field
    /// to know whether the `Datetime` corresponds to
    /// the 59th or the 60th second.
    is_60th_sec: bool,
}

impl<'a> Datetime<'a> {
    /// Project the current `Datetime` in another `Timezone`.
    pub fn project<'b>(&self, tz: &'b Timezone) -> Datetime<'b> {
        Datetime {
            tz: tz,
            stamp: self.stamp,
            is_60th_sec: self.is_60th_sec,
        }
    }

    /// Return the tm in the associated `Timezone`.
    fn tm(&self) -> time::Tm {
        let offset = self.tz.offset(self.stamp.sec);
        let local = time::Timespec {
            sec: self.stamp.sec + offset as i64,
            nsec: self.stamp.nsec,
        };
        let mut tm = time::at_utc(local);
        println!("on {:#?}, offset for {} = {}", tm, self.tz.name, offset);
        tm.tm_utcoff = offset;
        tm
    }

    /// Return the date component of the `Datetime` expressed
    /// in the associated `Timezone`. The tuple holds the
    /// year, month and day in this order.
    pub fn date(&self) -> (i32, i32, i32) {
        let tm = self.tm();
        (tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday)
    }

    /// Return the time component of the `Datetime` expressed
    /// in the associated `Timezone`. The tuple holds
    /// the hour, minute, second and nanosecond in this order.
    pub fn time(&self) -> (i32, i32, i32, i32) {
        let tm = self.tm();
        (tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_nsec)
    }
}

impl<'a> PartialEq<Datetime<'a>> for Datetime<'a> {
    fn eq(&self, other: &Datetime) -> bool {
        self.stamp.eq(&other.stamp)
    }
}

impl<'a> Eq for Datetime<'a> {}

impl<'a> PartialOrd<Datetime<'a>> for Datetime<'a> {
    fn partial_cmp(&self, other: &Datetime) -> Option<Ordering> {
        let cmp = self.stamp.cmp(&other.stamp);
        if let Ordering::Equal = cmp {
            Some(self.is_60th_sec.cmp(&other.is_60th_sec))
        } else {
            Some(cmp)
        }
    }
}

impl<'a> Ord for Datetime<'a> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(other).unwrap()
    }
}

impl<'a> fmt::Debug for Datetime<'a> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.tm().rfc3339())
    }
}

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

    #[test]
    fn test_datetime() {
        let utc = Timezone::utc();
        for &((y, m, d, h, mi, s, n), stamp) in &[
            ((1970, 1, 1, 0, 0, 0, 0), 0),
            ((1970, 1, 1, 1, 0, 0, 0), 3600),
            ((2016, 1, 1, 0, 0, 0, 0), 1451606400),
        ] {
            let stamp = time::Timespec {
                sec: stamp,
                nsec: 0,
            };
            let dt = utc.datetime(y, m, d, h, mi, s, n);
            assert_eq!(dt.stamp, stamp);
            assert_eq!(dt.is_60th_sec, false);
        }
    }

    #[test]
    fn test_tz_projection() {
        let utc = Timezone::utc();
        let seoul = Timezone::new("Asia/Seoul").unwrap();
        let new_york = Timezone::new("America/New_York").unwrap();

        let t = utc.datetime(2016, 1, 15, 20, 0, 0, 0);
        let t_seoul = t.project(&seoul);
        let t_ny = t.project(&new_york);

        assert_eq!(t.date(), (2016, 1, 15));
        assert_eq!(t.time(), (20, 0, 0, 0));
        assert_eq!(t_seoul, t);
        assert_eq!(t_seoul.date(), (2016, 1, 16));
        assert_eq!(t_seoul.time(), (5, 0, 0, 0));
        assert_eq!(t_ny, t);
        assert_eq!(t_ny.date(), (2016, 1, 15));
        assert_eq!(t_ny.time(), (15, 0, 0, 0));
    }
}
<commit_msg>Remove debugging artifacts<commit_after>//! `tzdata` uses the IANA Time Zone Database to provide conversion between timezones.
extern crate time;

mod parse;

pub use time::*;
use std::rc::Rc;
use std::io;
use std::fmt;
use std::cmp::{Eq, PartialEq, Ord, PartialOrd, Ordering};

/// A named timezone from the [`IANA Time Zone Database`](https://www.iana.org/time-zones)
///
/// # Example
///
/// ```rust
/// let utc = tzdata::Timezone::utc();
/// let now = utc.now();
///
/// for tzname in &["Europe/Paris", "America/New_York", "Asia/Seoul"] {
///     let tz = tzdata::Timezone::new(tzname).unwrap();
///     let now = now.project(&tz);
///     println!("it is now {:?} in {}", now, tz.name);
/// }
/// ```
pub struct Timezone {
    /// The timezone name e.g. `Europe/Paris`.
    pub name: String,
    /// The UTC offset transitions
    trans: Vec<Transition>,
}

#[derive(Debug)]
struct Transition {
    utc: i64,
    ttype: Rc<Type>,
}

#[derive(Debug)]
struct Type {
    utc_off_sec: i32,
    is_dst: bool,
    abbr: String,
}

impl Timezone {
    /// Try to load a new `Timezone`.
    /// It assumes that the zoneinfo data are located
    /// under `/usr/share/zoneinfo`.
    pub fn new(timezone: &str) -> io::Result<Self> {
        parse::load_timezone(timezone)
    }

    /// Load the local `Timezone` set by the system,
    /// disregarding the `TZ` environment variable.
    pub fn local() -> io::Result<Self> {
        parse::load_timezone("localtime")
    }

    /// Returns the `UTC` timezone.
    pub fn utc() -> Self {
        Self::fixed(0)
    }

    /// Returns a fixed offset to `UTC` timezone.
    /// The provided offset is in seconds.
    pub fn fixed(sec: i32) -> Self {
        Timezone {
            name: "UTC".to_owned(),
            trans: vec![
                Transition {
                    utc: std::i64::MIN,
                    ttype: Rc::new(Type {
                        utc_off_sec: sec,
                        is_dst: false,
                        abbr: "".to_owned(),
                    }),
                }
            ],
        }
    }

    /// Compute the UTC offset in this `Timezone` for unix timestamp `t`.
    fn offset(&self, stamp: i64) -> i32 {
        let idx = match self.trans.binary_search_by(|t| t.utc.cmp(&stamp)) {
            Err(0) => return 0, // FIXME?
            Err(i) => i - 1,
            Ok(i) => i,
        };

        self.trans[idx].ttype.utc_off_sec
    }

    /// Return the `Datetime` representing now, relative to this `Timezone`.
    pub fn now(&self) -> Datetime {
        Datetime {
            tz: self,
            stamp: time::get_time(),
            is_60th_sec: false,
        }
    }

    /// Create a new `Datetime` relative to this `Timezone`.
    /// Panics if the following constraints do not hold:
    ///
    /// - `month` ∊ [1, 12]
    /// - `day` ∊ [1, 31] and is valid within the month
    /// - `hour` ∊ [0, 23]
    /// - `minute` ∊ [0, 59]
    /// - `second` ∊ [0, 59]
    /// - `nano` ∊ [0, 999999999]
    pub fn datetime(&self, year: i32, month: i32, day: i32, hour: i32, minute: i32, second: i32, nano: i32) -> Datetime {
        let is_leap_year = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;

        // Panics if constaints described in documentation do not hold.
        assert!(month >= 1 && month <= 12);
        assert!(hour <= 23);
        assert!(minute <= 59);
        assert!(second <= 59); // TODO: handle leap second
        assert!(nano <= 999_999_999);
        let max_day = match month {
            1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
            4 | 6 | 9 | 11 => 30,
            2 if is_leap_year => 30,
            2 => 29,
            _ => unreachable!(),
        };
        assert!(day >= 1 && day <= max_day);

        // Let the time crate do the heavy lifting.
        let utc_dt = time::Tm {
            tm_sec: second as i32,
            tm_min: minute as i32,
            tm_hour: hour as i32,
            tm_mday: day as i32,
            tm_mon: (month - 1) as i32,
            tm_year: (year - 1900) as i32,
            tm_wday: 0,
            tm_yday: 0,
            tm_isdst: 0,
            tm_utcoff: 0,
            tm_nsec: nano as i32,
        };
        let mut stamp = utc_dt.to_timespec();
        let utc_offset = self.offset(stamp.sec);
        stamp.sec -= utc_offset as i64;

        Datetime {
            tz: self,
            stamp: stamp,
            is_60th_sec: false, // Always false because of ambiguity
        }
    }
}

/// A precise point in time along associated to a `Timezone`.
///
/// The `Datetime` cannot be created on its own as it depends on
/// a `Timezone`. `tzdata` does not expose a naive flavor of Datetime.
/// To build a `Datetime`, instanciate a `Timezone` first and call
/// the desired method.
///
/// ```rust
/// let paris = tzdata::Timezone::new("Europe/Paris").unwrap();
/// let midnight_in_paris = paris.datetime(2015, 12, 25, 0, 0, 0, 0);
///
/// let utc = tzdata::Timezone::utc();
/// let t = midnight_in_paris.project(&utc);
///
/// assert_eq!(t.date(), (2015, 12, 24));
/// assert_eq!(t.time(), (23, 0, 0, 0));
/// ```
pub struct Datetime<'a> {
    /// The associated timezone.
    tz: &'a Timezone,
    /// The offset since Unix Epoch. This is *not* the number
    /// of SI seconds since Unix Epoch because of leap seconds.
    stamp: time::Timespec,
    /// Remove ambiguous datetime on leap. When stamp
    /// corresponds to a leap second, use this field
    /// to know whether the `Datetime` corresponds to
    /// the 59th or the 60th second.
    is_60th_sec: bool,
}

impl<'a> Datetime<'a> {
    /// Project the current `Datetime` in another `Timezone`.
    pub fn project<'b>(&self, tz: &'b Timezone) -> Datetime<'b> {
        Datetime {
            tz: tz,
            stamp: self.stamp,
            is_60th_sec: self.is_60th_sec,
        }
    }

    /// Return the tm in the associated `Timezone`.
    fn tm(&self) -> time::Tm {
        let offset = self.tz.offset(self.stamp.sec);
        let local = time::Timespec {
            sec: self.stamp.sec + offset as i64,
            nsec: self.stamp.nsec,
        };
        let mut tm = time::at_utc(local);
        tm.tm_utcoff = offset;
        tm
    }

    /// Return the date component of the `Datetime` expressed
    /// in the associated `Timezone`. The tuple holds the
    /// year, month and day in this order.
    pub fn date(&self) -> (i32, i32, i32) {
        let tm = self.tm();
        (tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday)
    }

    /// Return the time component of the `Datetime` expressed
    /// in the associated `Timezone`. The tuple holds
    /// the hour, minute, second and nanosecond in this order.
    pub fn time(&self) -> (i32, i32, i32, i32) {
        let tm = self.tm();
        (tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_nsec)
    }
}

impl<'a> PartialEq<Datetime<'a>> for Datetime<'a> {
    fn eq(&self, other: &Datetime) -> bool {
        self.stamp.eq(&other.stamp)
    }
}

impl<'a> Eq for Datetime<'a> {}

impl<'a> PartialOrd<Datetime<'a>> for Datetime<'a> {
    fn partial_cmp(&self, other: &Datetime) -> Option<Ordering> {
        let cmp = self.stamp.cmp(&other.stamp);
        if let Ordering::Equal = cmp {
            Some(self.is_60th_sec.cmp(&other.is_60th_sec))
        } else {
            Some(cmp)
        }
    }
}

impl<'a> Ord for Datetime<'a> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(other).unwrap()
    }
}

impl<'a> fmt::Debug for Datetime<'a> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.tm().rfc3339())
    }
}

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

    #[test]
    fn test_datetime() {
        let utc = Timezone::utc();
        for &((y, m, d, h, mi, s, n), stamp) in &[
            ((1970, 1, 1, 0, 0, 0, 0), 0),
            ((1970, 1, 1, 1, 0, 0, 0), 3600),
            ((2016, 1, 1, 0, 0, 0, 0), 1451606400),
        ] {
            let stamp = time::Timespec {
                sec: stamp,
                nsec: 0,
            };
            let dt = utc.datetime(y, m, d, h, mi, s, n);
            assert_eq!(dt.stamp, stamp);
            assert_eq!(dt.is_60th_sec, false);
        }
    }

    #[test]
    fn test_tz_projection() {
        let utc = Timezone::utc();
        let seoul = Timezone::new("Asia/Seoul").unwrap();
        let new_york = Timezone::new("America/New_York").unwrap();

        let t = utc.datetime(2016, 1, 15, 20, 0, 0, 0);
        let t_seoul = t.project(&seoul);
        let t_ny = t.project(&new_york);

        assert_eq!(t.date(), (2016, 1, 15));
        assert_eq!(t.time(), (20, 0, 0, 0));
        assert_eq!(t_seoul, t);
        assert_eq!(t_seoul.date(), (2016, 1, 16));
        assert_eq!(t_seoul.time(), (5, 0, 0, 0));
        assert_eq!(t_ny, t);
        assert_eq!(t_ny.date(), (2016, 1, 15));
        assert_eq!(t_ny.time(), (15, 0, 0, 0));
    }
}
<|endoftext|>


<commit_before>//! Provides token definitions for HTML stream processing. The goal of this
//! library is to provide a simple API over which higher abstraction can be
//! built on.
//!
//! ## Example
//!
//! ```rust
//! #[macro_use]
//! extern crate hamlet;
//!
//! use std::fmt::Write;
//!
//! fn main() {
//!     use hamlet::Token;
//!     let tokens = vec![
//!         Token::text("Hello, "),
//!         Token::start_tag("small", attrs!(class="foo")),
//!         Token::text("world!"),
//!         Token::end_tag("small"),
//!     ];
//!
//!     let mut html = String::from("");
//!     for token in tokens {
//!         write!(html, "{}", token);
//!     }
//!
//!     assert_eq!(html, "Hello, <small class=\"foo\">world!</small>");
//! }
//! ```

pub mod util;

#[macro_use]
mod macros;

pub mod attr;
mod escape;
mod token;

pub use token::Token;
<commit_msg>Enable missing documentation warning<commit_after>//! Provides token definitions for HTML stream processing. The goal of this
//! library is to provide a simple API over which higher abstraction can be
//! built on.
//!
//! ## Example
//!
//! ```rust
//! #[macro_use]
//! extern crate hamlet;
//!
//! use std::fmt::Write;
//!
//! fn main() {
//!     use hamlet::Token;
//!     let tokens = vec![
//!         Token::text("Hello, "),
//!         Token::start_tag("small", attrs!(class="foo")),
//!         Token::text("world!"),
//!         Token::end_tag("small"),
//!     ];
//!
//!     let mut html = String::from("");
//!     for token in tokens {
//!         write!(html, "{}", token);
//!     }
//!
//!     assert_eq!(html, "Hello, <small class=\"foo\">world!</small>");
//! }
//! ```

#![warn(missing_docs)]

pub mod util;

#[macro_use]
mod macros;

pub mod attr;
mod escape;
mod token;

pub use token::Token;
<|endoftext|>