<commit_before>//! This crate provide type for counting mutable borrow of a value. The `Bc<T>`
//! type is a small wrapper on top of a value of type `T` which count the number
//! of time the value has been mutably borrowed since it's creation.
//!
//! # Why?
//!
//! If you want to cache an expensive computation result, you need to have
//! information about wether the parameters of the computation have changed or
//! not. You can use a hash for that, but this have two shortcomings:
//!
//!  * You need to have values which implement the `Hash` trait. Some useful
//!    types like `f64` do not;
//!  * You need to have a cheap way to compute the hash.
//!
//! If computing the hash is harder or more expensive than doing the
//! computation, you are doomed. Or you can use `Bc<T>` which will give you
//! information about the number of borrow since the last computation. If this
//! number have changed, then it is very likely that the value have changed,
//! and that you need to redo your computation.
//!
//! # Limitations
//!
//! This can not be used a real hash algorithm, because the number of borrow can
//! change even if the value do not.
//!
//! If more than `usize::MAX` borrow occurs, the borrow counter will be wrapped
//! around to 0, and will not `panic` because of the overflow.
//!
//! # Performances
//!
//! The `Bc` type do not introduce notable overhead when borrowing. Here are the
//! benchmark results comparing a raw value and a borrow counted value:
//!
//! ```text
//! running 2 tests
//!    test counted ... bench:       1,061 ns/iter (+/- 12)
//!    test raw     ... bench:       1,059 ns/iter (+/- 16)
//! ```
//!
//! Using the number of borrow as hash value is way faster than doing the real
//! hash. Here is a benchmark for `[usize; 10000]` values:
//!
//! ```text
//! running 2 tests
//!    test counted ... bench:          22 ns/iter (+/- 1)
//!    test raw     ... bench:      49,011 ns/iter (+/- 755)
//! ```
//!
//! You can see the code for these benchmarks on [Github](https://github.com/Luthaf/bcount/tree/master/benches).
//!
//! # Example
//!
//! ```rust
//! extern crate bcount;
//! use bcount::Bc;
//!
//! fn main() {
//!     let mut a = Bc::new(vec![63, 67, 42]);
//!     assert_eq!(a.count(), 0);
//!
//!     do_work(&mut a);
//!     do_work(&mut a);
//!     do_work(&mut a);
//!     do_work(&mut a);
//!
//!     assert_eq!(a.count(), 4);
//!
//!     *a = vec![3, 4, 5];
//!     assert_eq!(a.count(), 5);
//! }
//!
//! fn do_work(_: &mut [usize]) {
//!     // Whatever, nobody cares
//! }
//!
//! ```
//!
//! # Caveats:
//!
//! This only count direct mutable borrow, nothing else. This means that
//! multiple borrow are only counted once. In this code, a call to
//! `borrow_me_twice` will only augment the borrow count by one.
//!
//! ```rust
//! fn borrow_me(reference: &mut T) {
//!     // Do work
//! }
//!
//! fn borrow_me_twice(reference: &mut T) {
//!     // Do work
//!     borrow_me(reference)
//! }
//! ```
//!
//! Also, `Cell` and `RefCell` allow programmers to separate mutability from
//! mutable references, so with `Bc<Cell<T>>` the borrow count will never
//! change, even if the internal `T` is modified.

// TODO? Mbc (Mutable Borrow counter) & Cbc (*const* borrow counter) & Bc (*all* borrow counter)

#![deny(missing_docs)]
use std::ops::{Deref, DerefMut};

/// The borrow counter struct for type `T`.
pub struct Bc<T> {
    counter: usize,
    val: T
}

impl<T> Bc<T> {
    /// Create a new `Bc<T>` containing the value `val`.
    pub fn new(val: T) -> Bc<T> {
        Bc {
            val: val,
            counter: 0,
        }
    }

    /// Reset the borrow counter
    pub fn reset(&mut self) {
        self.counter = 0;
    }

    /// Get the number of time this structure has been mutably borrowed.
    pub fn count(&self) -> usize {
        self.counter
    }
}

impl<T> Deref for Bc<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.val
    }
}

impl<T> DerefMut for Bc<T> {
     fn deref_mut(&mut self) -> &mut T {
         self.counter = self.counter.wrapping_add(1);
         &mut self.val
     }
}

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

    fn do_nothing(_: &mut f64) {}

    #[test]
    fn count() {
        let mut a = Bc::new(5.0);
        assert_eq!(a.count(), 0);

        *a = 89.0;
        assert_eq!(a.count(), 1);

        do_nothing(&mut a);
        assert_eq!(a.count(), 2);
    }

    #[test]
    fn reset() {
        let mut a = Bc::new(3);

        assert_eq!(a.count(), 0);

        *a = 18;
        *a = 42;
        assert_eq!(a.count(), 2);

        a.reset();
        assert_eq!(a.count(), 0);
    }

    #[test]
    fn overflow() {
        let mut a = Bc::new(3);
        a.counter = usize::MAX - 1;

        *a = 18;
        *a = 18;
        assert_eq!(a.count(), 0);
    }

    #[test]
    fn non_mutable() {
        fn observe(_: &f64) {/* Do nothing */}

        let a = Bc::new(3.0);
        assert_eq!(a.count(), 0);

        observe(&a);
        observe(&a);
        observe(&a);
        assert_eq!(a.count(), 0);
    }
}
<commit_msg>Fix doctests<commit_after>//! This crate provide type for counting mutable borrow of a value. The `Bc<T>`
//! type is a small wrapper on top of a value of type `T` which count the number
//! of time the value has been mutably borrowed since it's creation.
//!
//! # Why?
//!
//! If you want to cache an expensive computation result, you need to have
//! information about wether the parameters of the computation have changed or
//! not. You can use a hash for that, but this have two shortcomings:
//!
//!  * You need to have values which implement the `Hash` trait. Some useful
//!    types like `f64` do not;
//!  * You need to have a cheap way to compute the hash.
//!
//! If computing the hash is harder or more expensive than doing the
//! computation, you are doomed. Or you can use `Bc<T>` which will give you
//! information about the number of borrow since the last computation. If this
//! number have changed, then it is very likely that the value have changed,
//! and that you need to redo your computation.
//!
//! # Limitations
//!
//! This can not be used a real hash algorithm, because the number of borrow can
//! change even if the value do not.
//!
//! If more than `usize::MAX` borrow occurs, the borrow counter will be wrapped
//! around to 0, and will not `panic` because of the overflow.
//!
//! # Performances
//!
//! The `Bc` type do not introduce notable overhead when borrowing. Here are the
//! benchmark results comparing a raw value and a borrow counted value:
//!
//! ```text
//! running 2 tests
//!    test counted ... bench:       1,061 ns/iter (+/- 12)
//!    test raw     ... bench:       1,059 ns/iter (+/- 16)
//! ```
//!
//! Using the number of borrow as hash value is way faster than doing the real
//! hash. Here is a benchmark for `[usize; 10000]` values:
//!
//! ```text
//! running 2 tests
//!    test counted ... bench:          22 ns/iter (+/- 1)
//!    test raw     ... bench:      49,011 ns/iter (+/- 755)
//! ```
//!
//! You can see the code for these benchmarks on [Github](https://github.com/Luthaf/bcount/tree/master/benches).
//!
//! # Example
//!
//! ```rust
//! extern crate bcount;
//! use bcount::Bc;
//!
//! fn main() {
//!     let mut a = Bc::new(vec![63, 67, 42]);
//!     assert_eq!(a.count(), 0);
//!
//!     do_work(&mut a);
//!     do_work(&mut a);
//!     do_work(&mut a);
//!     do_work(&mut a);
//!
//!     assert_eq!(a.count(), 4);
//!
//!     *a = vec![3, 4, 5];
//!     assert_eq!(a.count(), 5);
//! }
//!
//! fn do_work(_: &mut [usize]) {
//!     // Whatever, nobody cares
//! }
//!
//! ```
//!
//! # Caveats:
//!
//! This only count direct mutable borrow, nothing else. This means that
//! multiple borrow are only counted once. In this code, a call to
//! `borrow_me_twice` will only augment the borrow count by one.
//!
//! ```text
//! fn borrow_me(reference: &mut T) {
//!     // Do work
//! }
//!
//! fn borrow_me_twice(reference: &mut T) {
//!     // Do work
//!     borrow_me(reference)
//! }
//! ```
//!
//! Also, `Cell` and `RefCell` allow programmers to separate mutability from
//! mutable references, so with `Bc<Cell<T>>` the borrow count will never
//! change, even if the internal `T` is modified.

// TODO? Mbc (Mutable Borrow counter) & Cbc (*const* borrow counter) & Bc (*all* borrow counter)

#![deny(missing_docs)]
use std::ops::{Deref, DerefMut};

/// The borrow counter struct for type `T`.
pub struct Bc<T> {
    counter: usize,
    val: T
}

impl<T> Bc<T> {
    /// Create a new `Bc<T>` containing the value `val`.
    pub fn new(val: T) -> Bc<T> {
        Bc {
            val: val,
            counter: 0,
        }
    }

    /// Reset the borrow counter
    pub fn reset(&mut self) {
        self.counter = 0;
    }

    /// Get the number of time this structure has been mutably borrowed.
    pub fn count(&self) -> usize {
        self.counter
    }
}

impl<T> Deref for Bc<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.val
    }
}

impl<T> DerefMut for Bc<T> {
     fn deref_mut(&mut self) -> &mut T {
         self.counter = self.counter.wrapping_add(1);
         &mut self.val
     }
}

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

    fn do_nothing(_: &mut f64) {}

    #[test]
    fn count() {
        let mut a = Bc::new(5.0);
        assert_eq!(a.count(), 0);

        *a = 89.0;
        assert_eq!(a.count(), 1);

        do_nothing(&mut a);
        assert_eq!(a.count(), 2);
    }

    #[test]
    fn reset() {
        let mut a = Bc::new(3);

        assert_eq!(a.count(), 0);

        *a = 18;
        *a = 42;
        assert_eq!(a.count(), 2);

        a.reset();
        assert_eq!(a.count(), 0);
    }

    #[test]
    fn overflow() {
        let mut a = Bc::new(3);
        a.counter = usize::MAX - 1;

        *a = 18;
        *a = 18;
        assert_eq!(a.count(), 0);
    }

    #[test]
    fn non_mutable() {
        fn observe(_: &f64) {/* Do nothing */}

        let a = Bc::new(3.0);
        assert_eq!(a.count(), 0);

        observe(&a);
        observe(&a);
        observe(&a);
        assert_eq!(a.count(), 0);
    }
}
<|endoftext|>


<commit_before>//! Rsync-like library/program.
//!
//! Rrsync is intended to provide the functionality of rsync ("live" transfer
//! of files/directories over SSH), rdiff (creation of binary patches between
//! files, for later application), and zsync (efficient synchronization of
//! files or file trees from a central "dumb" HTTP server). It also has some
//! additions such as caching file signatures to make repeated synchronizations
//! faster.

extern crate cdchunking;
extern crate chrono;
#[macro_use] extern crate log;
extern crate rusqlite;
extern crate sha1;
#[cfg(test)] extern crate tempfile;

mod index;

use rusqlite::types::{ToSql, ToSqlOutput};
use std::fmt;
use std::io::Write;

pub use index::{Index, IndexTransaction};

/// General error type for this library
#[derive(Debug)]
pub enum Error {
    Io(std::io::Error),
    Sqlite(rusqlite::Error),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Error::Sqlite(e) => write!(f, "SQLite error: {}", e),
            Error::Io(e) => write!(f, "I/O error: {}", e),
        }
    }
}

impl std::error::Error for Error {}

impl From<rusqlite::Error> for Error {
    fn from(e: rusqlite::Error) -> Error {
        Error::Sqlite(e)
    }
}

impl From<std::io::Error> for Error {
    fn from(e: std::io::Error) -> Error {
        Error::Io(e)
    }
}

/// Type for the hashes
#[derive(Debug, PartialEq, Eq)]
pub struct HashDigest([u8; 20]);

impl ToSql for HashDigest {
    fn to_sql(&self) -> Result<ToSqlOutput, rusqlite::Error> {
        // Write the hash to buffer on the stack, we know the size
        let mut buffer = Vec::with_capacity(40);
        for byte in &self.0 {
            write!(&mut buffer, "{:02x}", byte).unwrap();
        }
        // Hexadecimal chars are ASCII, cast to string
        let string = String::from_utf8(buffer).unwrap();

        Ok(ToSqlOutput::from(string))
    }
}

impl fmt::Display for HashDigest {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for byte in &self.0 {
            write!(f, "{:02x}", byte)?;
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use rusqlite::types::{ToSql, ToSqlOutput, Value};
    use sha1::Sha1;

    use super::HashDigest;

    #[test]
    fn test_hash_tosql() {
        let mut sha1 = Sha1::new();
        sha1.update(b"test");
        let digest = HashDigest(sha1.digest().bytes());
        assert_eq!(
            digest.to_sql().unwrap(),
            ToSqlOutput::Owned(
                Value::Text("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3".into())
            ),
        );
    }
}
<commit_msg>Implement FromSql for HashDigest<commit_after>//! Rsync-like library/program.
//!
//! Rrsync is intended to provide the functionality of rsync ("live" transfer
//! of files/directories over SSH), rdiff (creation of binary patches between
//! files, for later application), and zsync (efficient synchronization of
//! files or file trees from a central "dumb" HTTP server). It also has some
//! additions such as caching file signatures to make repeated synchronizations
//! faster.

extern crate cdchunking;
extern crate chrono;
#[macro_use] extern crate log;
extern crate rusqlite;
extern crate sha1;
#[cfg(test)] extern crate tempfile;

mod index;

use rusqlite::types::{FromSql, FromSqlError, ToSql, ToSqlOutput};
use std::fmt;
use std::io::Write;

pub use index::{Index, IndexTransaction};

/// General error type for this library
#[derive(Debug)]
pub enum Error {
    Io(std::io::Error),
    Sqlite(rusqlite::Error),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Error::Sqlite(e) => write!(f, "SQLite error: {}", e),
            Error::Io(e) => write!(f, "I/O error: {}", e),
        }
    }
}

impl std::error::Error for Error {}

impl From<rusqlite::Error> for Error {
    fn from(e: rusqlite::Error) -> Error {
        Error::Sqlite(e)
    }
}

impl From<std::io::Error> for Error {
    fn from(e: std::io::Error) -> Error {
        Error::Io(e)
    }
}

/// Type for the hashes
#[derive(Debug, PartialEq, Eq)]
pub struct HashDigest([u8; 20]);

impl ToSql for HashDigest {
    fn to_sql(&self) -> Result<ToSqlOutput, rusqlite::Error> {
        // Write the hash to buffer on the stack, we know the size
        let mut buffer = Vec::with_capacity(40);
        for byte in &self.0 {
            write!(&mut buffer, "{:02x}", byte).unwrap();
        }
        // Hexadecimal chars are ASCII, cast to string
        let string = String::from_utf8(buffer).unwrap();

        Ok(ToSqlOutput::from(string))
    }
}

#[derive(Debug)]
enum InvalidHashDigest {
    WrongSize,
    InvalidChar,
}

impl fmt::Display for InvalidHashDigest {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            InvalidHashDigest::WrongSize => {
                write!(f, "Invalid hash: wrong size")
            }
            InvalidHashDigest::InvalidChar => {
                write!(f, "Invalid hash: invalid character")
            }
        }
    }
}

impl std::error::Error for InvalidHashDigest {}

impl FromSql for HashDigest {
    fn column_result(
        value: rusqlite::types::ValueRef,
    ) -> Result<HashDigest, FromSqlError>
    {
        value
            .as_str()
            .and_then(|s| {
                if s.len() != 40 {
                    Err(FromSqlError::Other(Box::new(
                        InvalidHashDigest::WrongSize
                    )))
                } else {
                    let mut bytes = [0u8; 20];
                    for (i, byte) in (&mut bytes).iter_mut().enumerate() {
                        *byte = u8::from_str_radix(&s[i*2 .. i*2 + 2], 16)
                            .map_err(|_| FromSqlError::Other(Box::new(
                                InvalidHashDigest::InvalidChar
                            )))?;
                    }
                    Ok(HashDigest(bytes))
                }
            })
    }
}

impl fmt::Display for HashDigest {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for byte in &self.0 {
            write!(f, "{:02x}", byte)?;
        }
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use rusqlite::types::{FromSql, ToSql, ToSqlOutput, Value, ValueRef};
    use sha1::Sha1;

    use super::HashDigest;

    #[test]
    fn test_hash_tosql() {
        let mut sha1 = Sha1::new();
        sha1.update(b"test");
        let digest = HashDigest(sha1.digest().bytes());
        assert_eq!(
            digest.to_sql().unwrap(),
            ToSqlOutput::Owned(
                Value::Text("a94a8fe5ccb19ba61c4c0873d391e987982fbbd3".into())
            ),
        );
    }

    #[test]
    fn test_hash_fromsql() {
        let mut sha1 = Sha1::new();
        sha1.update(b"test");
        let digest = HashDigest(sha1.digest().bytes());

        let hash = <HashDigest as FromSql>::column_result(ValueRef::Text(
            "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"
        ));
        assert_eq!(
            hash.unwrap(),
            digest,
        );
    }
}
<|endoftext|>


<commit_before>extern crate byteorder;
#[cfg(feature = "enable_logging")]
#[macro_use]
extern crate log;
extern crate crc;

#[macro_use]
mod macros;

mod decode;
mod encode;
pub mod error;

use crate::decode::lzbuffer::LZBuffer;
use std::io;

pub mod compress {
    pub use crate::encode::options::*;
}

pub mod decompress {
    pub use crate::decode::options::*;
}

/// Decompress LZMA data with default [`Options`](decompress/struct.Options.html).
pub fn lzma_decompress<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
) -> error::Result<()> {
    lzma_decompress_with_options(input, output, &decompress::Options::default())
}

/// Decompress LZMA data with the provided options.
pub fn lzma_decompress_with_options<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
    options: &decompress::Options,
) -> error::Result<()> {
    let params = decode::lzma::LZMAParams::read_header(input, options)?;
    let mut decoder = decode::lzma::new_circular(output, params)?;
    let mut rangecoder = decode::rangecoder::RangeDecoder::new(input).or_else(|e| {
        Err(error::Error::LZMAError(format!(
            "LZMA stream too short: {}",
            e
        )))
    })?;
    decoder.process(&mut rangecoder)?;
    decoder.output.finish()?;
    Ok(())
}

/// Compresses the data with default [`Options`](compress/struct.Options.html).
pub fn lzma_compress<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
) -> io::Result<()> {
    lzma_compress_with_options(input, output, &compress::Options::default())
}

pub fn lzma_compress_with_options<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
    options: &compress::Options,
) -> io::Result<()> {
    let encoder = encode::dumbencoder::Encoder::from_stream(output, options)?;
    encoder.process(input)
}

pub fn lzma2_decompress<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
) -> error::Result<()> {
    decode::lzma2::decode_stream(input, output)
}

pub fn lzma2_compress<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
) -> io::Result<()> {
    encode::lzma2::encode_stream(input, output)
}

pub fn xz_decompress<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
) -> error::Result<()> {
    decode::xz::decode_stream(input, output)
}

pub fn xz_compress<R: io::BufRead, W: io::Write>(input: &mut R, output: &mut W) -> io::Result<()> {
    encode::xz::encode_stream(input, output)
}
<commit_msg>Add '#![forbid(unsafe_code)]' which turns `unsafe` blocks into compile-time errors<commit_after>#![forbid(unsafe_code)]

extern crate byteorder;
#[cfg(feature = "enable_logging")]
#[macro_use]
extern crate log;
extern crate crc;

#[macro_use]
mod macros;

mod decode;
mod encode;
pub mod error;

use crate::decode::lzbuffer::LZBuffer;
use std::io;

pub mod compress {
    pub use crate::encode::options::*;
}

pub mod decompress {
    pub use crate::decode::options::*;
}

/// Decompress LZMA data with default [`Options`](decompress/struct.Options.html).
pub fn lzma_decompress<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
) -> error::Result<()> {
    lzma_decompress_with_options(input, output, &decompress::Options::default())
}

/// Decompress LZMA data with the provided options.
pub fn lzma_decompress_with_options<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
    options: &decompress::Options,
) -> error::Result<()> {
    let params = decode::lzma::LZMAParams::read_header(input, options)?;
    let mut decoder = decode::lzma::new_circular(output, params)?;
    let mut rangecoder = decode::rangecoder::RangeDecoder::new(input).or_else(|e| {
        Err(error::Error::LZMAError(format!(
            "LZMA stream too short: {}",
            e
        )))
    })?;
    decoder.process(&mut rangecoder)?;
    decoder.output.finish()?;
    Ok(())
}

/// Compresses the data with default [`Options`](compress/struct.Options.html).
pub fn lzma_compress<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
) -> io::Result<()> {
    lzma_compress_with_options(input, output, &compress::Options::default())
}

pub fn lzma_compress_with_options<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
    options: &compress::Options,
) -> io::Result<()> {
    let encoder = encode::dumbencoder::Encoder::from_stream(output, options)?;
    encoder.process(input)
}

pub fn lzma2_decompress<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
) -> error::Result<()> {
    decode::lzma2::decode_stream(input, output)
}

pub fn lzma2_compress<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
) -> io::Result<()> {
    encode::lzma2::encode_stream(input, output)
}

pub fn xz_decompress<R: io::BufRead, W: io::Write>(
    input: &mut R,
    output: &mut W,
) -> error::Result<()> {
    decode::xz::decode_stream(input, output)
}

pub fn xz_compress<R: io::BufRead, W: io::Write>(input: &mut R, output: &mut W) -> io::Result<()> {
    encode::xz::encode_stream(input, output)
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! A SDL2 window back-end for the Piston game engine.

extern crate sdl2;
extern crate window;
extern crate input;
extern crate shader_version;
extern crate gl;

// External crates.
use window::{
    OpenGLWindow,
    ProcAddress,
    Window,
    AdvancedWindow,
    WindowSettings,
    Size,
};
use input::{ keyboard, Button, MouseButton, Input, Motion };

pub use shader_version::OpenGL;

/// A widow implemented by SDL2 back-end.
pub struct Sdl2Window {
    /// SDL window handle.
    pub window: sdl2::video::Window,
    /// Allow dead code because this keeps track of the OpenGL context.
    /// Will be released on drop.
    #[allow(dead_code)]
    pub context: sdl2::video::GLContext,
    /// SDL context.
    pub sdl_context: sdl2::Sdl,
    /// Video subsystem.
    pub video_subsystem: sdl2::VideoSubsystem,
    should_close: bool,
    mouse_relative: Option<(f64, f64)>,
    exit_on_esc: bool,
    title: String,
    size: Size,
    draw_size: Size,
}

impl Sdl2Window {
    /// Creates a new game window for SDL2. This will initialize SDL and the video subsystem.
    /// You can retrieve both via the public fields on the `Sdl2Window` struct.
    pub fn new(settings: WindowSettings) -> Self {
        let sdl = sdl2::init().unwrap();
        let video_subsystem = sdl.video().unwrap();
        Self::with_subsystem(video_subsystem, settings)
    }

    /// Creates a window with the supplied SDL Video subsystem.
    pub fn with_subsystem(video_subsystem: sdl2::VideoSubsystem, settings: WindowSettings) -> Self {
        use sdl2::video::GLProfile;

        let sdl_context = video_subsystem.sdl();

        let opengl = settings.get_maybe_opengl().unwrap_or(OpenGL::V3_2);
        let (major, minor) = opengl.get_major_minor();

        {
            let gl_attr = video_subsystem.gl_attr();

            // Not all drivers default to 32bit color, so explicitly set it to 32bit color.
            gl_attr.set_red_size(8);
            gl_attr.set_green_size(8);
            gl_attr.set_blue_size(8);
            gl_attr.set_alpha_size(8);
            gl_attr.set_stencil_size(8);
            gl_attr.set_context_version(major as u8, minor as u8);
        }

        if opengl >= OpenGL::V3_2 {
            video_subsystem.gl_attr().set_context_profile(GLProfile::Core);
        }
        if settings.get_samples() != 0 {
            let gl_attr = video_subsystem.gl_attr();
            gl_attr.set_multisample_buffers(1);
            gl_attr.set_multisample_samples(settings.get_samples());
        }

        let mut window_builder = video_subsystem.window(
            &settings.get_title(),
            settings.get_size().width as u32,
            settings.get_size().height as u32
        );

        let window_builder = window_builder.position_centered()
            .opengl()
            .resizable();

        let window_builder = if settings.get_fullscreen() {
            window_builder.fullscreen()
        } else {
            window_builder
        };

        let window = window_builder.build();

        let window = match window {
            Ok(w) => w,
            Err(_) =>
                if settings.get_samples() != 0 {
                    // Retry without requiring anti-aliasing.
                    let gl_attr = video_subsystem.gl_attr();
                    gl_attr.set_multisample_buffers(0);
                    gl_attr.set_multisample_samples(0);
                    window_builder.build().unwrap()
                } else {
                    window.unwrap() // Panic.
                }
        };

        // Send text input events.
        video_subsystem.text_input().start();

        let context = window.gl_create_context().unwrap();

        // Load the OpenGL function pointers.
        gl::load_with(|name| video_subsystem.gl_get_proc_address(name));

        if settings.get_vsync() {
            video_subsystem.gl_set_swap_interval(1);
        } else {
            video_subsystem.gl_set_swap_interval(0);
        }

        let mut window = Sdl2Window {
            exit_on_esc: settings.get_exit_on_esc(),
            should_close: false,
            window: window,
            context: context,
            sdl_context: sdl_context,
            video_subsystem: video_subsystem,
            mouse_relative: None,
            title: settings.get_title() ,
            size: settings.get_size(),
            draw_size: settings.get_size(),
        };
        window.update_draw_size();
        window
    }

    fn update_draw_size(&mut self) {
        let (w, h) = self.window.get_drawable_size();
        self.draw_size = Size { width: w as u32, height: h as u32 };
    }

    fn poll_event(&mut self) -> Option<Input> {
        // First check for a pending relative mouse move event.
        if let Some((x, y)) = self.mouse_relative {
            self.mouse_relative = None;
            return Some(Input::Move(Motion::MouseRelative(x, y)));
        }

        // Even though we create a new EventPump each time we poll an event
        // this should not be a problem since it only contains phantom data
        // and therefore should actually not have any overhead.
        let event = match self.sdl_context.event_pump().unwrap().poll_event() {
            Some( ev ) => ev,
            None => return None
        };
        match event {
            sdl2::event::Event::Quit{..} => {
                self.should_close = true;
            }
            sdl2::event::Event::TextInput { text, .. } => {
                return Some(Input::Text(text));
            }
            sdl2::event::Event::KeyDown { keycode: Some(key), repeat, ..} => {
                // SDL2 repeats the key down event.
                // If the event is the same as last one, ignore it.
                if repeat {
                    return self.poll_event()
                }

                if self.exit_on_esc
                && key == sdl2::keyboard::Keycode::Escape {
                    self.should_close = true;
                } else {
                    return Some(Input::Press(Button::Keyboard(sdl2_map_key(key))));
                }
            }
            sdl2::event::Event::KeyUp { keycode: Some(key), repeat, .. } => {
                if repeat {
                    return self.poll_event()
                }
                return Some(Input::Release(Button::Keyboard(sdl2_map_key(key))));
            }
            sdl2::event::Event::MouseButtonDown { mouse_btn: button, .. } => {
                return Some(Input::Press(Button::Mouse(sdl2_map_mouse(button))));
            }
            sdl2::event::Event::MouseButtonUp { mouse_btn: button, .. } => {
                return Some(Input::Release(Button::Mouse(sdl2_map_mouse(button))));
            }
            sdl2::event::Event::MouseMotion { x, y, xrel: dx, yrel: dy, .. } => {
                // Send relative move movement next time.
                self.mouse_relative = Some((dx as f64, dy as f64));
                return Some(Input::Move(Motion::MouseCursor(x as f64, y as f64)));
            },
            sdl2::event::Event::MouseWheel { x, y, .. } => {
                return Some(Input::Move(Motion::MouseScroll(x as f64, y as f64)));
            }
            sdl2::event::Event::Window {
                win_event_id: sdl2::event::WindowEventId::Resized, data1: w, data2: h, .. } => {
                self.size.width = w as u32;
                self.size.height = h as u32;
                self.update_draw_size();
                return Some(Input::Resize(w as u32, h as u32));
            }
            sdl2::event::Event::Window { win_event_id: sdl2::event::WindowEventId::FocusGained, .. } => {
                return Some(Input::Focus(true));
            }
            sdl2::event::Event::Window { win_event_id: sdl2::event::WindowEventId::FocusLost, .. } => {
                return Some(Input::Focus(false));
            }
            _ => {}
        }
        None
    }
}

impl From<WindowSettings> for Sdl2Window {
    fn from(settings: WindowSettings) -> Sdl2Window {
        Sdl2Window::new(settings)
    }
}

impl Drop for Sdl2Window {
    fn drop(&mut self) {
        self.set_capture_cursor(false);
    }
}

impl Window for Sdl2Window {
    type Event = Input;

    fn should_close(&self) -> bool { self.should_close }
    fn set_should_close(&mut self, value: bool) { self.should_close = value; }
    fn swap_buffers(&mut self) { self.window.gl_swap_window(); }
    fn size(&self) -> Size { self.size }
    fn poll_event(&mut self) -> Option<Input> { self.poll_event() }
    fn draw_size(&self) -> Size { self.draw_size }
}

impl AdvancedWindow for Sdl2Window {
    fn get_title(&self) -> String {
        self.title.clone()
    }
    fn set_title(&mut self, value: String) {
        let _ = self.window.set_title(&value);
        self.title = value
    }
    fn get_exit_on_esc(&self) -> bool { self.exit_on_esc }
    fn set_exit_on_esc(&mut self, value: bool) { self.exit_on_esc = value; }
    fn set_capture_cursor(&mut self, value: bool) {
        self.sdl_context.mouse().set_relative_mouse_mode(value);
    }
}

impl OpenGLWindow for Sdl2Window {
    fn get_proc_address(&mut self, proc_name: &str) -> ProcAddress {
        self.video_subsystem.gl_get_proc_address(proc_name)
    }

    fn is_current(&self) -> bool {
        self.context.is_current()
    }

    fn make_current(&mut self) {
        self.window.gl_make_current(&self.context).unwrap();
    }
}

/// Maps a SDL2 key to piston-input key.
pub fn sdl2_map_key(keycode: sdl2::keyboard::Keycode) -> keyboard::Key {
    (keycode as u32).into()
}

/// Maps a SDL2 mouse button to piston-input button.
pub fn sdl2_map_mouse(button: sdl2::mouse::Mouse) -> MouseButton {
    match button {
        sdl2::mouse::Mouse::Left => MouseButton::Left,
        sdl2::mouse::Mouse::Right => MouseButton::Right,
        sdl2::mouse::Mouse::Middle => MouseButton::Middle,
        sdl2::mouse::Mouse::X1 => MouseButton::X1,
        sdl2::mouse::Mouse::X2 => MouseButton::X2,
        sdl2::mouse::Mouse::Unknown(_) => MouseButton::Unknown,
    }
}
<commit_msg>Use Result rather than panicking.<commit_after>#![deny(missing_docs)]

//! A SDL2 window back-end for the Piston game engine.

extern crate sdl2;
extern crate window;
extern crate input;
extern crate shader_version;
extern crate gl;

// External crates.
use window::{
    OpenGLWindow,
    ProcAddress,
    Window,
    AdvancedWindow,
    WindowSettings,
    Size,
};
use input::{ keyboard, Button, MouseButton, Input, Motion };

pub use shader_version::OpenGL;

/// A widow implemented by SDL2 back-end.
pub struct Sdl2Window {
    /// SDL window handle.
    pub window: sdl2::video::Window,
    /// Allow dead code because this keeps track of the OpenGL context.
    /// Will be released on drop.
    #[allow(dead_code)]
    pub context: sdl2::video::GLContext,
    /// SDL context.
    pub sdl_context: sdl2::Sdl,
    /// Video subsystem.
    pub video_subsystem: sdl2::VideoSubsystem,
    should_close: bool,
    mouse_relative: Option<(f64, f64)>,
    exit_on_esc: bool,
    title: String,
    size: Size,
    draw_size: Size,
}

impl Sdl2Window {
    /// Creates a new game window for SDL2. This will initialize SDL and the video subsystem.
    /// You can retrieve both via the public fields on the `Sdl2Window` struct.
    pub fn new(settings: WindowSettings) -> Result<Self, String> {
        let sdl = try!(sdl2::init());
        let video_subsystem = try!(sdl.video());
        Self::with_subsystem(video_subsystem, settings)
    }

    /// Creates a window with the supplied SDL Video subsystem.
    pub fn with_subsystem(video_subsystem: sdl2::VideoSubsystem, settings: WindowSettings) -> Result<Self, String> {
        use sdl2::video::GLProfile;

        let sdl_context = video_subsystem.sdl();

        let opengl = settings.get_maybe_opengl().unwrap_or(OpenGL::V3_2);
        let (major, minor) = opengl.get_major_minor();

        {
            let gl_attr = video_subsystem.gl_attr();

            // Not all drivers default to 32bit color, so explicitly set it to 32bit color.
            gl_attr.set_red_size(8);
            gl_attr.set_green_size(8);
            gl_attr.set_blue_size(8);
            gl_attr.set_alpha_size(8);
            gl_attr.set_stencil_size(8);
            gl_attr.set_context_version(major as u8, minor as u8);
        }

        if opengl >= OpenGL::V3_2 {
            video_subsystem.gl_attr().set_context_profile(GLProfile::Core);
        }
        if settings.get_samples() != 0 {
            let gl_attr = video_subsystem.gl_attr();
            gl_attr.set_multisample_buffers(1);
            gl_attr.set_multisample_samples(settings.get_samples());
        }

        let mut window_builder = video_subsystem.window(
            &settings.get_title(),
            settings.get_size().width as u32,
            settings.get_size().height as u32
        );

        let window_builder = window_builder.position_centered()
            .opengl()
            .resizable();

        let window_builder = if settings.get_fullscreen() {
            window_builder.fullscreen()
        } else {
            window_builder
        };

        let window = window_builder.build();

        let window = match window {
            Ok(w) => w,
            Err(_) =>
                if settings.get_samples() != 0 {
                    // Retry without requiring anti-aliasing.
                    let gl_attr = video_subsystem.gl_attr();
                    gl_attr.set_multisample_buffers(0);
                    gl_attr.set_multisample_samples(0);
                    try!(window_builder.build())
                } else {
                    try!(window)
                }
        };

        // Send text input events.
        video_subsystem.text_input().start();

        let context = try!(window.gl_create_context());

        // Load the OpenGL function pointers.
        gl::load_with(|name| video_subsystem.gl_get_proc_address(name));

        if settings.get_vsync() {
            video_subsystem.gl_set_swap_interval(1);
        } else {
            video_subsystem.gl_set_swap_interval(0);
        }

        let mut window = Sdl2Window {
            exit_on_esc: settings.get_exit_on_esc(),
            should_close: false,
            window: window,
            context: context,
            sdl_context: sdl_context,
            video_subsystem: video_subsystem,
            mouse_relative: None,
            title: settings.get_title() ,
            size: settings.get_size(),
            draw_size: settings.get_size(),
        };
        window.update_draw_size();
        Ok(window)
    }

    fn update_draw_size(&mut self) {
        let (w, h) = self.window.get_drawable_size();
        self.draw_size = Size { width: w as u32, height: h as u32 };
    }

    fn poll_event(&mut self) -> Option<Input> {
        // First check for a pending relative mouse move event.
        if let Some((x, y)) = self.mouse_relative {
            self.mouse_relative = None;
            return Some(Input::Move(Motion::MouseRelative(x, y)));
        }

        // Even though we create a new EventPump each time we poll an event
        // this should not be a problem since it only contains phantom data
        // and therefore should actually not have any overhead.
        let event = match self.sdl_context.event_pump().unwrap().poll_event() {
            Some( ev ) => ev,
            None => return None
        };
        match event {
            sdl2::event::Event::Quit{..} => {
                self.should_close = true;
            }
            sdl2::event::Event::TextInput { text, .. } => {
                return Some(Input::Text(text));
            }
            sdl2::event::Event::KeyDown { keycode: Some(key), repeat, ..} => {
                // SDL2 repeats the key down event.
                // If the event is the same as last one, ignore it.
                if repeat {
                    return self.poll_event()
                }

                if self.exit_on_esc
                && key == sdl2::keyboard::Keycode::Escape {
                    self.should_close = true;
                } else {
                    return Some(Input::Press(Button::Keyboard(sdl2_map_key(key))));
                }
            }
            sdl2::event::Event::KeyUp { keycode: Some(key), repeat, .. } => {
                if repeat {
                    return self.poll_event()
                }
                return Some(Input::Release(Button::Keyboard(sdl2_map_key(key))));
            }
            sdl2::event::Event::MouseButtonDown { mouse_btn: button, .. } => {
                return Some(Input::Press(Button::Mouse(sdl2_map_mouse(button))));
            }
            sdl2::event::Event::MouseButtonUp { mouse_btn: button, .. } => {
                return Some(Input::Release(Button::Mouse(sdl2_map_mouse(button))));
            }
            sdl2::event::Event::MouseMotion { x, y, xrel: dx, yrel: dy, .. } => {
                // Send relative move movement next time.
                self.mouse_relative = Some((dx as f64, dy as f64));
                return Some(Input::Move(Motion::MouseCursor(x as f64, y as f64)));
            },
            sdl2::event::Event::MouseWheel { x, y, .. } => {
                return Some(Input::Move(Motion::MouseScroll(x as f64, y as f64)));
            }
            sdl2::event::Event::Window {
                win_event_id: sdl2::event::WindowEventId::Resized, data1: w, data2: h, .. } => {
                self.size.width = w as u32;
                self.size.height = h as u32;
                self.update_draw_size();
                return Some(Input::Resize(w as u32, h as u32));
            }
            sdl2::event::Event::Window { win_event_id: sdl2::event::WindowEventId::FocusGained, .. } => {
                return Some(Input::Focus(true));
            }
            sdl2::event::Event::Window { win_event_id: sdl2::event::WindowEventId::FocusLost, .. } => {
                return Some(Input::Focus(false));
            }
            _ => {}
        }
        None
    }
}

impl Drop for Sdl2Window {
    fn drop(&mut self) {
        self.set_capture_cursor(false);
    }
}

impl Window for Sdl2Window {
    type Event = Input;

    fn should_close(&self) -> bool { self.should_close }
    fn set_should_close(&mut self, value: bool) { self.should_close = value; }
    fn swap_buffers(&mut self) { self.window.gl_swap_window(); }
    fn size(&self) -> Size { self.size }
    fn poll_event(&mut self) -> Option<Input> { self.poll_event() }
    fn draw_size(&self) -> Size { self.draw_size }
}

impl AdvancedWindow for Sdl2Window {
    fn get_title(&self) -> String {
        self.title.clone()
    }
    fn set_title(&mut self, value: String) {
        let _ = self.window.set_title(&value);
        self.title = value
    }
    fn get_exit_on_esc(&self) -> bool { self.exit_on_esc }
    fn set_exit_on_esc(&mut self, value: bool) { self.exit_on_esc = value; }
    fn set_capture_cursor(&mut self, value: bool) {
        self.sdl_context.mouse().set_relative_mouse_mode(value);
    }
}

impl OpenGLWindow for Sdl2Window {
    fn get_proc_address(&mut self, proc_name: &str) -> ProcAddress {
        self.video_subsystem.gl_get_proc_address(proc_name)
    }

    fn is_current(&self) -> bool {
        self.context.is_current()
    }

    fn make_current(&mut self) {
        self.window.gl_make_current(&self.context).unwrap();
    }
}

/// Maps a SDL2 key to piston-input key.
pub fn sdl2_map_key(keycode: sdl2::keyboard::Keycode) -> keyboard::Key {
    (keycode as u32).into()
}

/// Maps a SDL2 mouse button to piston-input button.
pub fn sdl2_map_mouse(button: sdl2::mouse::Mouse) -> MouseButton {
    match button {
        sdl2::mouse::Mouse::Left => MouseButton::Left,
        sdl2::mouse::Mouse::Right => MouseButton::Right,
        sdl2::mouse::Mouse::Middle => MouseButton::Middle,
        sdl2::mouse::Mouse::X1 => MouseButton::X1,
        sdl2::mouse::Mouse::X2 => MouseButton::X2,
        sdl2::mouse::Mouse::Unknown(_) => MouseButton::Unknown,
    }
}
<|endoftext|>


<commit_before>//! Edge is a Web framework that is simple to use, with the most common things
//! you need out of the box, and flexible, supporting both synchronous and asynchronous
//! request handling styles; see below for examples.
//!
//! The crate exports the things that you often need from dependencies, such as headers (from `hyper`),
//! cookies (from `cookie`) and JSON serialization (from `serde_json`).
//!
//! Please note that this is an early version, and the API is likely to evolve.
//!
//! ## Overview
//!
//! In Edge you must define an *application structure* that contains the state of your application.
//! You instantiate a container around this application, and associate GET/POST/... requests
//! with given URLs to methods of your application. The container handles the routing and
//! delegates calls to the appropriate methods.
//!
//! Note that the state cannot be mutated, as is usual in Rust (and enforced by the underlying HTTP server
//! this crate uses, a.k.a. Hyper). Use appropriate concurrent data structures if you need
//! shared mutable variables: locks, mutexes, channels, etc.
//!
//! ## Why another Web framework in Rust?
//!
//! Because I wanted a simple Web framework with:
//!
//!   1. everything I needed out of the box, like cookies and forms and templating, without having to dig up third-party crates,
//!   1. the possibility to describe my application as a struct, so that callbacks could use a state (even if just for configuration).
//!
//! We focus on integration rather than modularity.
//! I hope you like this crate, if it misses something to fit your needs just open an issue or make a pull request!
//!
//! And please keep in mind that the framework is in a (very) early stage :-)
//!
//! ## Hello World
//!
//! The most basic application: no state, a single page that prints Hello, world!
//!
//! ```no_run
//! extern crate edge;
//!
//! use edge::{Edge, Request, Response};
//!
//! struct Hello;
//! impl Hello {
//!     fn hello(&self, _req: &mut Request, mut res: Response) {
//!         res.content_type("text/plain");
//!         res.send("Hello, world!")
//!     }
//! }
//!
//! fn main() {
//!     let mut edge = Edge::new("0.0.0.0:3000", Hello);
//!     edge.get("/", Hello::hello);
//!     edge.start().unwrap();
//! }
//! ```
//!
//! ## Asynchronous handling
//!
//! Under the hood, Edge uses the asynchronous version of Hyper. This means that to get the maximum
//! performance, you should avoid waiting in a handler, so that other requests
//! can be served as soon as possible. In that example, the handler waits in a separate thread before sending
//! the response.
//!
//! ```no_run
//! extern crate edge;
//!
//! use edge::{Edge, Request, Response};
//! use std::thread;
//! use std::time::Duration;
//!
//! struct AsyncHello;
//! impl AsyncHello {
//!     fn hello(&self, _req: &mut Request, mut res: Response) {
//!         thread::spawn(move || {
//!             println!("waiting 1 second");
//!             thread::sleep(Duration::from_secs(1));
//!
//!             res.content_type("text/plain");
//!             res.send("Hello, world!")
//!         });
//!
//!         // the handler returns immediately without waiting for the thread
//!     }
//! }
//!
//! fn main() {
//!     let mut edge = Edge::new("0.0.0.0:3000", AsyncHello);
//!     edge.get("/", AsyncHello::hello);
//!     edge.start().unwrap();
//! }
//! ```
//!
//! ## Templating
//!
//! Here our application has a version, still a single handler except this time
//! it accepts any page name, and renders a Handlebars template.  We're also
//! setting a custom Server header.
//!
//! ```no_run
//! extern crate edge;
//!
//! use edge::{Edge, Request, Response, Status};
//! use edge::header::Server;
//! use std::collections::BTreeMap;
//!
//! struct Templating {
//!     version: &'static str
//! }
//!
//! impl Templating {
//!     fn page_handler(&self, req: &mut Request, mut res: Response) {
//!         let mut data = BTreeMap::new();
//!         data.insert("title", req.param("page").unwrap());
//!         data.insert("version", self.version);
//!
//!         res.content_type("text/html").header(Server(format!("Edge version {}", self.version)));
//!         res.render("tmpl", data)
//!     }
//! }
//!
//! fn main() {
//!     let app = Templating { version: "0.1" };
//!     let mut edge = Edge::new("0.0.0.0:3000", app);
//!     edge.get("/:page", Templating::page_handler);
//!     edge.register_template("tmpl");
//!     edge.start().unwrap();
//! }
//! ```
//!
//! ## Using a shared mutable counter
//!
//! In this example, we use an atomic integer to track a counter. This shows a very basic
//! kind of shared state for a handler. In practice, it's best to avoid using blocking
//! mechanisms (locks, mutexes) in a handler directly. Prefer non-blocking calls,
//! like channels' try_recv, or move blocking code in a separate thread,
//! see the example for asynchronous handling above.
//!
//! ```no_run
//! extern crate edge;
//!
//! use edge::{Edge, Request, Response, Status};
//! use std::sync::atomic::{AtomicUsize, Ordering};
//!
//! struct Counting {
//!     counter: AtomicUsize
//! }
//!
//! impl Counting {
//!     fn new() -> Counting { Counting { counter: AtomicUsize::new(0) } }
//!
//!     fn home(&self, _req: &mut Request, mut res: Response) {
//!         let visits = self.counter.load(Ordering::Relaxed);
//!         self.counter.store(visits + 1, Ordering::Relaxed);
//!
//!         res.status(Status::Ok).content_type("text/plain");
//!         res.send(format!("Hello, world! {} visits", visits))
//!     }
//! }
//!
//! fn main() {
//!     let mut cter = Edge::new("0.0.0.0:3000", Counting::new());
//!     cter.get("/", Counting::home);
//!     cter.start().unwrap();
//! }
//! ```

extern crate crossbeam;
extern crate handlebars;
extern crate hyper;
extern crate num_cpus;
extern crate pulldown_cmark;
extern crate scoped_pool;
extern crate serde;
extern crate url;

#[macro_use]
extern crate log;
pub extern crate serde_json;

pub use hyper::header as header;
pub use header::CookiePair as Cookie;
pub use hyper::status::StatusCode as Status;

/// serde_json crate
pub use serde_json as json;

use handlebars::{Context, Handlebars, Helper, RenderContext, RenderError};

use hyper::net::HttpListener;
use hyper::server::Server;

use pulldown_cmark::Parser;
use pulldown_cmark::{Options, OPTION_ENABLE_TABLES, OPTION_ENABLE_FOOTNOTES};
use pulldown_cmark::html;

use scoped_pool::Pool;

use url::Url;

use std::fs::read_dir;
use std::io::Result as IoResult;
use std::net::ToSocketAddrs;
use std::path::{Path, PathBuf};
use std::result;

mod buffer;
mod client;
mod handler;
mod router;
mod request;
mod response;

pub use client::Client;
pub use request::Request;
pub use response::{Response, Result, Action, stream};
pub use router::{Router};

/// Structure for an Edge application.
pub struct Edge {
    base_url: Url,
    routers: Vec<router::RouterAny>,
    handlebars: Handlebars
}

/// ok!() means Ok(Action::End).
/// ok!(expr) returns Ok(From::from(expr))
#[macro_export]
macro_rules! ok {
    () => (
        return Ok($crate::Action::End(None));
    );
    ($exp:expr) => (
        return Ok(::std::convert::From::from($exp));
    );
    ($e1:expr, $e2:expr) => (
        return Ok(::std::convert::From::from(($e1, $e2)));
    )
}

impl Edge {

    /// Creates an Edge application using the given address and application.
    pub fn new(addr: &str) -> Edge {
        let mut handlebars = Handlebars::new();
        init_handlebars(&mut handlebars).unwrap();

        Edge {
            base_url: Url::parse(&("http://".to_string() + addr)).unwrap(),
            routers: Vec::new(),
            handlebars: handlebars
        }
    }

    /// Mounts the given router at the given path.
    ///
    /// Use "/" to mount the router at the root.
    pub fn mount<T>(&mut self, mount: &str, router: Router<T>) {
        let mut router = router::get_inner(router);
        router.set_prefix(mount);
        self.routers.push(router)
    }

    // Registers a template with the given name.
    pub fn register_template(&mut self, name: &str) {
        let mut path = PathBuf::new();
        path.push("views");
        path.push(name);
        path.set_extension("hbs");

        self.handlebars.register_template_file(name, &path).unwrap();
    }

    /// Runs the server in one thread per cpu.
    ///
    /// Creates one instance of `T` per request by calling `Default::default`.
    /// This method blocks the current thread.
    pub fn start(&mut self) -> IoResult<()> {
        assert!(!self.routers.is_empty(), "No router registered! Please mount at least one router");

        // get address and start listening
        let addr = self.base_url.to_socket_addrs().unwrap().next().unwrap();
        let listener = HttpListener::bind(&addr).unwrap();

        // 50% threads for the pool, 50% for the listeners
        let num_threads = ::std::cmp::max(num_cpus::get() / 2, 1);
        let pool = Pool::new(num_threads);
        pool.scoped(|pool_scope| {
            crossbeam::scope(|scope| {
                for i in 0..num_threads {
                    let listener = listener.try_clone().unwrap();
                    let base_url = &self.base_url;
                    let routers = &self.routers;
                    let handlebars = &self.handlebars;
                    scope.spawn(move || {
                        info!("thread {} listening on http://{}", i, addr);
                        Server::new(listener).handle(move |control| {
                            handler::EdgeHandler::new(pool_scope, &base_url, &routers, &handlebars, control)
                        }).unwrap();
                    });
                }
            });
        });

        Ok(())
    }
}

fn render_html(text: &str) -> String {
    let mut opts = Options::empty();
    opts.insert(OPTION_ENABLE_TABLES);
    opts.insert(OPTION_ENABLE_FOOTNOTES);

    let mut s = String::with_capacity(text.len() * 3 / 2);
    let p = Parser::new_ext(text, opts);
    html::push_html(&mut s, p);
    s
}

/// this code is based on code Copyright (c) 2015 Wayne Nilsen
/// see https://github.com/waynenilsen/handlebars-markdown-helper/blob/master/src/lib.rs#L31
///
/// because the handlebars-markdown-helper crate does not allow custom options for Markdown rendering yet
fn markdown_helper(_: &Context, h: &Helper, _ : &Handlebars, rc: &mut RenderContext) -> result::Result<(), RenderError> {
    let markdown_text_var = try!(h.param(0).ok_or_else(|| RenderError::new(
        "Param not found for helper \"markdown\"")
    ));
    let markdown = try!(markdown_text_var.value().as_string().ok_or_else(||
        RenderError::new(format!("Expected a string for parameter {:?}", markdown_text_var))
    ));
    let html = render_html(markdown);
    try!(rc.writer.write_all(html.as_bytes()));
    Ok(())
}

fn init_handlebars(handlebars: &mut Handlebars) -> IoResult<()> {
    // register markdown helper
    handlebars.register_helper("markdown", Box::new(::markdown_helper));

    // register partials folder (if it exists)
    let partials = Path::new("views/partials");
    if partials.exists() {
        for it in try!(read_dir("views/partials")) {
            let entry = try!(it);
            let path = entry.path();
            if path.extension().is_some() && path.extension().unwrap() == "hbs" {
                let name = path.file_stem().unwrap().to_str().unwrap();
                handlebars.register_template_file(name, path.as_path()).unwrap();
            }
        }
    }

    Ok(())
}
<commit_msg>add more threads to the pool<commit_after>//! Edge is a Web framework that is simple to use, with the most common things
//! you need out of the box, and flexible, supporting both synchronous and asynchronous
//! request handling styles; see below for examples.
//!
//! The crate exports the things that you often need from dependencies, such as headers (from `hyper`),
//! cookies (from `cookie`) and JSON serialization (from `serde_json`).
//!
//! Please note that this is an early version, and the API is likely to evolve.
//!
//! ## Overview
//!
//! In Edge you must define an *application structure* that contains the state of your application.
//! You instantiate a container around this application, and associate GET/POST/... requests
//! with given URLs to methods of your application. The container handles the routing and
//! delegates calls to the appropriate methods.
//!
//! Note that the state cannot be mutated, as is usual in Rust (and enforced by the underlying HTTP server
//! this crate uses, a.k.a. Hyper). Use appropriate concurrent data structures if you need
//! shared mutable variables: locks, mutexes, channels, etc.
//!
//! ## Why another Web framework in Rust?
//!
//! Because I wanted a simple Web framework with:
//!
//!   1. everything I needed out of the box, like cookies and forms and templating, without having to dig up third-party crates,
//!   1. the possibility to describe my application as a struct, so that callbacks could use a state (even if just for configuration).
//!
//! We focus on integration rather than modularity.
//! I hope you like this crate, if it misses something to fit your needs just open an issue or make a pull request!
//!
//! And please keep in mind that the framework is in a (very) early stage :-)
//!
//! ## Hello World
//!
//! The most basic application: no state, a single page that prints Hello, world!
//!
//! ```no_run
//! extern crate edge;
//!
//! use edge::{Edge, Request, Response};
//!
//! struct Hello;
//! impl Hello {
//!     fn hello(&self, _req: &mut Request, mut res: Response) {
//!         res.content_type("text/plain");
//!         res.send("Hello, world!")
//!     }
//! }
//!
//! fn main() {
//!     let mut edge = Edge::new("0.0.0.0:3000", Hello);
//!     edge.get("/", Hello::hello);
//!     edge.start().unwrap();
//! }
//! ```
//!
//! ## Asynchronous handling
//!
//! Under the hood, Edge uses the asynchronous version of Hyper. This means that to get the maximum
//! performance, you should avoid waiting in a handler, so that other requests
//! can be served as soon as possible. In that example, the handler waits in a separate thread before sending
//! the response.
//!
//! ```no_run
//! extern crate edge;
//!
//! use edge::{Edge, Request, Response};
//! use std::thread;
//! use std::time::Duration;
//!
//! struct AsyncHello;
//! impl AsyncHello {
//!     fn hello(&self, _req: &mut Request, mut res: Response) {
//!         thread::spawn(move || {
//!             println!("waiting 1 second");
//!             thread::sleep(Duration::from_secs(1));
//!
//!             res.content_type("text/plain");
//!             res.send("Hello, world!")
//!         });
//!
//!         // the handler returns immediately without waiting for the thread
//!     }
//! }
//!
//! fn main() {
//!     let mut edge = Edge::new("0.0.0.0:3000", AsyncHello);
//!     edge.get("/", AsyncHello::hello);
//!     edge.start().unwrap();
//! }
//! ```
//!
//! ## Templating
//!
//! Here our application has a version, still a single handler except this time
//! it accepts any page name, and renders a Handlebars template.  We're also
//! setting a custom Server header.
//!
//! ```no_run
//! extern crate edge;
//!
//! use edge::{Edge, Request, Response, Status};
//! use edge::header::Server;
//! use std::collections::BTreeMap;
//!
//! struct Templating {
//!     version: &'static str
//! }
//!
//! impl Templating {
//!     fn page_handler(&self, req: &mut Request, mut res: Response) {
//!         let mut data = BTreeMap::new();
//!         data.insert("title", req.param("page").unwrap());
//!         data.insert("version", self.version);
//!
//!         res.content_type("text/html").header(Server(format!("Edge version {}", self.version)));
//!         res.render("tmpl", data)
//!     }
//! }
//!
//! fn main() {
//!     let app = Templating { version: "0.1" };
//!     let mut edge = Edge::new("0.0.0.0:3000", app);
//!     edge.get("/:page", Templating::page_handler);
//!     edge.register_template("tmpl");
//!     edge.start().unwrap();
//! }
//! ```
//!
//! ## Using a shared mutable counter
//!
//! In this example, we use an atomic integer to track a counter. This shows a very basic
//! kind of shared state for a handler. In practice, it's best to avoid using blocking
//! mechanisms (locks, mutexes) in a handler directly. Prefer non-blocking calls,
//! like channels' try_recv, or move blocking code in a separate thread,
//! see the example for asynchronous handling above.
//!
//! ```no_run
//! extern crate edge;
//!
//! use edge::{Edge, Request, Response, Status};
//! use std::sync::atomic::{AtomicUsize, Ordering};
//!
//! struct Counting {
//!     counter: AtomicUsize
//! }
//!
//! impl Counting {
//!     fn new() -> Counting { Counting { counter: AtomicUsize::new(0) } }
//!
//!     fn home(&self, _req: &mut Request, mut res: Response) {
//!         let visits = self.counter.load(Ordering::Relaxed);
//!         self.counter.store(visits + 1, Ordering::Relaxed);
//!
//!         res.status(Status::Ok).content_type("text/plain");
//!         res.send(format!("Hello, world! {} visits", visits))
//!     }
//! }
//!
//! fn main() {
//!     let mut cter = Edge::new("0.0.0.0:3000", Counting::new());
//!     cter.get("/", Counting::home);
//!     cter.start().unwrap();
//! }
//! ```

extern crate crossbeam;
extern crate handlebars;
extern crate hyper;
extern crate num_cpus;
extern crate pulldown_cmark;
extern crate scoped_pool;
extern crate serde;
extern crate url;

#[macro_use]
extern crate log;
pub extern crate serde_json;

pub use hyper::header as header;
pub use header::CookiePair as Cookie;
pub use hyper::status::StatusCode as Status;

/// serde_json crate
pub use serde_json as json;

use handlebars::{Context, Handlebars, Helper, RenderContext, RenderError};

use hyper::net::HttpListener;
use hyper::server::Server;

use pulldown_cmark::Parser;
use pulldown_cmark::{Options, OPTION_ENABLE_TABLES, OPTION_ENABLE_FOOTNOTES};
use pulldown_cmark::html;

use scoped_pool::Pool;

use url::Url;

use std::fs::read_dir;
use std::io::Result as IoResult;
use std::net::ToSocketAddrs;
use std::path::{Path, PathBuf};
use std::result;

mod buffer;
mod client;
mod handler;
mod router;
mod request;
mod response;

pub use client::Client;
pub use request::Request;
pub use response::{Response, Result, Action, stream};
pub use router::{Router};

/// Structure for an Edge application.
pub struct Edge {
    base_url: Url,
    routers: Vec<router::RouterAny>,
    handlebars: Handlebars
}

/// ok!() means Ok(Action::End).
/// ok!(expr) returns Ok(From::from(expr))
#[macro_export]
macro_rules! ok {
    () => (
        return Ok($crate::Action::End(None));
    );
    ($exp:expr) => (
        return Ok(::std::convert::From::from($exp));
    );
    ($e1:expr, $e2:expr) => (
        return Ok(::std::convert::From::from(($e1, $e2)));
    )
}

impl Edge {

    /// Creates an Edge application using the given address and application.
    pub fn new(addr: &str) -> Edge {
        let mut handlebars = Handlebars::new();
        init_handlebars(&mut handlebars).unwrap();

        Edge {
            base_url: Url::parse(&("http://".to_string() + addr)).unwrap(),
            routers: Vec::new(),
            handlebars: handlebars
        }
    }

    /// Mounts the given router at the given path.
    ///
    /// Use "/" to mount the router at the root.
    pub fn mount<T>(&mut self, mount: &str, router: Router<T>) {
        let mut router = router::get_inner(router);
        router.set_prefix(mount);
        self.routers.push(router)
    }

    // Registers a template with the given name.
    pub fn register_template(&mut self, name: &str) {
        let mut path = PathBuf::new();
        path.push("views");
        path.push(name);
        path.set_extension("hbs");

        self.handlebars.register_template_file(name, &path).unwrap();
    }

    /// Runs the server in one thread per cpu.
    ///
    /// Creates one instance of `T` per request by calling `Default::default`.
    /// This method blocks the current thread.
    pub fn start(&mut self) -> IoResult<()> {
        assert!(!self.routers.is_empty(), "No router registered! Please mount at least one router");

        // get address and start listening
        let addr = self.base_url.to_socket_addrs().unwrap().next().unwrap();
        let listener = HttpListener::bind(&addr).unwrap();

        let num_cpus = num_cpus::get();
        let pool = Pool::new(num_cpus * 4);
        pool.scoped(|pool_scope| {
            crossbeam::scope(|scope| {
                for i in 0..num_cpus {
                    let listener = listener.try_clone().unwrap();
                    let base_url = &self.base_url;
                    let routers = &self.routers;
                    let handlebars = &self.handlebars;
                    scope.spawn(move || {
                        info!("thread {} listening on http://{}", i, addr);
                        Server::new(listener).handle(move |control| {
                            handler::EdgeHandler::new(pool_scope, &base_url, &routers, &handlebars, control)
                        }).unwrap();
                    });
                }
            });
        });

        Ok(())
    }
}

fn render_html(text: &str) -> String {
    let mut opts = Options::empty();
    opts.insert(OPTION_ENABLE_TABLES);
    opts.insert(OPTION_ENABLE_FOOTNOTES);

    let mut s = String::with_capacity(text.len() * 3 / 2);
    let p = Parser::new_ext(text, opts);
    html::push_html(&mut s, p);
    s
}

/// this code is based on code Copyright (c) 2015 Wayne Nilsen
/// see https://github.com/waynenilsen/handlebars-markdown-helper/blob/master/src/lib.rs#L31
///
/// because the handlebars-markdown-helper crate does not allow custom options for Markdown rendering yet
fn markdown_helper(_: &Context, h: &Helper, _ : &Handlebars, rc: &mut RenderContext) -> result::Result<(), RenderError> {
    let markdown_text_var = try!(h.param(0).ok_or_else(|| RenderError::new(
        "Param not found for helper \"markdown\"")
    ));
    let markdown = try!(markdown_text_var.value().as_string().ok_or_else(||
        RenderError::new(format!("Expected a string for parameter {:?}", markdown_text_var))
    ));
    let html = render_html(markdown);
    try!(rc.writer.write_all(html.as_bytes()));
    Ok(())
}

fn init_handlebars(handlebars: &mut Handlebars) -> IoResult<()> {
    // register markdown helper
    handlebars.register_helper("markdown", Box::new(::markdown_helper));

    // register partials folder (if it exists)
    let partials = Path::new("views/partials");
    if partials.exists() {
        for it in try!(read_dir("views/partials")) {
            let entry = try!(it);
            let path = entry.path();
            if path.extension().is_some() && path.extension().unwrap() == "hbs" {
                let name = path.file_stem().unwrap().to_str().unwrap();
                handlebars.register_template_file(name, path.as_path()).unwrap();
            }
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>// Copyright 2016 Amanieu d'Antras
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! This library provides implementations of `Mutex`, `RwLock`, `Condvar` and
//! `Once` that are smaller, faster and more flexible than those in the Rust
//! standard library. It also provides a `ReentrantMutex` type.

#![warn(missing_docs)]
#![warn(rust_2018_idioms)]
#![cfg_attr(feature = "nightly", feature(asm))]

mod condvar;
mod elision;
mod mutex;
mod once;
mod raw_mutex;
mod raw_rwlock;
mod remutex;
mod rwlock;
mod util;

#[cfg(feature = "deadlock_detection")]
pub mod deadlock;
#[cfg(not(feature = "deadlock_detection"))]
mod deadlock;

pub use self::condvar::{Condvar, WaitTimeoutResult};
pub use self::mutex::{MappedMutexGuard, Mutex, MutexGuard};
pub use self::once::{Once, OnceState};
pub use self::raw_mutex::RawMutex;
pub use self::raw_rwlock::RawRwLock;
pub use self::remutex::{
    MappedReentrantMutexGuard, RawThreadId, ReentrantMutex, ReentrantMutexGuard,
};
pub use self::rwlock::{
    MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard,
    RwLockUpgradableReadGuard, RwLockWriteGuard,
};
<commit_msg>reexport lock_api crate<commit_after>// Copyright 2016 Amanieu d'Antras
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! This library provides implementations of `Mutex`, `RwLock`, `Condvar` and
//! `Once` that are smaller, faster and more flexible than those in the Rust
//! standard library. It also provides a `ReentrantMutex` type.

#![warn(missing_docs)]
#![warn(rust_2018_idioms)]
#![cfg_attr(feature = "nightly", feature(asm))]

mod condvar;
mod elision;
mod mutex;
mod once;
mod raw_mutex;
mod raw_rwlock;
mod remutex;
mod rwlock;
mod util;

#[cfg(feature = "deadlock_detection")]
pub mod deadlock;
#[cfg(not(feature = "deadlock_detection"))]
mod deadlock;

pub use ::lock_api as lock_api;
pub use self::condvar::{Condvar, WaitTimeoutResult};
pub use self::mutex::{MappedMutexGuard, Mutex, MutexGuard};
pub use self::once::{Once, OnceState};
pub use self::raw_mutex::RawMutex;
pub use self::raw_rwlock::RawRwLock;
pub use self::remutex::{
    MappedReentrantMutexGuard, RawThreadId, ReentrantMutex, ReentrantMutexGuard,
};
pub use self::rwlock::{
    MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard,
    RwLockUpgradableReadGuard, RwLockWriteGuard,
};
<|endoftext|>


<commit_before>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is(atty::Stream::Stdout) {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt(atty::Stream::Stdout) {
//!   println!("i'm not a tty")
//! }
//! ```

extern crate libc;

/// possible stream sources
pub enum Stream {
    Stdout,
    Stderr,
    Stdin
}

/// returns true if this is a tty
#[cfg(unix)]
pub fn is(stream: Stream) -> bool {
    let fd = match stream {
        Stream::Stdout => libc::STDOUT_FILENO,
        Stream::Stderr => libc::STDERR_FILENO,
        Stream::Stdin => libc::STDIN_FILENO
    };
    unsafe { libc::isatty(fd) != 0 }
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is(stream: Stream) -> bool {
    extern crate kernel32;
    extern crate winapi;

    let handle = match stream {
        Stream::Stdout => winapi::STD_OUTPUT_HANDLE,
        Stream::Stderr => winapi::STD_ERROR_HANDLE,
        Stream::Stdin => winapi::STD_INPUT_HANDLE
    };

    unsafe {
        let std_handle = kernel32::GetStdHandle(handle);
        match stream {
            Stream::Stdin => {
                let mut out = 0;
                kernel32::GetConsoleMode(std_handle, &mut out) != 0
            },
            _ => {
                // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx
                let mut buffer_info: winapi::PCONSOLE_SCREEN_BUFFER_INFO = ::std::mem::uninitialized();
                let ret = kernel32::GetConsoleScreenBufferInfo(std_handle, &mut buffer_info);
                let last_err = kernel32::GetLastError();
                panic!("is invalid? {:#?}  result {:#?} last err {:#?}",
                winapi::INVALID_HANDLE_VALUE == std_handle,
                ret,
                last_err);
                ret != 0
            }
        }

    }
}

/// returns true if this is _not_ a tty
pub fn isnt(stream: Stream) -> bool {
    !is(stream)
}

#[cfg(test)]
mod tests {
    use super::{is, Stream};

    #[test]
    fn is_err() {
        assert!(is(Stream::Stderr))
    }

    #[test]
    fn is_out() {
        assert!(is(Stream::Stdout))
    }

    #[test]
    fn is_in() {
        assert!(is(Stream::Stdin))
    }
}
<commit_msg>getStdHandle is inherently unreliable for output<commit_after>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is(atty::Stream::Stdout) {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt(atty::Stream::Stdout) {
//!   println!("i'm not a tty")
//! }
//! ```

extern crate libc;

/// possible stream sources
pub enum Stream {
    Stdout,
    Stderr,
    Stdin,
}

/// returns true if this is a tty
#[cfg(unix)]
pub fn is(stream: Stream) -> bool {
    let fd = match stream {
        Stream::Stdout => libc::STDOUT_FILENO,
        Stream::Stderr => libc::STDERR_FILENO,
        Stream::Stdin => libc::STDIN_FILENO,
    };
    unsafe { libc::isatty(fd) != 0 }
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is(stream: Stream) -> bool {
    extern crate kernel32;
    extern crate winapi;

    let handle = match stream {
        Stream::Stdout => winapi::STD_OUTPUT_HANDLE,
        Stream::Stderr => winapi::STD_ERROR_HANDLE,
        Stream::Stdin => winapi::STD_INPUT_HANDLE,
    };

    unsafe {
        match stream {
            Stream::Stdin => {
                let mut out = 0;
                kernel32::GetConsoleMode(kernel32::GetStdHandle(winapi::STD_INPUT_HANDLE),
                                         &mut out) != 0
            }
            out => {
                let name = match out {
                    Stream::Stdout => b"CONOUT$\0",
                    Stream::Stderr => b"CONERR$\0",
                    _ => unreachable!(),
                };
                let handle = kernel32::CreateFileA(name.as_ptr() as *const i8,
                                                   winapi::GENERIC_READ | winapi::GENERIC_WRITE,
                                                   winapi::FILE_SHARE_WRITE,
                                                   ptr::null_mut(),
                                                   winapi::OPEN_EXISTING,
                                                   0,
                                                   ptr::null_mut());
                // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx
                let mut buffer_info = ::std::mem::uninitialized();
                let ret = kernel32::GetConsoleScreenBufferInfo(handle, &mut buffer_info);
                let last_err = kernel32::GetLastError();
                panic!("is invalid? {:#?}  result {:#?} last err {:#?}",
                       winapi::INVALID_HANDLE_VALUE == std_handle,
                       ret,
                       last_err);
                ret != 0
            }
        }

    }
}

/// returns true if this is _not_ a tty
pub fn isnt(stream: Stream) -> bool {
    !is(stream)
}

#[cfg(test)]
mod tests {
    use super::{is, Stream};

    #[test]
    fn is_err() {
        assert!(is(Stream::Stderr))
    }

    #[test]
    fn is_out() {
        assert!(is(Stream::Stdout))
    }

    #[test]
    fn is_in() {
        assert!(is(Stream::Stdin))
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

#[macro_use]
extern crate router;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;

pub mod routing;
pub mod templating;
pub mod session;
pub mod quiz;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<commit_msg>Run rustfmt<commit_after>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

#[macro_use]
extern crate router;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_codegen;

pub mod routing;
pub mod templating;
pub mod session;
pub mod quiz;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<|endoftext|>


<commit_before>// Copyright 2014 Christopher Schröder, Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Rust-HTSlib provides a high level BAM API.
//! Reading and writing BAM files is as easy as
//!
//! ```
//! use rust_htslib::bam;
//! use rust_htslib::bam::Read;
//! use std::path::Path;
//!
//! let bam = bam::Reader::from_path(&Path::new("test/test.bam")).unwrap();
//! let mut out = bam::Writer::from_path_with_template(&Path::new("test/test.bam"), &Path::new("test/out.bam")).unwrap();
//!
//! // copy reverse reads to new BAM file
//! for r in bam.records() {
//!     let record = r.unwrap();
//!     if record.is_reverse() {
//!         out.write(&record).unwrap();
//!     }
//! }
//! ```
//!
//! Pileups can be performed with
//!
//! ```
//! use rust_htslib::bam;
//! use rust_htslib::bam::Read;
//! use std::path::Path;
//!
//! let bam = bam::Reader::from_path(&Path::new("test/test.bam")).unwrap();
//!
//! // pileup over all covered sites
//! for p in bam.pileup() {
//!     let pileup = p.unwrap();
//!     println!("{}:{} depth {}", pileup.tid(), pileup.pos(), pileup.depth());
//!
//!     for alignment in pileup.alignments() {
//!         match alignment.indel() {
//!             bam::pileup::Indel::Ins(len) => println!("Insertion of length {}", len),
//!             bam::pileup::Indel::Del(len) => println!("Deletion of length {}", len),
//!             _ => println!("Base {}", alignment.record().seq()[alignment.qpos()])
//!         }
//!     }
//! }
//! ```
//!
//! In both cases, indexed BAM files can be seeked for specific regions, constraining either the record iterator or the pileups:
//!
//! ```
//! use rust_htslib::bam;
//! use std::path::Path;
//!
//! let mut bam = bam::IndexedReader::from_path(&Path::new("test/test.bam")).unwrap();
//!
//! // seek to chr1:50000-100000
//! let tid = bam.header.tid(b"CHROMOSOME_I").unwrap();
//! bam.seek(tid, 0, 20).unwrap();
//! // afterwards, read or pileup in this region
//! ```

extern crate libc;
extern crate itertools;
#[macro_use]
extern crate quick_error;
#[macro_use]
extern crate newtype_derive;
#[macro_use]
extern crate custom_derive;
extern crate url;

pub mod htslib;
pub mod bam;
pub mod bcf;
pub mod utils;
<commit_msg>Fix order of arguments.<commit_after>// Copyright 2014 Christopher Schröder, Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Rust-HTSlib provides a high level BAM API.
//! Reading and writing BAM files is as easy as
//!
//! ```
//! use rust_htslib::bam;
//! use rust_htslib::bam::Read;
//! use std::path::Path;
//!
//! let bam = bam::Reader::from_path(&Path::new("test/test.bam")).unwrap();
//! let mut out = bam::Writer::from_path_with_template(&Path::new("test/out.bam"), &Path::new("test/test.bam")).unwrap();
//!
//! // copy reverse reads to new BAM file
//! for r in bam.records() {
//!     let record = r.unwrap();
//!     if record.is_reverse() {
//!         out.write(&record).unwrap();
//!     }
//! }
//! ```
//!
//! Pileups can be performed with
//!
//! ```
//! use rust_htslib::bam;
//! use rust_htslib::bam::Read;
//! use std::path::Path;
//!
//! let bam = bam::Reader::from_path(&Path::new("test/test.bam")).unwrap();
//!
//! // pileup over all covered sites
//! for p in bam.pileup() {
//!     let pileup = p.unwrap();
//!     println!("{}:{} depth {}", pileup.tid(), pileup.pos(), pileup.depth());
//!
//!     for alignment in pileup.alignments() {
//!         match alignment.indel() {
//!             bam::pileup::Indel::Ins(len) => println!("Insertion of length {}", len),
//!             bam::pileup::Indel::Del(len) => println!("Deletion of length {}", len),
//!             _ => println!("Base {}", alignment.record().seq()[alignment.qpos()])
//!         }
//!     }
//! }
//! ```
//!
//! In both cases, indexed BAM files can be seeked for specific regions, constraining either the record iterator or the pileups:
//!
//! ```
//! use rust_htslib::bam;
//! use std::path::Path;
//!
//! let mut bam = bam::IndexedReader::from_path(&Path::new("test/test.bam")).unwrap();
//!
//! // seek to chr1:50000-100000
//! let tid = bam.header.tid(b"CHROMOSOME_I").unwrap();
//! bam.seek(tid, 0, 20).unwrap();
//! // afterwards, read or pileup in this region
//! ```

extern crate libc;
extern crate itertools;
#[macro_use]
extern crate quick_error;
#[macro_use]
extern crate newtype_derive;
#[macro_use]
extern crate custom_derive;
extern crate url;

pub mod htslib;
pub mod bam;
pub mod bcf;
pub mod utils;
<|endoftext|>