<commit_before>// Module for parsing ISO Base Media Format aka video/mp4 streams.

// 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 https://mozilla.org/MPL/2.0/.

/// Basic ISO box structure.
pub struct Mp4Box {
    /// Four character box type
    name: u32,
    /// Size of the box in bytes
    size: u64,
}

extern crate byteorder;
use byteorder::{BigEndian, ReadBytesExt};

/// Parse a box out of a data buffer.
pub fn read_box<T: ReadBytesExt>(src: &mut T) -> Option<Mp4Box> {
    let name = src.read_u32::<BigEndian>().unwrap();
    let tmp_size = src.read_u32::<BigEndian>().unwrap();
    let size = match tmp_size {
        1 => src.read_u64::<BigEndian>().unwrap(),
        _ => tmp_size as u64,
    };
    Some(Mp4Box{
        name: name,
        size: size,
    })
}

use std::fmt;
impl fmt::Display for Mp4Box {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let to_vec = |x| vec!((x >> 24 & 0xffu32) as u8,
                              (x >> 16 & 0xffu32) as u8,
                              (x >>  8 & 0xffu32) as u8,
                              (x & 0xffu32) as u8);
        let name_bytes = to_vec(self.name);
        let name = String::from_utf8_lossy(&name_bytes);
        write!(f, "'{}' {} bytes", name, self.size)
    }
}

#[test]
fn test_read_box() {
    use std::io::Cursor;
    let mut test = "test".to_string().into_bytes();
    for x in [0, 0, 0, 8].iter() {
        test.push(*x);
    }
    let mut stream = Cursor::new(test);
    let parsed = read_box(&mut stream).unwrap();
    assert_eq!(parsed.name, 1952805748);
    assert_eq!(parsed.size, 8);
    println!("box {}", parsed);
}

#[test]
fn test_read_box_long() {
    use std::io::Cursor;
    let mut test = "long".to_string().into_bytes();
    for x in [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 16, 0].iter() {
        test.push(*x);
    }
    let mut stream = Cursor::new(test);
    let parsed = read_box(&mut stream).unwrap();
    assert_eq!(parsed.name, 1819242087);
    assert_eq!(parsed.size, 4096);
    println!("box {}", parsed);
}
<commit_msg>Add ftyp box.<commit_after>// Module for parsing ISO Base Media Format aka video/mp4 streams.

// 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 https://mozilla.org/MPL/2.0/.

/// Basic ISO box structure.
pub struct Mp4Box {
    /// Four character box type
    name: u32,
    /// Size of the box in bytes
    size: u64,
}

/// File type box 'ftyp'.
pub struct Mp4FileTypeBox {
    name: u32,
    size: u64,
    major_brand: u32,
    minor_version: u32,
    compatible_brands: Vec<u32>,
}

extern crate byteorder;
use byteorder::{BigEndian, ReadBytesExt};

/// Parse a box out of a data buffer.
pub fn read_box<T: ReadBytesExt>(src: &mut T) -> Option<Mp4Box> {
    let name = src.read_u32::<BigEndian>().unwrap();
    let tmp_size = src.read_u32::<BigEndian>().unwrap();
    let size = match tmp_size {
        1 => src.read_u64::<BigEndian>().unwrap(),
        _ => tmp_size as u64,
    };
    Some(Mp4Box{
        name: name,
        size: size,
    })
}

/// Parse an ftype box.
pub fn read_ftype<T: ReadBytesExt>(src: &mut T) -> Option<Mp4FileTypeBox> {
    let head = read_box(src).unwrap();
    let major = src.read_u32::<BigEndian>().unwrap();
    let minor = src.read_u32::<BigEndian>().unwrap();
    let brand_count = (head.size - 8) /4;
//    let mut brands = Vec<u32>::with_capacity(brand_count);
    let mut brands = Vec::new();
    for _ in 0..brand_count {
        brands.push(src.read_u32::<BigEndian>().unwrap());
    }
    Some(Mp4FileTypeBox{
        name: head.name,
        size: head.size,
        major_brand: major,
        minor_version: minor,
        compatible_brands: brands,
    })
}

use std::fmt;
impl fmt::Display for Mp4Box {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let to_vec = |x| vec!((x >> 24 & 0xffu32) as u8,
                              (x >> 16 & 0xffu32) as u8,
                              (x >>  8 & 0xffu32) as u8,
                              (x & 0xffu32) as u8);
        let name_bytes = to_vec(self.name);
        let name = String::from_utf8_lossy(&name_bytes);
        write!(f, "'{}' {} bytes", name, self.size)
    }
}

#[test]
fn test_read_box() {
    use std::io::Cursor;
    let mut test = "test".to_string().into_bytes();
    for x in [0, 0, 0, 8].iter() {
        test.push(*x);
    }
    let mut stream = Cursor::new(test);
    let parsed = read_box(&mut stream).unwrap();
    assert_eq!(parsed.name, 1952805748);
    assert_eq!(parsed.size, 8);
    println!("box {}", parsed);
}

#[test]
fn test_read_box_long() {
    use std::io::Cursor;
    let mut test = "long".to_string().into_bytes();
    for x in [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 16, 0].iter() {
        test.push(*x);
    }
    let mut stream = Cursor::new(test);
    let parsed = read_box(&mut stream).unwrap();
    assert_eq!(parsed.name, 1819242087);
    assert_eq!(parsed.size, 4096);
    println!("box {}", parsed);
}
<|endoftext|>


<commit_before>#![feature(collections,io)]

/// Implements the XTEA block cipher, whose reference source is public
/// domain.  This code is also public domain.
///
/// Also implements a CBC-mode stream cipher.  I'm not good at crypto
/// so don't use this, and let me know if I'm using the wrong words.

/// A key is 128 bits.  We don't seem to need SIMD anywhere so it's
/// just an array.
pub type Key = [u32; 4];

/// XTEA uses 64-bit blocks; for simplicity and to match the reference
/// source, we use an array here too.
pub type Block = [u32; 2];

static NUM_ROUNDS: u32 = 32;

/// Encrypts 64 bits of input using the key.
pub fn encipher(key: &Key, input: &Block) -> Block {
    // Reference source:
    // unsigned int i;
    // uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
    // for (i=0; i < num_rounds; i++) {
    //     v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    //     sum += delta;
    //     v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
    // }
    // v[0]=v0; v[1]=v1;
    let [mut v0, mut v1] = *input;
    let delta = 0x9E3779B9;
    let mut sum: u32 = 0;
    for _ in 0..NUM_ROUNDS {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[(sum & 3) as usize]);
        sum += delta;
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[((sum>>11) & 3) as usize])
    }
    [v0, v1]
}

/// Decrypts 64 bits of input using the key.
pub fn decipher(key: &Key, input: &Block) -> Block {
    // Reference source:
    // unsigned int i;
    // uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
    // for (i=0; i < num_rounds; i++) {
    //     v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
    //     sum -= delta;
    //     v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    // }
    // v[0]=v0; v[1]=v1;
    let [mut v0, mut v1] = *input;
    let delta = 0x9E3779B9;
    let mut sum = delta * NUM_ROUNDS;
    for _ in 0..NUM_ROUNDS {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[((sum>>11) & 3) as usize]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[(sum & 3) as usize]);
    }
    [v0, v1]
}

use std::io;
use std::mem;
use std::ptr;

fn read_block(chunk: &[u8]) -> Block {
    assert_eq!(chunk.len(), 8);
    unsafe {
        let mut block: Block = mem::uninitialized();
        let b0 = block.get_unchecked_mut(0) as *mut u32;
        let input = chunk.get_unchecked(0) as *const u8;
        ptr::copy_nonoverlapping(b0 as *mut u8, input, 8);
        block
    }
}

fn write_block(block: &Block) -> [u8; 8] {
    unsafe { mem::transmute(*block) }
}

/// Adapts encipher and decipher into a stream cipher using CBC.
pub struct StreamCipher {
    key: Key,
    prev: Block,
}

impl StreamCipher {

    /// Creates an XTEA StreamCipher with a key and an initialization
    /// vector.
    pub fn new(key: Key, iv: Block) -> StreamCipher {
        StreamCipher{key: key, prev: iv}
    }

    fn encrypt_chunk(&mut self, chunk: &[u8], output: &mut io::Write) {
        let mut input_block: Block = read_block(chunk);
        input_block[0] ^= self.prev[0];
        input_block[1] ^= self.prev[1];
        self.prev = encipher(&self.key, &input_block);
        output.write_all(&write_block(&self.prev)).ok().unwrap();
    }

    /// Reads bytes from `input` until it's consumed, and writes the
    /// encrypted bytes to `output`.  Will pad to an 8-byte boundary.
    pub fn encrypt(&mut self, input: &mut io::BufRead, output: &mut io::Write) {
        loop {
            let consumed = {
                let bytes = input.fill_buf().ok().unwrap();
                if bytes.len() == 0 {
                    break;
                }
                for chunk in bytes.chunks(8) {
                    if chunk.len() < 8 {
                        let mut vec = chunk.to_vec();
                        vec.resize(8, 0u8);
                        self.encrypt_chunk(&vec, output);
                    } else {
                        self.encrypt_chunk(&chunk, output);
                    }
                }
                bytes.len()
            };
            input.consume(consumed);
        }
    }

    fn decrypt_chunk(&mut self, chunk: &[u8], output: &mut io::Write) {
        let input_block: Block = read_block(chunk);
        let mut decrypted_block = decipher(&self.key, &input_block);
        decrypted_block[0] ^= self.prev[0];
        decrypted_block[1] ^= self.prev[1];
        self.prev = input_block;
        output.write_all(&write_block(&decrypted_block)).ok().unwrap();
    }

    /// Reads encrypted bytes from `input` until it's consumed, and
    /// writes the decrypted bytes to `output`.  If the input needed
    /// to be padded, the result will have trailing zeroes.
    pub fn decrypt(&mut self, input: &mut io::BufRead, output: &mut io::Write) {
        loop {
            let consumed = {
                let bytes = input.fill_buf().ok().unwrap();
                if bytes.len() == 0 {
                    break;
                }
                for chunk in bytes.chunks(8) {
                    if chunk.len() < 8 {
                        let mut vec = chunk.to_vec();
                        vec.resize(8, 0u8);
                        self.decrypt_chunk(&vec, output);
                    } else {
                        self.decrypt_chunk(&chunk, output);
                    }
                }
                bytes.len()
            };
            input.consume(consumed);
        }
    }

}

#[test]
fn tea_works() {
    let key: Key = [10, 20, 30, 42];
    let plaintext: Block = [300, 400];
    let ciphertext = encipher(&key, &plaintext);
    assert!(plaintext != ciphertext);
    assert_eq!(plaintext, decipher(&key, &ciphertext));
}

#[test]
fn cipher_works() {
    let mut cipher = StreamCipher::new([123, 456, 789, 1011], [867, 5309]);
    let input: Vec<u8> = (0u8..128).collect();

    let mut crypted_cursor: io::Cursor<Vec<u8>> = io::Cursor::new(Vec::new());
    cipher.encrypt(&mut io::Cursor::new(input.clone()), &mut crypted_cursor);
    let crypted = crypted_cursor.into_inner();

    assert_eq!(input.len(), crypted.len());
    assert!(input != crypted);

    // reset cipher iv
    cipher = StreamCipher::new([123, 456, 789, 1011], [867, 5309]);

    let mut decrypted_cursor: io::Cursor<Vec<u8>> = io::Cursor::new(Vec::new());
    cipher.decrypt(&mut io::Cursor::new(crypted.clone()), &mut decrypted_cursor);
    let decrypted = decrypted_cursor.into_inner();
    assert_eq!(input, decrypted);
}

#[test]
fn cipher_padding() {
    let mut cipher = StreamCipher::new([123, 456, 789, 1011], [867, 5309]);
    let input: Vec<u8> = (0u8..123).collect();

    let mut crypted_cursor: io::Cursor<Vec<u8>> = io::Cursor::new(Vec::new());
    cipher.encrypt(&mut io::Cursor::new(input.clone()), &mut crypted_cursor);
    let crypted = crypted_cursor.into_inner();

    assert!(input.len() != crypted.len());
    assert!(input != crypted);

    // reset cipher iv
    cipher = StreamCipher::new([123, 456, 789, 1011], [867, 5309]);

    let mut decrypted_cursor: io::Cursor<Vec<u8>> = io::Cursor::new(Vec::new());
    cipher.decrypt(&mut io::Cursor::new(crypted.clone()), &mut decrypted_cursor);
    let decrypted = decrypted_cursor.into_inner();
    let mut padded_input = input.clone();
    padded_input.resize(128, 0u8);
    assert_eq!(padded_input, decrypted);
}
<commit_msg>fixed crypto language<commit_after>#![feature(collections,io)]

/// Implements the XTEA block cipher, whose reference source is public
/// domain.  This code is also public domain.
///
/// Also implements a CBC-mode block cipher with padding.  I'm not
/// good at crypto so don't use this.

/// A key is 128 bits.  We don't seem to need SIMD anywhere so it's
/// just an array.
pub type Key = [u32; 4];

/// XTEA uses 64-bit blocks; for simplicity and to match the reference
/// source, we use an array here too.
pub type Block = [u32; 2];

static NUM_ROUNDS: u32 = 32;

/// Encrypts 64 bits of input using the key.
pub fn encipher(key: &Key, input: &Block) -> Block {
    // Reference source:
    // unsigned int i;
    // uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
    // for (i=0; i < num_rounds; i++) {
    //     v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    //     sum += delta;
    //     v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
    // }
    // v[0]=v0; v[1]=v1;
    let [mut v0, mut v1] = *input;
    let delta = 0x9E3779B9;
    let mut sum: u32 = 0;
    for _ in 0..NUM_ROUNDS {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[(sum & 3) as usize]);
        sum += delta;
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[((sum>>11) & 3) as usize])
    }
    [v0, v1]
}

/// Decrypts 64 bits of input using the key.
pub fn decipher(key: &Key, input: &Block) -> Block {
    // Reference source:
    // unsigned int i;
    // uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
    // for (i=0; i < num_rounds; i++) {
    //     v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
    //     sum -= delta;
    //     v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    // }
    // v[0]=v0; v[1]=v1;
    let [mut v0, mut v1] = *input;
    let delta = 0x9E3779B9;
    let mut sum = delta * NUM_ROUNDS;
    for _ in 0..NUM_ROUNDS {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[((sum>>11) & 3) as usize]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[(sum & 3) as usize]);
    }
    [v0, v1]
}

use std::io;
use std::mem;
use std::ptr;

fn read_block(chunk: &[u8]) -> Block {
    assert_eq!(chunk.len(), 8);
    unsafe {
        let mut block: Block = mem::uninitialized();
        let b0 = block.get_unchecked_mut(0) as *mut u32;
        let input = chunk.get_unchecked(0) as *const u8;
        ptr::copy_nonoverlapping(b0 as *mut u8, input, 8);
        block
    }
}

fn write_block(block: &Block) -> [u8; 8] {
    unsafe { mem::transmute(*block) }
}

/// Adapts encipher and decipher into a block cipher using CBC.
pub struct BlockCipher {
    key: Key,
    prev: Block,
}

impl BlockCipher {

    /// Creates an XTEA BlockCipher with a key and an initialization
    /// vector.
    pub fn new(key: Key, iv: Block) -> BlockCipher {
        BlockCipher{key: key, prev: iv}
    }

    fn encrypt_chunk(&mut self, chunk: &[u8], output: &mut io::Write) {
        let mut input_block: Block = read_block(chunk);
        input_block[0] ^= self.prev[0];
        input_block[1] ^= self.prev[1];
        self.prev = encipher(&self.key, &input_block);
        output.write_all(&write_block(&self.prev)).ok().unwrap();
    }

    /// Reads bytes from `input` until it's consumed, and writes the
    /// encrypted bytes to `output`.  Will pad to an 8-byte boundary.
    pub fn encrypt(&mut self, input: &mut io::BufRead, output: &mut io::Write) {
        loop {
            let consumed = {
                let bytes = input.fill_buf().ok().unwrap();
                if bytes.len() == 0 {
                    break;
                }
                for chunk in bytes.chunks(8) {
                    if chunk.len() < 8 {
                        let mut vec = chunk.to_vec();
                        vec.resize(8, 0u8);
                        self.encrypt_chunk(&vec, output);
                    } else {
                        self.encrypt_chunk(&chunk, output);
                    }
                }
                bytes.len()
            };
            input.consume(consumed);
        }
    }

    fn decrypt_chunk(&mut self, chunk: &[u8], output: &mut io::Write) {
        let input_block: Block = read_block(chunk);
        let mut decrypted_block = decipher(&self.key, &input_block);
        decrypted_block[0] ^= self.prev[0];
        decrypted_block[1] ^= self.prev[1];
        self.prev = input_block;
        output.write_all(&write_block(&decrypted_block)).ok().unwrap();
    }

    /// Reads encrypted bytes from `input` until it's consumed, and
    /// writes the decrypted bytes to `output`.  If the input needed
    /// to be padded, the result will have trailing zeroes.
    pub fn decrypt(&mut self, input: &mut io::BufRead, output: &mut io::Write) {
        loop {
            let consumed = {
                let bytes = input.fill_buf().ok().unwrap();
                if bytes.len() == 0 {
                    break;
                }
                for chunk in bytes.chunks(8) {
                    if chunk.len() < 8 {
                        let mut vec = chunk.to_vec();
                        vec.resize(8, 0u8);
                        self.decrypt_chunk(&vec, output);
                    } else {
                        self.decrypt_chunk(&chunk, output);
                    }
                }
                bytes.len()
            };
            input.consume(consumed);
        }
    }

}

#[test]
fn tea_works() {
    let key: Key = [10, 20, 30, 42];
    let plaintext: Block = [300, 400];
    let ciphertext = encipher(&key, &plaintext);
    assert!(plaintext != ciphertext);
    assert_eq!(plaintext, decipher(&key, &ciphertext));
}

#[test]
fn cipher_works() {
    let mut cipher = BlockCipher::new([123, 456, 789, 1011], [867, 5309]);
    let input: Vec<u8> = (0u8..128).collect();

    let mut crypted_cursor: io::Cursor<Vec<u8>> = io::Cursor::new(Vec::new());
    cipher.encrypt(&mut io::Cursor::new(input.clone()), &mut crypted_cursor);
    let crypted = crypted_cursor.into_inner();

    assert_eq!(input.len(), crypted.len());
    assert!(input != crypted);

    // reset cipher iv
    cipher = BlockCipher::new([123, 456, 789, 1011], [867, 5309]);

    let mut decrypted_cursor: io::Cursor<Vec<u8>> = io::Cursor::new(Vec::new());
    cipher.decrypt(&mut io::Cursor::new(crypted.clone()), &mut decrypted_cursor);
    let decrypted = decrypted_cursor.into_inner();
    assert_eq!(input, decrypted);
}

#[test]
fn cipher_padding() {
    let mut cipher = BlockCipher::new([123, 456, 789, 1011], [867, 5309]);
    let input: Vec<u8> = (0u8..123).collect();

    let mut crypted_cursor: io::Cursor<Vec<u8>> = io::Cursor::new(Vec::new());
    cipher.encrypt(&mut io::Cursor::new(input.clone()), &mut crypted_cursor);
    let crypted = crypted_cursor.into_inner();

    assert!(input.len() != crypted.len());
    assert!(input != crypted);

    // reset cipher iv
    cipher = BlockCipher::new([123, 456, 789, 1011], [867, 5309]);

    let mut decrypted_cursor: io::Cursor<Vec<u8>> = io::Cursor::new(Vec::new());
    cipher.decrypt(&mut io::Cursor::new(crypted.clone()), &mut decrypted_cursor);
    let decrypted = decrypted_cursor.into_inner();
    let mut padded_input = input.clone();
    padded_input.resize(128, 0u8);
    assert_eq!(padded_input, decrypted);
}
<|endoftext|>


<commit_before>/*!

# GraphQL

[GraphQL][1] is a data query language developed by Facebook intended to serve
mobile and web application frontends. A server provides a schema, containing
types and fields that applications can query. Queries are hierarchical,
composable, and statically typed. Schemas are introspective, which lets clients
statically verify their queries against a server without actually executing
them.

This library provides data types and traits to expose Rust types in a GraphQL
schema, as well as an optional integration into the [Iron framework][2]. It
tries to keep the number of dynamic operations to a minimum, and give you as the
schema developer the control of the query execution path.

Juniper only depends on `rustc-serialize` by default, making it lightweight and
easy to drop into any project. Through the `iron-handlers` feature, it also
depends on Iron.

## Exposing data types

The `GraphQLType` trait is the primary interface towards application developers.
By deriving this trait, you can expose your types as either objects, enums,
interfaces, unions, or scalars.

However, due to the dynamic nature of GraphQL's type system, deriving this trait
manually is a bit tedious, especially in order to do it in a fully type safe
manner. To help with this task, this library provides a couple of macros; the
most common one being `graphql_object!`. Use this macro to expose your already
existing object types as GraphQL objects:

```rust
#[macro_use] extern crate juniper;
# use std::collections::HashMap;
use juniper::{Context, FieldResult};

struct User { id: String, name: String, friend_ids: Vec<String>  }
struct QueryRoot;
struct Database { users: HashMap<String, User> }

impl Context for Database {}

// GraphQL objects can access a "context object" during execution. Use this
// object to provide e.g. database access to the field accessors. This object
// must implement the `Context` trait. If you don't need a context, use the
// empty tuple `()` to indicate this.
//
// In this example, we use the Database struct as our context.
graphql_object!(User: Database |&self| {

    // Expose a simple field as a GraphQL string.
    field id() -> &String {
        &self.id
    }

    field name() -> &String {
        &self.name
    }

    // FieldResult<T> is an alias for Result<T, String> - simply return
    // a string from this method and it will be correctly inserted into
    // the execution response.
    field secret() -> FieldResult<&String> {
        Err("Can't touch this".to_owned())
    }

    // Field accessors can optionally take an "executor" as their first
    // argument. This object can help guide query execution and provides
    // access to the context instance.
    //
    // In this example, the context is used to convert the friend_ids array
    // into actual User objects.
    field friends(&executor) -> Vec<&User> {
        self.friend_ids.iter()
            .filter_map(|id| executor.context().users.get(id))
            .collect()
    }
});

// The context object is passed down to all referenced types - all your exposed
// types need to have the same context type.
graphql_object!(QueryRoot: Database |&self| {

    // Arguments work just like they do on functions.
    field user(&executor, id: String) -> Option<&User> {
        executor.context().users.get(&id)
    }
});

# fn main() { }
```

Adding per type, field, and argument documentation is possible directly from
this macro. For more in-depth information on how to expose fields and types, see
the [`graphql_object!`][3] macro.

## Integrating with Iron

The most obvious usecase is to expose the GraphQL schema over an HTTP endpoint.
To support this, the library provides an optional and customizable Iron handler.

For example, continuing from the schema created above:

```rust,no_run
extern crate iron;
# #[macro_use] extern crate juniper;
# use std::collections::HashMap;

use iron::prelude::*;
use juniper::iron_handlers::GraphQLHandler;
use juniper::{Context, EmptyMutation};

# use juniper::FieldResult;
#
# struct User { id: String, name: String, friend_ids: Vec<String>  }
# struct QueryRoot;
# struct Database { users: HashMap<String, User> }
#
# graphql_object!(User: Database |&self| {
#     field id() -> FieldResult<&String> {
#         Ok(&self.id)
#     }
#
#     field name() -> FieldResult<&String> {
#         Ok(&self.name)
#     }
#
#     field friends(&executor) -> FieldResult<Vec<&User>> {
#         Ok(self.friend_ids.iter()
#             .filter_map(|id| executor.context().users.get(id))
#             .collect())
#     }
# });
#
# graphql_object!(QueryRoot: Database |&self| {
#     field user(&executor, id: String) -> FieldResult<Option<&User>> {
#         Ok(executor.context().users.get(&id))
#     }
# });

// This function is executed for every request. Here, we would realistically
// provide a database connection or similar. For this example, we'll be
// creating the database from scratch.
fn context_factory(_: &mut Request) -> Database {
    Database {
        users: vec![
            ( "1000".to_owned(), User {
                id: "1000".to_owned(), name: "Robin".to_owned(),
                friend_ids: vec!["1001".to_owned()] } ),
            ( "1001".to_owned(), User {
                id: "1001".to_owned(), name: "Max".to_owned(),
                friend_ids: vec!["1000".to_owned()] } ),
        ].into_iter().collect()
    }
}

impl Context for Database {}

fn main() {
    // GraphQLHandler takes a context factory function, the root object,
    // and the mutation object. If we don't have any mutations to expose, we
    // can use the empty tuple () to indicate absence.
    let graphql_endpoint = GraphQLHandler::new(
        context_factory, QueryRoot, EmptyMutation::<Database>::new());

    // Start serving the schema at the root on port 8080.
    Iron::new(graphql_endpoint).http("localhost:8080").unwrap();
}

```

See the [`iron_handlers`][4] module and the [`GraphQLHandler`][5] documentation
for more information on what request methods are supported. There's also a
built-in [GraphiQL][6] handler included.

[1]: http://graphql.org
[2]: http://ironframework.io
[3]: macro.graphql_object!.html
[4]: iron_handlers/index.html
[5]: iron_handlers/struct.GraphQLHandler.html
[6]: https://github.com/graphql/graphiql

*/

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

#[cfg(feature="rustc-serialize")] extern crate rustc_serialize;
#[cfg(feature="serde")] extern crate serde;

#[cfg(feature="nightly")] extern crate test;
#[cfg(feature="iron-handlers")] #[macro_use(itry, iexpect)] extern crate iron;
#[cfg(test)] extern crate iron_test;

#[macro_use] mod macros;
mod ast;
pub mod parser;
mod value;
mod types;
mod schema;
mod validation;
mod executor;
mod integrations;
#[macro_use] mod result_ext;

#[cfg(all(test, not(feature="expose-test-schema")))] mod tests;
#[cfg(feature="expose-test-schema")] pub mod tests;

#[cfg(test)] mod executor_tests;

use parser::{parse_document_source, ParseError, Spanning};
use validation::{ValidatorContext, visit_all_rules, validate_input_values};
use executor::execute_validated_query;

pub use ast::{ToInputValue, FromInputValue, InputValue, Type, Selection};
pub use value::Value;
pub use types::base::{Arguments, GraphQLType, TypeKind};
pub use executor::{
    Executor, ExecutionError, Registry,
    Context, FromContext, IntoResolvable,
    FieldResult, ExecutionResult, Variables,
};
pub use validation::RuleError;
pub use types::scalars::{EmptyMutation, ID};
pub use schema::model::RootNode;
pub use result_ext::ResultExt;

pub use schema::meta;

#[cfg(feature="iron-handlers")] pub use integrations::iron_handlers;

/// An error that prevented query execution
#[derive(Debug, PartialEq)]
#[allow(missing_docs)]
pub enum GraphQLError<'a> {
    ParseError(Spanning<ParseError<'a>>),
    ValidationError(Vec<RuleError>),
    NoOperationProvided,
    MultipleOperationsProvided,
    UnknownOperationName,
}

/// Execute a query in a provided schema
pub fn execute<'a, CtxT, QueryT, MutationT>(
    document_source: &'a str,
    operation_name: Option<&str>,
    root_node: &RootNode<QueryT, MutationT>,
    variables: &Variables,
    context: &CtxT,
)
    -> Result<(Value, Vec<ExecutionError>), GraphQLError<'a>>
    where QueryT: GraphQLType<Context=CtxT>,
          MutationT: GraphQLType<Context=CtxT>,
{
    let document = try!(parse_document_source(document_source));

    {
        let errors = validate_input_values(variables, &document, &root_node.schema);

        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    {
        let mut ctx = ValidatorContext::new(&root_node.schema, &document);
        visit_all_rules(&mut ctx, &document);

        let errors = ctx.into_errors();
        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    execute_validated_query(document, operation_name, root_node, variables, context)
}

impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
    fn from(f: Spanning<ParseError<'a>>) -> GraphQLError<'a> {
        GraphQLError::ParseError(f)
    }
}

#[doc(hidden)]
pub fn to_camel_case(s: &str) -> String {
    let mut dest = String::new();

    for (i, part) in s.split('_').enumerate() {
        if i > 0 && part.len() == 1 {
            dest.push_str(&part.to_uppercase());
        }
        else if i > 0 && part.len() > 1 {
            let first = part.chars().next().unwrap().to_uppercase().collect::<String>();
            let second = &part[1..];

            dest.push_str(&first);
            dest.push_str(second);
        }
        else if i == 0 {
            dest.push_str(part);
        }
    }

    dest
}

#[test]
fn test_to_camel_case() {
    assert_eq!(&to_camel_case("test")[..], "test");
    assert_eq!(&to_camel_case("_test")[..], "Test");
    assert_eq!(&to_camel_case("first_second")[..], "firstSecond");
    assert_eq!(&to_camel_case("first_")[..], "first");
    assert_eq!(&to_camel_case("a_b_c")[..], "aBC");
    assert_eq!(&to_camel_case("a_bc")[..], "aBc");
    assert_eq!(&to_camel_case("a_b")[..], "aB");
    assert_eq!(&to_camel_case("a")[..], "a");
    assert_eq!(&to_camel_case("")[..], "");
}
<commit_msg>Removed rustc-serialization as dependency and updated the docs that referenced rustc.<commit_after>/*!

# GraphQL

[GraphQL][1] is a data query language developed by Facebook intended to serve
mobile and web application frontends. A server provides a schema, containing
types and fields that applications can query. Queries are hierarchical,
composable, and statically typed. Schemas are introspective, which lets clients
statically verify their queries against a server without actually executing
them.

This library provides data types and traits to expose Rust types in a GraphQL
schema, as well as an optional integration into the [Iron framework][2]. It
tries to keep the number of dynamic operations to a minimum, and give you as the
schema developer the control of the query execution path.

Juniper only depends on `serde` and `serde_json` by default, making it lightweight and
easy to drop into any project. Through the `iron-handlers` feature, it also
depends on Iron.

## Exposing data types

The `GraphQLType` trait is the primary interface towards application developers.
By deriving this trait, you can expose your types as either objects, enums,
interfaces, unions, or scalars.

However, due to the dynamic nature of GraphQL's type system, deriving this trait
manually is a bit tedious, especially in order to do it in a fully type safe
manner. To help with this task, this library provides a couple of macros; the
most common one being `graphql_object!`. Use this macro to expose your already
existing object types as GraphQL objects:

```rust
#[macro_use] extern crate juniper;
# use std::collections::HashMap;
use juniper::{Context, FieldResult};

struct User { id: String, name: String, friend_ids: Vec<String>  }
struct QueryRoot;
struct Database { users: HashMap<String, User> }

impl Context for Database {}

// GraphQL objects can access a "context object" during execution. Use this
// object to provide e.g. database access to the field accessors. This object
// must implement the `Context` trait. If you don't need a context, use the
// empty tuple `()` to indicate this.
//
// In this example, we use the Database struct as our context.
graphql_object!(User: Database |&self| {

    // Expose a simple field as a GraphQL string.
    field id() -> &String {
        &self.id
    }

    field name() -> &String {
        &self.name
    }

    // FieldResult<T> is an alias for Result<T, String> - simply return
    // a string from this method and it will be correctly inserted into
    // the execution response.
    field secret() -> FieldResult<&String> {
        Err("Can't touch this".to_owned())
    }

    // Field accessors can optionally take an "executor" as their first
    // argument. This object can help guide query execution and provides
    // access to the context instance.
    //
    // In this example, the context is used to convert the friend_ids array
    // into actual User objects.
    field friends(&executor) -> Vec<&User> {
        self.friend_ids.iter()
            .filter_map(|id| executor.context().users.get(id))
            .collect()
    }
});

// The context object is passed down to all referenced types - all your exposed
// types need to have the same context type.
graphql_object!(QueryRoot: Database |&self| {

    // Arguments work just like they do on functions.
    field user(&executor, id: String) -> Option<&User> {
        executor.context().users.get(&id)
    }
});

# fn main() { }
```

Adding per type, field, and argument documentation is possible directly from
this macro. For more in-depth information on how to expose fields and types, see
the [`graphql_object!`][3] macro.

## Integrating with Iron

The most obvious usecase is to expose the GraphQL schema over an HTTP endpoint.
To support this, the library provides an optional and customizable Iron handler.

For example, continuing from the schema created above:

```rust,no_run
extern crate iron;
# #[macro_use] extern crate juniper;
# use std::collections::HashMap;

use iron::prelude::*;
use juniper::iron_handlers::GraphQLHandler;
use juniper::{Context, EmptyMutation};

# use juniper::FieldResult;
#
# struct User { id: String, name: String, friend_ids: Vec<String>  }
# struct QueryRoot;
# struct Database { users: HashMap<String, User> }
#
# graphql_object!(User: Database |&self| {
#     field id() -> FieldResult<&String> {
#         Ok(&self.id)
#     }
#
#     field name() -> FieldResult<&String> {
#         Ok(&self.name)
#     }
#
#     field friends(&executor) -> FieldResult<Vec<&User>> {
#         Ok(self.friend_ids.iter()
#             .filter_map(|id| executor.context().users.get(id))
#             .collect())
#     }
# });
#
# graphql_object!(QueryRoot: Database |&self| {
#     field user(&executor, id: String) -> FieldResult<Option<&User>> {
#         Ok(executor.context().users.get(&id))
#     }
# });

// This function is executed for every request. Here, we would realistically
// provide a database connection or similar. For this example, we'll be
// creating the database from scratch.
fn context_factory(_: &mut Request) -> Database {
    Database {
        users: vec![
            ( "1000".to_owned(), User {
                id: "1000".to_owned(), name: "Robin".to_owned(),
                friend_ids: vec!["1001".to_owned()] } ),
            ( "1001".to_owned(), User {
                id: "1001".to_owned(), name: "Max".to_owned(),
                friend_ids: vec!["1000".to_owned()] } ),
        ].into_iter().collect()
    }
}

impl Context for Database {}

fn main() {
    // GraphQLHandler takes a context factory function, the root object,
    // and the mutation object. If we don't have any mutations to expose, we
    // can use the empty tuple () to indicate absence.
    let graphql_endpoint = GraphQLHandler::new(
        context_factory, QueryRoot, EmptyMutation::<Database>::new());

    // Start serving the schema at the root on port 8080.
    Iron::new(graphql_endpoint).http("localhost:8080").unwrap();
}

```

See the [`iron_handlers`][4] module and the [`GraphQLHandler`][5] documentation
for more information on what request methods are supported. There's also a
built-in [GraphiQL][6] handler included.

[1]: http://graphql.org
[2]: http://ironframework.io
[3]: macro.graphql_object!.html
[4]: iron_handlers/index.html
[5]: iron_handlers/struct.GraphQLHandler.html
[6]: https://github.com/graphql/graphiql

*/

#![cfg_attr(feature="nightly", feature(test))]
#![warn(missing_docs)]
#[cfg(feature="nightly")] extern crate test;
#[cfg(feature="iron-handlers")] #[macro_use(itry, iexpect)] extern crate iron;
#[cfg(test)] extern crate iron_test;
extern crate serde;
extern crate serde_json;

#[macro_use] mod macros;
mod ast;
pub mod parser;
mod value;
mod types;
mod schema;
mod validation;
mod executor;
mod integrations;
#[macro_use] mod result_ext;

#[cfg(all(test, not(feature="expose-test-schema")))] mod tests;
#[cfg(feature="expose-test-schema")] pub mod tests;

#[cfg(test)] mod executor_tests;

use parser::{parse_document_source, ParseError, Spanning};
use validation::{ValidatorContext, visit_all_rules, validate_input_values};
use executor::execute_validated_query;

pub use ast::{ToInputValue, FromInputValue, InputValue, Type, Selection};
pub use value::Value;
pub use types::base::{Arguments, GraphQLType, TypeKind};
pub use executor::{
    Executor, ExecutionError, Registry,
    Context, FromContext, IntoResolvable,
    FieldResult, ExecutionResult, Variables,
};
pub use validation::RuleError;
pub use types::scalars::{EmptyMutation, ID};
pub use schema::model::RootNode;
pub use result_ext::ResultExt;

pub use schema::meta;

#[cfg(feature="iron-handlers")] pub use integrations::iron_handlers;

/// An error that prevented query execution
#[derive(Debug, PartialEq)]
#[allow(missing_docs)]
pub enum GraphQLError<'a> {
    ParseError(Spanning<ParseError<'a>>),
    ValidationError(Vec<RuleError>),
    NoOperationProvided,
    MultipleOperationsProvided,
    UnknownOperationName,
}

/// Execute a query in a provided schema
pub fn execute<'a, CtxT, QueryT, MutationT>(
    document_source: &'a str,
    operation_name: Option<&str>,
    root_node: &RootNode<QueryT, MutationT>,
    variables: &Variables,
    context: &CtxT,
)
    -> Result<(Value, Vec<ExecutionError>), GraphQLError<'a>>
    where QueryT: GraphQLType<Context=CtxT>,
          MutationT: GraphQLType<Context=CtxT>,
{
    let document = try!(parse_document_source(document_source));

    {
        let errors = validate_input_values(variables, &document, &root_node.schema);

        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    {
        let mut ctx = ValidatorContext::new(&root_node.schema, &document);
        visit_all_rules(&mut ctx, &document);

        let errors = ctx.into_errors();
        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    execute_validated_query(document, operation_name, root_node, variables, context)
}

impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
    fn from(f: Spanning<ParseError<'a>>) -> GraphQLError<'a> {
        GraphQLError::ParseError(f)
    }
}

#[doc(hidden)]
pub fn to_camel_case(s: &str) -> String {
    let mut dest = String::new();

    for (i, part) in s.split('_').enumerate() {
        if i > 0 && part.len() == 1 {
            dest.push_str(&part.to_uppercase());
        }
        else if i > 0 && part.len() > 1 {
            let first = part.chars().next().unwrap().to_uppercase().collect::<String>();
            let second = &part[1..];

            dest.push_str(&first);
            dest.push_str(second);
        }
        else if i == 0 {
            dest.push_str(part);
        }
    }

    dest
}

#[test]
fn test_to_camel_case() {
    assert_eq!(&to_camel_case("test")[..], "test");
    assert_eq!(&to_camel_case("_test")[..], "Test");
    assert_eq!(&to_camel_case("first_second")[..], "firstSecond");
    assert_eq!(&to_camel_case("first_")[..], "first");
    assert_eq!(&to_camel_case("a_b_c")[..], "aBC");
    assert_eq!(&to_camel_case("a_bc")[..], "aBc");
    assert_eq!(&to_camel_case("a_b")[..], "aB");
    assert_eq!(&to_camel_case("a")[..], "a");
    assert_eq!(&to_camel_case("")[..], "");
}
<|endoftext|>


<commit_before>#![allow(dead_code)]
#![feature(float_extras, vec_resize)]

//! # tray\_rust - A Toy Ray Tracer in Rust
//!
//! tray\_rust is a toy physically based ray tracer built off of the techniques
//! discussed in [Physically Based Rendering](http://pbrt.org/). It began life as a port of
//! [tray](https://github.com/Twinklebear/tray) to [Rust](http://www.rust-lang.org) to check out the language.
//! The renderer is currently capable of path tracing, supports triangle meshes (MTL support coming soon),
//! and various physically based material models (including measured data from the
//! [MERL BRDF Database](http://www.merl.com/brdf/)).
//!
//! ## Building
//!
//! Unfortunately the project does currently require Rust nightly as I make use of some unstable features
//! (eg. Vec::resize). I hope to get things running on stable Rust once these features get stabilized.
//!
//! [![Build Status](https://travis-ci.org/Twinklebear/tray_rust.svg?branch=master)](https://travis-ci.org/Twinklebear/tray_rust)
//!
//! ## Running
//!
//! Currently the scene data is hardcoded in `src/scene.rs`, in the future I plan to add support for some
//! kind of JSON based scene file format. I strongly recommend running the release build as the debug version
//! will be very very slow. Running and passing `--help` or `-h` will print out some options, currently
//! the image resolution and samples per pixel are also hardcoded, though these are in `src/main.rs`.
//!
//! ## Building Your Own Scenes
//!
//! Start at the documentation for the scene module.
//!
//! ## TODO
//!
//! - More material models (eg. more microfacet models, rough glass, etc.)
//! - Textures
//! - Support for using an OBJ's associated MTL files
//! - Bump mapping
//! - [Subsurface scattering?](http://en.wikipedia.org/wiki/Subsurface_scattering)
//! - [Vertex Connection and Merging?](http://iliyan.com/publications/VertexMerging)
//!
//! ## Sample Renders
//!
//! In the samples the the Buddha, Dragon, Bunny and Lucy statue are from
//! [The Stanford Scanning Repository](http://graphics.stanford.edu/data/3Dscanrep/).
//! The Rust logo model was made by
//! [Nylithius on BlenderArtists](http://blenderartists.org/forum/showthread.php?362836-Rust-language-3D-logo).
//! The Utah teapot used is from [Morgan McGuire's page](http://graphics.cs.williams.edu/data/meshes.xml) and
//! the monkey head is Blender's Suzanne. I've made minor tweaks to some of the models so for convenience
//! you can find versions that can be easily loaded into the sample scenes [here](https://drive.google.com/folderview?id=0B-l_lLEMo1YeflUzUndCd01hOHhRNUhrQUowM3hVd2pCc3JrSXRiS3FQSzRYLWtGcGM0eGc&usp=sharing), though the
//! cube model for the Cornell box scene is included.
//! The materials on the Rust logo, Buddha, Dragon and Lucy are from the
//! [MERL BRDF Database](http://www.merl.com/brdf/).
//!
//! Render times are formatted as hh:mm:ss and were measured using 144 threads on a machine with four
//! [Xeon E7-8890 v3](http://ark.intel.com/products/84685/Intel-Xeon-Processor-E7-8890-v3-45M-Cache-2_50-GHz)
//! CPUs. The machine is an early/engineering sample from Intel so your results may differ, but massive thanks to
//! Intel for the hardware! Some older images renders are shown as well without timing since they were
//! run on a different machine.
//!
//!
//!
//!
//!
//! 1920x1080, 4096 samples/pixel. Rendering: 00:43:36.45.
//!
//!
//!
//!
//!
//! 1920x1080, 4096 samples/pixel. Rendering: 00:49:33.514.
//!
//!
//!
//!
//!
//! 800x600, 4096 samples/pixel. Rendering: 00:10:05.409.
//!

extern crate enum_set as enum_set;
extern crate rand;
extern crate byteorder;
extern crate serde_json;

pub mod linalg;
pub mod film;
pub mod geometry;
pub mod sampler;
pub mod integrator;
pub mod scene;
pub mod bxdf;
pub mod material;
pub mod light;
pub mod mc;
pub mod partition;

<commit_msg>Fix centering of smaller images<commit_after>#![allow(dead_code)]
#![feature(float_extras, vec_resize)]

//! # tray\_rust - A Toy Ray Tracer in Rust
//!
//! tray\_rust is a toy physically based ray tracer built off of the techniques
//! discussed in [Physically Based Rendering](http://pbrt.org/). It began life as a port of
//! [tray](https://github.com/Twinklebear/tray) to [Rust](http://www.rust-lang.org) to check out the language.
//! The renderer is currently capable of path tracing, supports triangle meshes (MTL support coming soon),
//! and various physically based material models (including measured data from the
//! [MERL BRDF Database](http://www.merl.com/brdf/)).
//!
//! ## Building
//!
//! Unfortunately the project does currently require Rust nightly as I make use of some unstable features
//! (eg. Vec::resize). I hope to get things running on stable Rust once these features get stabilized.
//!
//! [![Build Status](https://travis-ci.org/Twinklebear/tray_rust.svg?branch=master)](https://travis-ci.org/Twinklebear/tray_rust)
//!
//! ## Running
//!
//! Currently the scene data is hardcoded in `src/scene.rs`, in the future I plan to add support for some
//! kind of JSON based scene file format. I strongly recommend running the release build as the debug version
//! will be very very slow. Running and passing `--help` or `-h` will print out some options, currently
//! the image resolution and samples per pixel are also hardcoded, though these are in `src/main.rs`.
//!
//! ## Building Your Own Scenes
//!
//! Start at the documentation for the scene module.
//!
//! ## TODO
//!
//! - More material models (eg. more microfacet models, rough glass, etc.)
//! - Textures
//! - Support for using an OBJ's associated MTL files
//! - Bump mapping
//! - [Subsurface scattering?](http://en.wikipedia.org/wiki/Subsurface_scattering)
//! - [Vertex Connection and Merging?](http://iliyan.com/publications/VertexMerging)
//!
//! ## Sample Renders
//!
//! In the samples the the Buddha, Dragon, Bunny and Lucy statue are from
//! [The Stanford Scanning Repository](http://graphics.stanford.edu/data/3Dscanrep/).
//! The Rust logo model was made by
//! [Nylithius on BlenderArtists](http://blenderartists.org/forum/showthread.php?362836-Rust-language-3D-logo).
//! The Utah teapot used is from [Morgan McGuire's page](http://graphics.cs.williams.edu/data/meshes.xml) and
//! the monkey head is Blender's Suzanne. I've made minor tweaks to some of the models so for convenience
//! you can find versions that can be easily loaded into the sample scenes [here](https://drive.google.com/folderview?id=0B-l_lLEMo1YeflUzUndCd01hOHhRNUhrQUowM3hVd2pCc3JrSXRiS3FQSzRYLWtGcGM0eGc&usp=sharing), though the
//! cube model for the Cornell box scene is included.
//! The materials on the Rust logo, Buddha, Dragon and Lucy are from the
//! [MERL BRDF Database](http://www.merl.com/brdf/).
//!
//! Render times are formatted as hh:mm:ss and were measured using 144 threads on a machine with four
//! [Xeon E7-8890 v3](http://ark.intel.com/products/84685/Intel-Xeon-Processor-E7-8890-v3-45M-Cache-2_50-GHz)
//! CPUs. The machine is an early/engineering sample from Intel so your results may differ, but massive thanks to
//! Intel for the hardware! Some older images renders are shown as well without timing since they were
//! run on a different machine.
//!
//!
//!
//!
//!
//! 1920x1080, 4096 samples/pixel. Rendering: 00:43:36.45.
//!
//!
//!
//!
//!
//! 1920x1080, 4096 samples/pixel. Rendering: 00:49:33.514.
//!
//!
//!
//!
//!
//! 800x600, 4096 samples/pixel. Rendering: 00:10:05.409.
//!

extern crate enum_set as enum_set;
extern crate rand;
extern crate byteorder;
extern crate serde_json;

pub mod linalg;
pub mod film;
pub mod geometry;
pub mod sampler;
pub mod integrator;
pub mod scene;
pub mod bxdf;
pub mod material;
pub mod light;
pub mod mc;
pub mod partition;

<|endoftext|>


<commit_before>use std::fmt;
use std::iter::FromIterator;

pub fn puzzle(input: &str) -> u32 {
    0
}

#[derive(Debug, PartialEq)]
pub struct Screen {
    display: Vec<Vec<char>>,
}

impl Screen {
    pub fn new(width: usize, height: usize) -> Screen {
        Screen {
            display: vec![vec!['.'; width]; height],
        }
    }

    pub fn rect(&mut self, rect_width: usize, rect_height: usize) {
        for h in 0..rect_height {
            for w in 0..rect_width {
                self.display[h][w] = '#';
            }
        }
    }

    pub fn rotate_column(&mut self, col_index: usize, how_many: usize) {
        let col: Vec<_> = self.display.iter()
            .map(|row| row[col_index] ).collect();

        for i in 0..self.display.len() {
            let from_index = (i + self.display.len() - how_many) % self.display.len();
            self.display[i][col_index] = col[from_index];
        }
    }
}

impl fmt::Display for Screen {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for row in self.display.iter() {
            write!(f, "{}\n", String::from_iter(row.iter().cloned()))?;
        }
        Ok(())
    }
}

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

    #[test]
    fn new_screen(){
        let s = Screen::new(1, 2);
        assert_eq!(s, Screen {
            display: vec![vec!['.'], vec!['.']],
        });
        assert_eq!(s.to_string(), ".\n.\n");
    }

    #[test]
    fn rect_drawing() {
        let mut s = Screen::new(7, 3);
        s.rect(3, 2);
        assert_eq!(s.to_string(), "###....\n###....\n.......\n");
    }

    #[test]
    fn rotate_column() {
        let mut s = Screen::new(7, 3);
        s.rect(3, 2);
        s.rotate_column(1, 1);
        assert_eq!(s.to_string(), "#.#....\n###....\n.#.....\n");
    }

}
<commit_msg>Implement rotate row<commit_after>use std::fmt;
use std::iter::FromIterator;

pub fn puzzle(input: &str) -> u32 {
    0
}

#[derive(Debug, PartialEq)]
pub struct Screen {
    display: Vec<Vec<char>>,
}

impl Screen {
    pub fn new(width: usize, height: usize) -> Screen {
        Screen {
            display: vec![vec!['.'; width]; height],
        }
    }

    pub fn rect(&mut self, rect_width: usize, rect_height: usize) {
        for h in 0..rect_height {
            for w in 0..rect_width {
                self.display[h][w] = '#';
            }
        }
    }

    pub fn rotate_column(&mut self, col_index: usize, how_many: usize) {
        let col: Vec<_> = self.display.iter()
            .map(|row| row[col_index] ).collect();

        for i in 0..self.display.len() {
            let from_index = (i + self.display.len() - how_many) % self.display.len();
            self.display[i][col_index] = col[from_index];
        }
    }

    pub fn rotate_row(&mut self, row_index: usize, how_many: usize) {
        let row = self.display[row_index].clone();

        for i in 0..row.len() {
            let from_index = (i + row.len() - how_many) % row.len();
            self.display[row_index][i] = row[from_index];
        }
    }
}

impl fmt::Display for Screen {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for row in self.display.iter() {
            write!(f, "{}\n", String::from_iter(row.iter().cloned()))?;
        }
        Ok(())
    }
}

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

    #[test]
    fn new_screen(){
        let s = Screen::new(1, 2);
        assert_eq!(s, Screen {
            display: vec![vec!['.'], vec!['.']],
        });
        assert_eq!(s.to_string(), ".\n.\n");
    }

    #[test]
    fn rect_drawing() {
        let mut s = Screen::new(7, 3);
        s.rect(3, 2);
        assert_eq!(s.to_string(), "###....\n###....\n.......\n");
    }

    #[test]
    fn rotate_column() {
        let mut s = Screen::new(7, 3);
        s.rect(3, 2);
        s.rotate_column(1, 1);
        assert_eq!(s.to_string(), "#.#....\n###....\n.#.....\n");
    }

    #[test]
    fn rotate_row() {
        let mut s = Screen::new(7, 3);
        s.rect(3, 2);
        s.rotate_column(1, 1);
        s.rotate_row(0, 4);
        assert_eq!(s.to_string(), "....#.#\n###....\n.#.....\n");
    }
}
<|endoftext|>


<commit_before>//! Two-step verification of HOTP/TOTP.
//!
//! # Examples
//!
//!
//! ## HOTP example
//! ```
//! extern crate otpauth;
//!
//! fn main() {
//!     let auth = otpauth::OtpAuth::new("python");
//!     let code = auth.hotp(4);
//!     assert_eq!(true, auth.valid_hotp(code, 0, 100));
//! }
//! ```
//!
//! ## TOTP example
//!
//! ```
//! extern crate otpauth;
//! extern crate time;
//!
//! fn main() {
//!     let auth = otpauth::OtpAuth::new("python");
//!     let timestamp1 = time::now().to_timespec().sec as usize;
//!     let code = auth.totp(30usize, timestamp1);
//!     let timestamp2 = time::now().to_timespec().sec as usize;
//!     assert_eq!(true, auth.valid_totp(code, 30usize, timestamp2));
//! }
//! ```
//!
extern crate crypto;
extern crate byteorder;

use std::io::Cursor;

use crypto::digest::Digest;
use crypto::mac::Mac;
use crypto::hmac::Hmac;
use crypto::sha1::Sha1;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};

pub struct OtpAuth {
    /// A secret token for the authentication
    pub secret: String,
}

impl OtpAuth {
    /// Constructs a new `OtpAuth`
    pub fn new(secret: &str) -> OtpAuth {
        OtpAuth {
            secret: secret.to_string(),
        }
    }

    /// Generate a TOTP code.
    ///
    /// A TOTP code is an extension of HOTP algorithm.
    ///
    /// ``period``: A period that a TOTP code is valid in seconds
    ///
    /// ``timestamp``: Create TOTP at this given timestamp
    pub fn totp(&self, period: usize, timestamp: usize) -> u32 {
        let counter = timestamp / period;
        self.hotp(counter)
    }

    /// Generate a HOTP code.
    ///
    /// ``counter``: HOTP is a counter based algorithm.
    pub fn hotp(&self, counter: usize) -> u32 {
        // Init Hmac
        let key = self.secret.clone().into_bytes();
        let mut hmac = Hmac::new(Sha1::new(), &key[..]);
        // Calc msg
        let mut wtr = vec![];
        // supress warning about unused_must_use
        let _ = wtr.write_u64::<BigEndian>(counter as u64);
        hmac.input(&wtr[..]);
        // Get digest
        let result = hmac.result();
        let digest = result.code();
        let ob = digest[19];
        let pos: usize = (ob & 15) as usize;
        let mut rdr = Cursor::new(digest[pos..pos+4].to_vec());
        let base = rdr.read_u32::<BigEndian>().unwrap() & 0x7fffffff;
        base % 1000000
    }

    /// Valid a TOTP code.
    ///
    /// ``code``: A number that is less than 6 characters.
    ///
    /// ``period``: A period that a TOTP code is valid in seconds
    ///
    /// ``timestamp``: Validate TOTP at this given timestamp
    pub fn valid_totp(&self, code: u32, period: usize, timestamp: usize) -> bool {
        let code_str = code.to_string();
        let code_bytes = code_str.as_bytes();
        if code_bytes.len() > 6 {
            return false;
        }
        let valid_code = self.totp(period, timestamp).to_string();
        let valid_bytes = valid_code.as_bytes();
        if code_bytes.len() != valid_code.len() {
            return false;
        }
        let mut rv = 0;
        for (a, b) in code_bytes.iter().zip(valid_bytes.iter()) {
            rv |= a ^ b;
        }
        rv == 0
    }

    /// Valid a HOTP code.
    ///
    /// ``code``: A number that is less than 6 characters.
    ///
    /// ``last``: Guess HOTP code from last + 1 range.
    ///
    /// ``trials``: Guest HOTP code end at last + trials + 1.
    pub fn valid_hotp(&self, code: u32, last: usize, trials: usize) -> bool {
        let code_str = code.to_string();
        let code_bytes = code_str.as_bytes();
        if code_bytes.len() > 6 {
            return false;
        }
        for i in last+1..last+trials+1 {
            let valid_code = self.hotp(i).to_string();
            let valid_bytes = valid_code.as_bytes();
            if code_bytes.len() != valid_code.len() {
                continue;
            }
            let mut rv = 0;
            for (a, b) in code_bytes.iter().zip(valid_bytes.iter()) {
                rv |= a ^ b;
            }
            if rv == 0 {
                return true;
            }
        }
        false
    }
}
<commit_msg>Update documentation<commit_after>//! Two-step verification of HOTP/TOTP.
//!
//! # Examples
//!
//!
//! ## HOTP example
//! ```
//! extern crate otpauth;
//!
//! fn main() {
//!     let auth = otpauth::OtpAuth::new("python");
//!     let code = auth.hotp(4);
//!     assert_eq!(true, auth.valid_hotp(code, 0, 100));
//! }
//! ```
//!
//! ## TOTP example
//!
//! ```
//! extern crate otpauth;
//! extern crate time;
//!
//! fn main() {
//!     let auth = otpauth::OtpAuth::new("python");
//!     let timestamp1 = time::now().to_timespec().sec as usize;
//!     let code = auth.totp(30usize, timestamp1);
//!     let timestamp2 = time::now().to_timespec().sec as usize;
//!     assert_eq!(true, auth.valid_totp(code, 30usize, timestamp2));
//! }
//! ```
//!
extern crate crypto;
extern crate byteorder;

use std::io::Cursor;

use crypto::digest::Digest;
use crypto::mac::Mac;
use crypto::hmac::Hmac;
use crypto::sha1::Sha1;
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};

pub struct OtpAuth {
    /// A secret token for the authentication
    pub secret: String,
}

impl OtpAuth {
    /// Constructs a new `OtpAuth`
    pub fn new(secret: &str) -> OtpAuth {
        OtpAuth {
            secret: secret.to_string(),
        }
    }

    /// Generate a TOTP code.
    ///
    /// A TOTP code is an extension of HOTP algorithm.
    ///
    /// ``period``: A period that a TOTP code is valid in seconds
    ///
    /// ``timestamp``: Create TOTP at this given timestamp
    pub fn totp(&self, period: usize, timestamp: usize) -> u32 {
        let counter = timestamp / period;
        self.hotp(counter)
    }

    /// Generate a HOTP code.
    ///
    /// ``counter``: HOTP is a counter based algorithm.
    pub fn hotp(&self, counter: usize) -> u32 {
        // Init Hmac
        let key = self.secret.clone().into_bytes();
        let mut hmac = Hmac::new(Sha1::new(), &key[..]);
        // Calc msg
        let mut wtr = vec![];
        // supress warning about unused_must_use
        let _ = wtr.write_u64::<BigEndian>(counter as u64);
        hmac.input(&wtr[..]);
        // Get digest
        let result = hmac.result();
        let digest = result.code();
        let ob = digest[19];
        let pos: usize = (ob & 15) as usize;
        let mut rdr = Cursor::new(digest[pos..pos+4].to_vec());
        let base = rdr.read_u32::<BigEndian>().unwrap() & 0x7fffffff;
        base % 1000000
    }

    /// Valid a TOTP code.
    ///
    /// ``code``: A number that is less than 6 characters.
    ///
    /// ``period``: A period that a TOTP code is valid in seconds
    ///
    /// ``timestamp``: Validate TOTP at this given timestamp
    pub fn valid_totp(&self, code: u32, period: usize, timestamp: usize) -> bool {
        let code_str = code.to_string();
        let code_bytes = code_str.as_bytes();
        if code_bytes.len() > 6 {
            return false;
        }
        let valid_code = self.totp(period, timestamp).to_string();
        let valid_bytes = valid_code.as_bytes();
        if code_bytes.len() != valid_code.len() {
            return false;
        }
        let mut rv = 0;
        for (a, b) in code_bytes.iter().zip(valid_bytes.iter()) {
            rv |= a ^ b;
        }
        rv == 0
    }

    /// Valid a HOTP code.
    ///
    /// ``code``: A number that is less than 6 characters.
    ///
    /// ``last``: Guess HOTP code from ``last + 1`` range.
    ///
    /// ``trials``: Guest HOTP code end at ``last + trials + 1``.
    pub fn valid_hotp(&self, code: u32, last: usize, trials: usize) -> bool {
        let code_str = code.to_string();
        let code_bytes = code_str.as_bytes();
        if code_bytes.len() > 6 {
            return false;
        }
        for i in last+1..last+trials+1 {
            let valid_code = self.hotp(i).to_string();
            let valid_bytes = valid_code.as_bytes();
            if code_bytes.len() != valid_code.len() {
                continue;
            }
            let mut rv = 0;
            for (a, b) in code_bytes.iter().zip(valid_bytes.iter()) {
                rv |= a ^ b;
            }
            if rv == 0 {
                return true;
            }
        }
        false
    }
}
<|endoftext|>


<commit_before>//! A digital signal compressor, designed for use with audio.
//!
//! The main type of interest is the [**Compressor**](./struct.Compressor).
//!
//! You may also find the [**EvenGainFunction**](./even_gain_fn/trait.EvenGainFunction) trait
//! (implemented for both [**Average**](./even_gain_fn/enum.Average) and
//! [**Minimum**](./even_gain_fn/enum.Minimum)) and the [**Detector**](./detector/trait.Detector)
//! trait (implemented for [**PeakEnvelopeDetector**](./detector/type.PeakEnvelopeDetector) and
//! [**RmsEnvelopeDetector**](./detector/struct.RmsEnvelopeDetector).

#[deny(missing_copy_implementations)]
#[deny(missing_docs)]

extern crate envelope_detector;
extern crate time_calc as time;

use envelope_detector::{EnvelopeDetector, Frame, Sample};
use std::marker::PhantomData;
use time::Ms;

pub mod detector;
pub mod even_gain_fn;

#[cfg(feature = "dsp-chain")]
pub mod dsp_node;

pub use detector::{Detector, PeakEnvelopeDetector, RmsEnvelopeDetector};
pub use even_gain_fn::{EvenGainFunction, Average, Minimum};

/// A dynamics processing unit designed to compress some given audio signal that exceeds the
/// `threshold` using the `ratio`.
///
/// The **Compressor** is generic over its envelope [**Detector**](./detector/trait.Detector) and
/// the [**EvenGainFunction**](./even_gain_fn/trait.EvenGainFunction) (used to determine the gain
/// that will be applied evenly to all channels for a single frame).
#[derive(Clone, Debug)]
pub struct Compressor<F, D, EGF> {
    /// The **EnvelopeDetector** used to create a "loudness" envelope.
    envelope_detector: D,
    /// The envelope attack duration in milliseconds.
    attack_ms: Ms,
    /// The envelope release duration in milliseconds.
    release_ms: Ms,
    /// When the detected envelope exceeds this threshold, the signal is compressed via the `ratio`.
    pub threshold: f32,
    /// The slope of the `ratio`, used to calculate the compressor_gain.
    ///
    /// The ratio is the amount at which we compress the signal once the envelope exceeds the
    /// `threshold`.
    ///
    /// *ratio of 4.0 == 4:1 == compress by every 4 parts of the exceeding envelope to 1 == slope
    /// of 0.75.*
    slope: f32,
    /// Some function that yields a gain to be applied evenly across all channels in a single
    /// frame.
    even_gain_fn: PhantomData<EGF>,
    frame: PhantomData<F>,
}

/// A **Compressor** that uses a **Peak** envelope detector.
pub type PeakCompressor<F, EGF> = Compressor<F, PeakEnvelopeDetector<F>, EGF>;
/// A **Compressor** that uses the average across channels yielded by a **Peak** envelope detector.
pub type PeakAvgCompressor<F> = PeakCompressor<F, Average>;
/// A **Compressor** that uses the minimum across channels yielded by a **Peak** envelope detector.
pub type PeakMinCompressor<F> = PeakCompressor<F, Minimum>;

/// A **Compressor** that uses an **Rms** envelope detector.
pub type RmsCompressor<F, EGF> = Compressor<F, RmsEnvelopeDetector<F>, EGF>;
/// A **Compressor** that uses the average across channels yielded by a **Rms** envelope detector.
pub type RmsAvgCompressor<F> = RmsCompressor<F, Average>;
/// A **Compressor** that uses the minimum across channels yielded by a **Rms** envelope detector.
pub type RmsMinCompressor<F> = RmsCompressor<F, Minimum>;

fn calc_slope(ratio: f32) -> f32 {
    1.0 - (1.0 / ratio)
}

impl<F, D, EGF> Compressor<F, D, EGF>
    where F: Frame,
          D: Detector<F>,
          EGF: EvenGainFunction,
{

    /// Construct a new `Compressor` from its parts.
    ///
    /// This is a private constructor wrapped by the more specific `rms` and `peak` public
    /// constructors.
    fn new(detector: D, attack_ms: Ms, release_ms: Ms, threshold: f32, ratio: f32) -> Self {
        let slope = calc_slope(ratio);
        Compressor {
            envelope_detector: detector,
            attack_ms: attack_ms,
            release_ms: release_ms,
            threshold: threshold,
            slope: slope,
            even_gain_fn: std::marker::PhantomData,
            frame: std::marker::PhantomData,
        }
    }

    /// Set the duration of the envelope's attack in milliseconds.
    pub fn set_attack_ms<M: Into<Ms>>(&mut self, ms: M, sample_hz: f64) {
        let ms: Ms = ms.into();
        self.attack_ms = ms;
        self.update_attack_to_sample_hz(sample_hz);
    }

    /// Set the duration of the envelope's release in milliseconds.
    pub fn set_release_ms<M: Into<Ms>>(&mut self, ms: M, sample_hz: f64) {
        let ms: Ms = ms.into();
        self.release_ms = ms;
        self.update_release_to_sample_hz(sample_hz);
    }

    /// Updates the **Compressor**'s `attack` gain in accordance with the current sample_hz.
    pub fn update_attack_to_sample_hz(&mut self, sample_hz: f64) {
        let frames = self.attack_ms.samples(sample_hz) as f32;
        self.envelope_detector.detector().set_attack_frames(frames);
    }

    /// Updates the **Compressor**'s `release` gain in accordance with the current sample_hz.
    pub fn update_release_to_sample_hz(&mut self, sample_hz: f64) {
        let frames = self.release_ms.samples(sample_hz) as f32;
        self.envelope_detector.detector().set_release_frames(frames);
    }

    /// Steps forward the detectors using the given frame and determines the gain per-channel,
    /// yielding the result as a `Frame`.
    pub fn next_gain_per_channel(&mut self, next_frame: F) -> F::Float {
        let threshold = self.threshold.to_sample();
        let slope = self.slope.to_sample();
        let identity = <F::Sample as Sample>::identity();
        let env_frame = self.envelope_detector.detector().next(next_frame).to_float_frame();
        env_frame.map(|s| {
            let s = if s > identity { identity } else { s }; // Clamp `s` between 0.0...1.0.
            if s > threshold { identity - (s - threshold) * slope } else { identity }
        })
    }

    /// Produce the gain to be applied evenly across all channels for the next frame.
    #[inline]
    pub fn next_gain(&mut self, next_frame: F) -> <F::Sample as Sample>::Float {
        EGF::next_gain(self, next_frame)
    }

    /// Steps forward the `Compressor` by the given frame and returns the compressed result.
    #[inline]
    pub fn next_frame(&mut self, next_frame: F) -> F {
        let gain = self.next_gain(next_frame);
        println!("gain: {:?}", gain.to_sample::<f32>());
        next_frame.scale_amp(gain)
    }

}

impl<F, EGF> PeakCompressor<F, EGF>
    where F: Frame,
          EGF: EvenGainFunction,
{

    /// Construct a **Compressor** that uses a **Peak** **EnvelopeDetector**.
    pub fn peak<A, R>(attack_ms: A,
                      release_ms: R,
                      sample_hz: f64,
                      threshold: f32,
                      ratio: f32) -> Self
        where A: Into<Ms>,
              R: Into<Ms>,
    {
        let attack_ms: Ms = attack_ms.into();
        let release_ms: Ms = release_ms.into();
        let attack_frames = attack_ms.samples(sample_hz) as f32;
        let release_frames = release_ms.samples(sample_hz) as f32;
        let envelope_detector = EnvelopeDetector::peak(attack_frames, release_frames);
        Compressor::new(envelope_detector, attack_ms, release_ms, threshold, ratio)
    }

}

impl<F> PeakAvgCompressor<F>
    where F: Frame,
{

    /// Construct a **Compressor** that uses the **Average** across all channels yielded by a
    /// **Peak** **EnvelopeDetector**
    pub fn peak_avg<A, R>(attack_ms: A,
                          release_ms: R,
                          sample_hz: f64,
                          threshold: f32,
                          ratio: f32) -> Self
        where A: Into<Ms>,
              R: Into<Ms>,
    {
        Self::peak(attack_ms, release_ms, sample_hz, threshold, ratio)
    }

}

impl<F> PeakMinCompressor<F>
    where F: Frame,
{

    /// Construct a **Compressor** that uses the **Minimum** across all channels yielded by a
    /// **Peak** **EnvelopeDetector**
    pub fn peak_min<A, R>(attack_ms: A,
                          release_ms: R,
                          sample_hz: f64,
                          threshold: f32,
                          ratio: f32) -> Self
        where A: Into<Ms>,
              R: Into<Ms>,
    {
        Self::peak(attack_ms, release_ms, sample_hz, threshold, ratio)
    }

}

impl<F, EGF> RmsCompressor<F, EGF>
    where F: Frame,
          EGF: EvenGainFunction,
{

    /// Construct a **Compressor** that uses an **Rms** **EnvelopeDetector**.
    pub fn rms<W, A, R>(window_ms: W,
                        attack_ms: A,
                        release_ms: R,
                        sample_hz: f64,
                        threshold: f32,
                        ratio: f32) -> Self
        where W: Into<Ms>,
              A: Into<Ms>,
              R: Into<Ms>,
    {
        let window_ms: Ms = window_ms.into();
        let attack_ms: Ms = attack_ms.into();
        let release_ms: Ms = release_ms.into();
        let window_frames = window_ms.samples(sample_hz) as usize;
        let attack_frames = attack_ms.samples(sample_hz) as f32;
        let release_frames = release_ms.samples(sample_hz) as f32;
        let envelope_detector = EnvelopeDetector::rms(window_frames, attack_frames, release_frames);
        let rms_envelope_detector = RmsEnvelopeDetector {
            rms: envelope_detector,
            window_ms: window_ms,
        };
        Compressor::new(rms_envelope_detector, attack_ms, release_ms, threshold, ratio)
    }

    /// Set the duration of the envelope's RMS window in milliseconds.
    pub fn set_window_ms<M: Into<Ms>>(&mut self, ms: M, sample_hz: f64) {
        let ms: Ms = ms.into();
        self.envelope_detector.window_ms = ms;
        self.update_window_to_sample_hz(sample_hz);
    }

    /// Updates the **Compressor**'s window size in frames via the given sample_hz.
    pub fn update_window_to_sample_hz(&mut self, sample_hz: f64) {
        let frames = self.envelope_detector.window_ms.samples(sample_hz) as usize;
        self.envelope_detector.rms.set_window_frames(frames);
    }

}

impl<F> RmsAvgCompressor<F>
    where F: Frame,
{

    /// Construct a **Compressor** that uses the **Average** across all channels yielded by a
    /// **Rms** **EnvelopeDetector**
    pub fn rms_avg<W, A, R>(window_ms: W,
                            attack_ms: A,
                            release_ms: R,
                            sample_hz: f64,
                            threshold: f32,
                            ratio: f32) -> Self
        where W: Into<Ms>,
              A: Into<Ms>,
              R: Into<Ms>,
    {
        Self::rms(window_ms, attack_ms, release_ms, sample_hz, threshold, ratio)
    }

}

impl<F> RmsMinCompressor<F>
    where F: Frame,
{

    /// Construct a **Compressor** that uses the **Minimum** across all channels yielded by a
    /// **Rms** **EnvelopeDetector**
    pub fn rms_min<W, A, R>(window_ms: W,
                            attack_ms: A,
                            release_ms: R,
                            sample_hz: f64,
                            threshold: f32,
                            ratio: f32) -> Self
        where W: Into<Ms>,
              A: Into<Ms>,
              R: Into<Ms>,
    {
        Self::rms(window_ms, attack_ms, release_ms, sample_hz, threshold, ratio)
    }

}
<commit_msg>Remove leftover println<commit_after>//! A digital signal compressor, designed for use with audio.
//!
//! The main type of interest is the [**Compressor**](./struct.Compressor).
//!
//! You may also find the [**EvenGainFunction**](./even_gain_fn/trait.EvenGainFunction) trait
//! (implemented for both [**Average**](./even_gain_fn/enum.Average) and
//! [**Minimum**](./even_gain_fn/enum.Minimum)) and the [**Detector**](./detector/trait.Detector)
//! trait (implemented for [**PeakEnvelopeDetector**](./detector/type.PeakEnvelopeDetector) and
//! [**RmsEnvelopeDetector**](./detector/struct.RmsEnvelopeDetector).

#[deny(missing_copy_implementations)]
#[deny(missing_docs)]

extern crate envelope_detector;
extern crate time_calc as time;

use envelope_detector::{EnvelopeDetector, Frame, Sample};
use std::marker::PhantomData;
use time::Ms;

pub mod detector;
pub mod even_gain_fn;

#[cfg(feature = "dsp-chain")]
pub mod dsp_node;

pub use detector::{Detector, PeakEnvelopeDetector, RmsEnvelopeDetector};
pub use even_gain_fn::{EvenGainFunction, Average, Minimum};

/// A dynamics processing unit designed to compress some given audio signal that exceeds the
/// `threshold` using the `ratio`.
///
/// The **Compressor** is generic over its envelope [**Detector**](./detector/trait.Detector) and
/// the [**EvenGainFunction**](./even_gain_fn/trait.EvenGainFunction) (used to determine the gain
/// that will be applied evenly to all channels for a single frame).
#[derive(Clone, Debug)]
pub struct Compressor<F, D, EGF> {
    /// The **EnvelopeDetector** used to create a "loudness" envelope.
    envelope_detector: D,
    /// The envelope attack duration in milliseconds.
    attack_ms: Ms,
    /// The envelope release duration in milliseconds.
    release_ms: Ms,
    /// When the detected envelope exceeds this threshold, the signal is compressed via the `ratio`.
    pub threshold: f32,
    /// The slope of the `ratio`, used to calculate the compressor_gain.
    ///
    /// The ratio is the amount at which we compress the signal once the envelope exceeds the
    /// `threshold`.
    ///
    /// *ratio of 4.0 == 4:1 == compress by every 4 parts of the exceeding envelope to 1 == slope
    /// of 0.75.*
    slope: f32,
    /// Some function that yields a gain to be applied evenly across all channels in a single
    /// frame.
    even_gain_fn: PhantomData<EGF>,
    frame: PhantomData<F>,
}

/// A **Compressor** that uses a **Peak** envelope detector.
pub type PeakCompressor<F, EGF> = Compressor<F, PeakEnvelopeDetector<F>, EGF>;
/// A **Compressor** that uses the average across channels yielded by a **Peak** envelope detector.
pub type PeakAvgCompressor<F> = PeakCompressor<F, Average>;
/// A **Compressor** that uses the minimum across channels yielded by a **Peak** envelope detector.
pub type PeakMinCompressor<F> = PeakCompressor<F, Minimum>;

/// A **Compressor** that uses an **Rms** envelope detector.
pub type RmsCompressor<F, EGF> = Compressor<F, RmsEnvelopeDetector<F>, EGF>;
/// A **Compressor** that uses the average across channels yielded by a **Rms** envelope detector.
pub type RmsAvgCompressor<F> = RmsCompressor<F, Average>;
/// A **Compressor** that uses the minimum across channels yielded by a **Rms** envelope detector.
pub type RmsMinCompressor<F> = RmsCompressor<F, Minimum>;

fn calc_slope(ratio: f32) -> f32 {
    1.0 - (1.0 / ratio)
}

impl<F, D, EGF> Compressor<F, D, EGF>
    where F: Frame,
          D: Detector<F>,
          EGF: EvenGainFunction,
{

    /// Construct a new `Compressor` from its parts.
    ///
    /// This is a private constructor wrapped by the more specific `rms` and `peak` public
    /// constructors.
    fn new(detector: D, attack_ms: Ms, release_ms: Ms, threshold: f32, ratio: f32) -> Self {
        let slope = calc_slope(ratio);
        Compressor {
            envelope_detector: detector,
            attack_ms: attack_ms,
            release_ms: release_ms,
            threshold: threshold,
            slope: slope,
            even_gain_fn: std::marker::PhantomData,
            frame: std::marker::PhantomData,
        }
    }

    /// Set the duration of the envelope's attack in milliseconds.
    pub fn set_attack_ms<M: Into<Ms>>(&mut self, ms: M, sample_hz: f64) {
        let ms: Ms = ms.into();
        self.attack_ms = ms;
        self.update_attack_to_sample_hz(sample_hz);
    }

    /// Set the duration of the envelope's release in milliseconds.
    pub fn set_release_ms<M: Into<Ms>>(&mut self, ms: M, sample_hz: f64) {
        let ms: Ms = ms.into();
        self.release_ms = ms;
        self.update_release_to_sample_hz(sample_hz);
    }

    /// Updates the **Compressor**'s `attack` gain in accordance with the current sample_hz.
    pub fn update_attack_to_sample_hz(&mut self, sample_hz: f64) {
        let frames = self.attack_ms.samples(sample_hz) as f32;
        self.envelope_detector.detector().set_attack_frames(frames);
    }

    /// Updates the **Compressor**'s `release` gain in accordance with the current sample_hz.
    pub fn update_release_to_sample_hz(&mut self, sample_hz: f64) {
        let frames = self.release_ms.samples(sample_hz) as f32;
        self.envelope_detector.detector().set_release_frames(frames);
    }

    /// Steps forward the detectors using the given frame and determines the gain per-channel,
    /// yielding the result as a `Frame`.
    pub fn next_gain_per_channel(&mut self, next_frame: F) -> F::Float {
        let threshold = self.threshold.to_sample();
        let slope = self.slope.to_sample();
        let identity = <F::Sample as Sample>::identity();
        let env_frame = self.envelope_detector.detector().next(next_frame).to_float_frame();
        env_frame.map(|s| {
            let s = if s > identity { identity } else { s }; // Clamp `s` between 0.0...1.0.
            if s > threshold { identity - (s - threshold) * slope } else { identity }
        })
    }

    /// Produce the gain to be applied evenly across all channels for the next frame.
    #[inline]
    pub fn next_gain(&mut self, next_frame: F) -> <F::Sample as Sample>::Float {
        EGF::next_gain(self, next_frame)
    }

    /// Steps forward the `Compressor` by the given frame and returns the compressed result.
    #[inline]
    pub fn next_frame(&mut self, next_frame: F) -> F {
        let gain = self.next_gain(next_frame);
        next_frame.scale_amp(gain)
    }

}

impl<F, EGF> PeakCompressor<F, EGF>
    where F: Frame,
          EGF: EvenGainFunction,
{

    /// Construct a **Compressor** that uses a **Peak** **EnvelopeDetector**.
    pub fn peak<A, R>(attack_ms: A,
                      release_ms: R,
                      sample_hz: f64,
                      threshold: f32,
                      ratio: f32) -> Self
        where A: Into<Ms>,
              R: Into<Ms>,
    {
        let attack_ms: Ms = attack_ms.into();
        let release_ms: Ms = release_ms.into();
        let attack_frames = attack_ms.samples(sample_hz) as f32;
        let release_frames = release_ms.samples(sample_hz) as f32;
        let envelope_detector = EnvelopeDetector::peak(attack_frames, release_frames);
        Compressor::new(envelope_detector, attack_ms, release_ms, threshold, ratio)
    }

}

impl<F> PeakAvgCompressor<F>
    where F: Frame,
{

    /// Construct a **Compressor** that uses the **Average** across all channels yielded by a
    /// **Peak** **EnvelopeDetector**
    pub fn peak_avg<A, R>(attack_ms: A,
                          release_ms: R,
                          sample_hz: f64,
                          threshold: f32,
                          ratio: f32) -> Self
        where A: Into<Ms>,
              R: Into<Ms>,
    {
        Self::peak(attack_ms, release_ms, sample_hz, threshold, ratio)
    }

}

impl<F> PeakMinCompressor<F>
    where F: Frame,
{

    /// Construct a **Compressor** that uses the **Minimum** across all channels yielded by a
    /// **Peak** **EnvelopeDetector**
    pub fn peak_min<A, R>(attack_ms: A,
                          release_ms: R,
                          sample_hz: f64,
                          threshold: f32,
                          ratio: f32) -> Self
        where A: Into<Ms>,
              R: Into<Ms>,
    {
        Self::peak(attack_ms, release_ms, sample_hz, threshold, ratio)
    }

}

impl<F, EGF> RmsCompressor<F, EGF>
    where F: Frame,
          EGF: EvenGainFunction,
{

    /// Construct a **Compressor** that uses an **Rms** **EnvelopeDetector**.
    pub fn rms<W, A, R>(window_ms: W,
                        attack_ms: A,
                        release_ms: R,
                        sample_hz: f64,
                        threshold: f32,
                        ratio: f32) -> Self
        where W: Into<Ms>,
              A: Into<Ms>,
              R: Into<Ms>,
    {
        let window_ms: Ms = window_ms.into();
        let attack_ms: Ms = attack_ms.into();
        let release_ms: Ms = release_ms.into();
        let window_frames = window_ms.samples(sample_hz) as usize;
        let attack_frames = attack_ms.samples(sample_hz) as f32;
        let release_frames = release_ms.samples(sample_hz) as f32;
        let envelope_detector = EnvelopeDetector::rms(window_frames, attack_frames, release_frames);
        let rms_envelope_detector = RmsEnvelopeDetector {
            rms: envelope_detector,
            window_ms: window_ms,
        };
        Compressor::new(rms_envelope_detector, attack_ms, release_ms, threshold, ratio)
    }

    /// Set the duration of the envelope's RMS window in milliseconds.
    pub fn set_window_ms<M: Into<Ms>>(&mut self, ms: M, sample_hz: f64) {
        let ms: Ms = ms.into();
        self.envelope_detector.window_ms = ms;
        self.update_window_to_sample_hz(sample_hz);
    }

    /// Updates the **Compressor**'s window size in frames via the given sample_hz.
    pub fn update_window_to_sample_hz(&mut self, sample_hz: f64) {
        let frames = self.envelope_detector.window_ms.samples(sample_hz) as usize;
        self.envelope_detector.rms.set_window_frames(frames);
    }

}

impl<F> RmsAvgCompressor<F>
    where F: Frame,
{

    /// Construct a **Compressor** that uses the **Average** across all channels yielded by a
    /// **Rms** **EnvelopeDetector**
    pub fn rms_avg<W, A, R>(window_ms: W,
                            attack_ms: A,
                            release_ms: R,
                            sample_hz: f64,
                            threshold: f32,
                            ratio: f32) -> Self
        where W: Into<Ms>,
              A: Into<Ms>,
              R: Into<Ms>,
    {
        Self::rms(window_ms, attack_ms, release_ms, sample_hz, threshold, ratio)
    }

}

impl<F> RmsMinCompressor<F>
    where F: Frame,
{

    /// Construct a **Compressor** that uses the **Minimum** across all channels yielded by a
    /// **Rms** **EnvelopeDetector**
    pub fn rms_min<W, A, R>(window_ms: W,
                            attack_ms: A,
                            release_ms: R,
                            sample_hz: f64,
                            threshold: f32,
                            ratio: f32) -> Self
        where W: Into<Ms>,
              A: Into<Ms>,
              R: Into<Ms>,
    {
        Self::rms(window_ms, attack_ms, release_ms, sample_hz, threshold, ratio)
    }

}
<|endoftext|>


<commit_before>#![crate_name = "librespot"]

#![cfg_attr(feature = "cargo-clippy", allow(unused_io_amount))]

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

extern crate base64;
extern crate crypto;
extern crate futures;
extern crate hyper;
extern crate num_bigint;
extern crate protobuf;
extern crate rand;
extern crate tokio_core;
extern crate url;

pub extern crate librespot_audio as audio;
pub extern crate librespot_core as core;
pub extern crate librespot_protocol as protocol;
pub extern crate librespot_metadata as metadata;

#[cfg(feature = "alsa-backend")]
extern crate alsa;

#[cfg(feature = "portaudio-rs")]
extern crate portaudio_rs;

#[cfg(feature = "libpulse-sys")]
extern crate libpulse_sys;

#[cfg(feature = "jackaudio-backend")]
extern crate jack;

#[cfg(feature = "libc")]
extern crate libc;

#[cfg(feature = "with-dns-sd")]
extern crate dns_sd;

#[cfg(not(feature = "with-dns-sd"))]
extern crate mdns;

pub mod audio_backend;
pub mod discovery;
pub mod mixer;
pub mod player;

include!(concat!(env!("OUT_DIR"), "/lib.rs"));
<commit_msg>Re-add serde_derive to lib.rs<commit_after>#![crate_name = "librespot"]

#![cfg_attr(feature = "cargo-clippy", allow(unused_io_amount))]

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

extern crate base64;
extern crate crypto;
extern crate futures;
extern crate hyper;
extern crate num_bigint;
extern crate protobuf;
extern crate rand;
extern crate tokio_core;
extern crate url;

pub extern crate librespot_audio as audio;
pub extern crate librespot_core as core;
pub extern crate librespot_protocol as protocol;
pub extern crate librespot_metadata as metadata;

#[cfg(feature = "alsa-backend")]
extern crate alsa;

#[cfg(feature = "portaudio-rs")]
extern crate portaudio_rs;

#[cfg(feature = "libpulse-sys")]
extern crate libpulse_sys;

#[cfg(feature = "jackaudio-backend")]
extern crate jack;

#[cfg(feature = "libc")]
extern crate libc;

#[cfg(feature = "with-dns-sd")]
extern crate dns_sd;

#[cfg(not(feature = "with-dns-sd"))]
extern crate mdns;

pub mod audio_backend;
pub mod discovery;
pub mod mixer;
pub mod player;

include!(concat!(env!("OUT_DIR"), "/lib.rs"));
<|endoftext|>