<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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.

/*!
 * An implementation of the SHA-1 cryptographic hash.
 *
 * First create a `sha1` object using the `sha1` constructor, then
 * feed it input using the `input` or `input_str` methods, which may be
 * called any number of times.
 *
 * After the entire input has been fed to the hash read the result using
 * the `result` or `result_str` methods.
 *
 * The `sha1` object may be reused to create multiple hashes by calling
 * the `reset` method.
 */

use cryptoutil::{write_u32_be, read_u32v_be, add_bytes_to_bits, FixedBuffer, FixedBuffer64,
    StandardPadding};
use digest::Digest;

/*
 * A SHA-1 implementation derived from Paul E. Jones's reference
 * implementation, which is written for clarity, not speed. At some
 * point this will want to be rewritten.
 */

// Some unexported constants
const DIGEST_BUF_LEN: usize = 5;
const WORK_BUF_LEN: usize = 80;
const K0: u32 = 0x5A827999u32;
const K1: u32 = 0x6ED9EBA1u32;
const K2: u32 = 0x8F1BBCDCu32;
const K3: u32 = 0xCA62C1D6u32;

/// Structure representing the state of a Sha1 computation
#[derive(Copy)]
pub struct Sha1 {
    h: [u32; DIGEST_BUF_LEN],
    length_bits: u64,
    buffer: FixedBuffer64,
    computed: bool,
}

fn add_input(st: &mut Sha1, msg: &[u8]) {
    assert!((!st.computed));
    // Assumes that msg.len() can be converted to u64 without overflow
    st.length_bits = add_bytes_to_bits(st.length_bits, msg.len() as u64);
    let st_h = &mut st.h;
    st.buffer.input(msg, |d: &[u8]| {process_msg_block(d, &mut *st_h); });
}

fn process_msg_block(data: &[u8], h: &mut [u32; DIGEST_BUF_LEN]) {
    let mut w = [0u32; WORK_BUF_LEN];

    // Initialize the first 16 words of the vector w
    read_u32v_be(&mut w[0..16], data);

    // Initialize the rest of vector w
    let mut t = 16; // loop counter
    while t < 80 {
        let val = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
        w[t] = circular_shift(1, val);
        t += 1;
    }
    let mut a = h[0];
    let mut b = h[1];
    let mut c = h[2];
    let mut d = h[3];
    let mut e = h[4];
    let mut temp: u32;
    t = 0;
    while t < 20 {
        temp = circular_shift(5, a) + (b & c | !b & d) + e + w[t] + K0;
        e = d;
        d = c;
        c = circular_shift(30, b);
        b = a;
        a = temp;
        t += 1;
    }
    while t < 40 {
        temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K1;
        e = d;
        d = c;
        c = circular_shift(30, b);
        b = a;
        a = temp;
        t += 1;
    }
    while t < 60 {
        temp =
            circular_shift(5, a) + (b & c | b & d | c & d) + e + w[t] +
                K2;
        e = d;
        d = c;
        c = circular_shift(30, b);
        b = a;
        a = temp;
        t += 1;
    }
    while t < 80 {
        temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K3;
        e = d;
        d = c;
        c = circular_shift(30, b);
        b = a;
        a = temp;
        t += 1;
    }
    h[0] += a;
    h[1] += b;
    h[2] += c;
    h[3] += d;
    h[4] += e;
}

fn circular_shift(bits: u32, word: u32) -> u32 {
    word << bits as usize | word >> (32u32 - bits) as usize
}

fn mk_result(st: &mut Sha1, rs: &mut [u8]) {
    if !st.computed {
        let st_h = &mut st.h;
        st.buffer.standard_padding(8, |d: &[u8]| { process_msg_block(d, &mut *st_h) });
        write_u32_be(st.buffer.next(4), (st.length_bits >> 32) as u32 );
        write_u32_be(st.buffer.next(4), st.length_bits as u32);
        process_msg_block(st.buffer.full_buffer(), st_h);

        st.computed = true;
    }

    write_u32_be(&mut rs[0..4], st.h[0]);
    write_u32_be(&mut rs[4..8], st.h[1]);
    write_u32_be(&mut rs[8..12], st.h[2]);
    write_u32_be(&mut rs[12..16], st.h[3]);
    write_u32_be(&mut rs[16..20], st.h[4]);
}

impl Sha1 {
    /// Construct a `sha` object
    pub fn new() -> Sha1 {
        let mut st = Sha1 {
            h: [0u32; DIGEST_BUF_LEN],
            length_bits: 0u64,
            buffer: FixedBuffer64::new(),
            computed: false,
        };
        st.reset();
        st
    }
}

impl Digest for Sha1 {
    fn reset(&mut self) {
        self.length_bits = 0;
        self.h[0] = 0x67452301u32;
        self.h[1] = 0xEFCDAB89u32;
        self.h[2] = 0x98BADCFEu32;
        self.h[3] = 0x10325476u32;
        self.h[4] = 0xC3D2E1F0u32;
        self.buffer.reset();
        self.computed = false;
    }
    fn input(&mut self, msg: &[u8]) { add_input(self, msg); }
    fn result(&mut self, out: &mut [u8]) { mk_result(self, out) }
    fn output_bits(&self) -> usize { 160 }
    fn block_size(&self) -> usize { 64 }
}

#[cfg(test)]
mod tests {
    use cryptoutil::test::test_digest_1million_random;
    use digest::Digest;
    use sha1::Sha1;

    #[derive(Clone)]
    struct Test {
        input: &'static str,
        output: Vec<u8>,
        output_str: &'static str,
    }

    #[test]
    fn test() {
        let tests = vec![
            // Test messages from FIPS 180-1
            Test {
                input: "abc",
                output: vec![
                    0xA9u8, 0x99u8, 0x3Eu8, 0x36u8,
                    0x47u8, 0x06u8, 0x81u8, 0x6Au8,
                    0xBAu8, 0x3Eu8, 0x25u8, 0x71u8,
                    0x78u8, 0x50u8, 0xC2u8, 0x6Cu8,
                    0x9Cu8, 0xD0u8, 0xD8u8, 0x9Du8,
                ],
                output_str: "a9993e364706816aba3e25717850c26c9cd0d89d"
            },
            Test {
                input:
                     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
                output: vec![
                    0x84u8, 0x98u8, 0x3Eu8, 0x44u8,
                    0x1Cu8, 0x3Bu8, 0xD2u8, 0x6Eu8,
                    0xBAu8, 0xAEu8, 0x4Au8, 0xA1u8,
                    0xF9u8, 0x51u8, 0x29u8, 0xE5u8,
                    0xE5u8, 0x46u8, 0x70u8, 0xF1u8,
                ],
                output_str: "84983e441c3bd26ebaae4aa1f95129e5e54670f1"
            },
            // Examples from wikipedia
            Test {
                input: "The quick brown fox jumps over the lazy dog",
                output: vec![
                    0x2fu8, 0xd4u8, 0xe1u8, 0xc6u8,
                    0x7au8, 0x2du8, 0x28u8, 0xfcu8,
                    0xedu8, 0x84u8, 0x9eu8, 0xe1u8,
                    0xbbu8, 0x76u8, 0xe7u8, 0x39u8,
                    0x1bu8, 0x93u8, 0xebu8, 0x12u8,
                ],
                output_str: "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
            },
            Test {
                input: "The quick brown fox jumps over the lazy cog",
                output: vec![
                    0xdeu8, 0x9fu8, 0x2cu8, 0x7fu8,
                    0xd2u8, 0x5eu8, 0x1bu8, 0x3au8,
                    0xfau8, 0xd3u8, 0xe8u8, 0x5au8,
                    0x0bu8, 0xd1u8, 0x7du8, 0x9bu8,
                    0x10u8, 0x0du8, 0xb4u8, 0xb3u8,
                ],
                output_str: "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3",
            },
        ];

        // Test that it works when accepting the message all at once

        let mut out = [0u8; 20];

        let mut sh = box Sha1::new();
        for t in tests.iter() {
            (*sh).input_str(t.input);
            sh.result(&mut out);
            assert!(t.output[] == out[]);

            let out_str = (*sh).result_str();
            assert_eq!(out_str.len(), 40);
            assert!(&out_str[] == t.output_str);

            sh.reset();
        }

        // Test that it works when accepting the message in pieces
        for t in tests.iter() {
            let len = t.input.len();
            let mut left = len;
            while left > 0u {
                let take = (left + 1u) / 2u;
                (*sh).input_str(&t.input[len - left..take + len - left]);
                left = left - take;
            }
            sh.result(&mut out);
            assert!(t.output[] == out[]);

            let out_str = (*sh).result_str();
            assert_eq!(out_str.len(), 40);
            assert!(&out_str[] == t.output_str);

            sh.reset();
        }
    }

    #[test]
    fn test_1million_random_sha1() {
        let mut sh = Sha1::new();
        test_digest_1million_random(
            &mut sh,
            64,
            "34aa973cd4c4daa4f61eeb2bdbad27316534016f");
    }
}

#[cfg(test)]
mod bench {
    use test::Bencher;
    use digest::Digest;
    use sha1::Sha1;

    #[bench]
    pub fn sha1_10(bh: & mut Bencher) {
        let mut sh = Sha1::new();
        let bytes = [1u8; 10];
        bh.iter( || {
            sh.input(&bytes);
        });
        bh.bytes = bytes.len() as u64;
    }

    #[bench]
    pub fn sha1_1k(bh: & mut Bencher) {
        let mut sh = Sha1::new();
        let bytes = [1u8; 1024];
        bh.iter( || {
            sh.input(&bytes);
        });
        bh.bytes = bytes.len() as u64;
    }

    #[bench]
    pub fn sha1_64k(bh: & mut Bencher) {
        let mut sh = Sha1::new();
        let bytes = [1u8; 65536];
        bh.iter( || {
            sh.input(&bytes);
        });
        bh.bytes = bytes.len() as u64;
    }

}
<commit_msg>Pick more appropriate int types for sha1<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.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.

/*!
 * An implementation of the SHA-1 cryptographic hash.
 *
 * First create a `sha1` object using the `sha1` constructor, then
 * feed it input using the `input` or `input_str` methods, which may be
 * called any number of times.
 *
 * After the entire input has been fed to the hash read the result using
 * the `result` or `result_str` methods.
 *
 * The `sha1` object may be reused to create multiple hashes by calling
 * the `reset` method.
 */

use cryptoutil::{write_u32_be, read_u32v_be, add_bytes_to_bits, FixedBuffer, FixedBuffer64,
    StandardPadding};
use digest::Digest;

/*
 * A SHA-1 implementation derived from Paul E. Jones's reference
 * implementation, which is written for clarity, not speed. At some
 * point this will want to be rewritten.
 */

// Some unexported constants
const DIGEST_BUF_LEN: usize = 5;
const WORK_BUF_LEN: usize = 80;
const K0: u32 = 0x5A827999u32;
const K1: u32 = 0x6ED9EBA1u32;
const K2: u32 = 0x8F1BBCDCu32;
const K3: u32 = 0xCA62C1D6u32;

/// Structure representing the state of a Sha1 computation
#[derive(Copy)]
pub struct Sha1 {
    h: [u32; DIGEST_BUF_LEN],
    length_bits: u64,
    buffer: FixedBuffer64,
    computed: bool,
}

fn add_input(st: &mut Sha1, msg: &[u8]) {
    assert!((!st.computed));
    // Assumes that msg.len() can be converted to u64 without overflow
    st.length_bits = add_bytes_to_bits(st.length_bits, msg.len() as u64);
    let st_h = &mut st.h;
    st.buffer.input(msg, |d: &[u8]| {process_msg_block(d, &mut *st_h); });
}

fn process_msg_block(data: &[u8], h: &mut [u32; DIGEST_BUF_LEN]) {
    let mut w = [0u32; WORK_BUF_LEN];

    // Initialize the first 16 words of the vector w
    read_u32v_be(&mut w[0..16], data);

    // Initialize the rest of vector w
    let mut t = 16; // loop counter
    while t < 80 {
        let val = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
        w[t] = circular_shift(1, val);
        t += 1;
    }
    let mut a = h[0];
    let mut b = h[1];
    let mut c = h[2];
    let mut d = h[3];
    let mut e = h[4];
    let mut temp: u32;
    t = 0;
    while t < 20 {
        temp = circular_shift(5, a) + (b & c | !b & d) + e + w[t] + K0;
        e = d;
        d = c;
        c = circular_shift(30, b);
        b = a;
        a = temp;
        t += 1;
    }
    while t < 40 {
        temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K1;
        e = d;
        d = c;
        c = circular_shift(30, b);
        b = a;
        a = temp;
        t += 1;
    }
    while t < 60 {
        temp =
            circular_shift(5, a) + (b & c | b & d | c & d) + e + w[t] +
                K2;
        e = d;
        d = c;
        c = circular_shift(30, b);
        b = a;
        a = temp;
        t += 1;
    }
    while t < 80 {
        temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K3;
        e = d;
        d = c;
        c = circular_shift(30, b);
        b = a;
        a = temp;
        t += 1;
    }
    h[0] += a;
    h[1] += b;
    h[2] += c;
    h[3] += d;
    h[4] += e;
}

fn circular_shift(bits: u32, word: u32) -> u32 {
    word << bits as usize | word >> (32u32 - bits) as usize
}

fn mk_result(st: &mut Sha1, rs: &mut [u8]) {
    if !st.computed {
        let st_h = &mut st.h;
        st.buffer.standard_padding(8, |d: &[u8]| { process_msg_block(d, &mut *st_h) });
        write_u32_be(st.buffer.next(4), (st.length_bits >> 32) as u32 );
        write_u32_be(st.buffer.next(4), st.length_bits as u32);
        process_msg_block(st.buffer.full_buffer(), st_h);

        st.computed = true;
    }

    write_u32_be(&mut rs[0..4], st.h[0]);
    write_u32_be(&mut rs[4..8], st.h[1]);
    write_u32_be(&mut rs[8..12], st.h[2]);
    write_u32_be(&mut rs[12..16], st.h[3]);
    write_u32_be(&mut rs[16..20], st.h[4]);
}

impl Sha1 {
    /// Construct a `sha` object
    pub fn new() -> Sha1 {
        let mut st = Sha1 {
            h: [0u32; DIGEST_BUF_LEN],
            length_bits: 0u64,
            buffer: FixedBuffer64::new(),
            computed: false,
        };
        st.reset();
        st
    }
}

impl Digest for Sha1 {
    fn reset(&mut self) {
        self.length_bits = 0;
        self.h[0] = 0x67452301u32;
        self.h[1] = 0xEFCDAB89u32;
        self.h[2] = 0x98BADCFEu32;
        self.h[3] = 0x10325476u32;
        self.h[4] = 0xC3D2E1F0u32;
        self.buffer.reset();
        self.computed = false;
    }
    fn input(&mut self, msg: &[u8]) { add_input(self, msg); }
    fn result(&mut self, out: &mut [u8]) { mk_result(self, out) }
    fn output_bits(&self) -> usize { 160 }
    fn block_size(&self) -> usize { 64 }
}

#[cfg(test)]
mod tests {
    use cryptoutil::test::test_digest_1million_random;
    use digest::Digest;
    use sha1::Sha1;

    #[derive(Clone)]
    struct Test {
        input: &'static str,
        output: Vec<u8>,
        output_str: &'static str,
    }

    #[test]
    fn test() {
        let tests = vec![
            // Test messages from FIPS 180-1
            Test {
                input: "abc",
                output: vec![
                    0xA9u8, 0x99u8, 0x3Eu8, 0x36u8,
                    0x47u8, 0x06u8, 0x81u8, 0x6Au8,
                    0xBAu8, 0x3Eu8, 0x25u8, 0x71u8,
                    0x78u8, 0x50u8, 0xC2u8, 0x6Cu8,
                    0x9Cu8, 0xD0u8, 0xD8u8, 0x9Du8,
                ],
                output_str: "a9993e364706816aba3e25717850c26c9cd0d89d"
            },
            Test {
                input:
                     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
                output: vec![
                    0x84u8, 0x98u8, 0x3Eu8, 0x44u8,
                    0x1Cu8, 0x3Bu8, 0xD2u8, 0x6Eu8,
                    0xBAu8, 0xAEu8, 0x4Au8, 0xA1u8,
                    0xF9u8, 0x51u8, 0x29u8, 0xE5u8,
                    0xE5u8, 0x46u8, 0x70u8, 0xF1u8,
                ],
                output_str: "84983e441c3bd26ebaae4aa1f95129e5e54670f1"
            },
            // Examples from wikipedia
            Test {
                input: "The quick brown fox jumps over the lazy dog",
                output: vec![
                    0x2fu8, 0xd4u8, 0xe1u8, 0xc6u8,
                    0x7au8, 0x2du8, 0x28u8, 0xfcu8,
                    0xedu8, 0x84u8, 0x9eu8, 0xe1u8,
                    0xbbu8, 0x76u8, 0xe7u8, 0x39u8,
                    0x1bu8, 0x93u8, 0xebu8, 0x12u8,
                ],
                output_str: "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
            },
            Test {
                input: "The quick brown fox jumps over the lazy cog",
                output: vec![
                    0xdeu8, 0x9fu8, 0x2cu8, 0x7fu8,
                    0xd2u8, 0x5eu8, 0x1bu8, 0x3au8,
                    0xfau8, 0xd3u8, 0xe8u8, 0x5au8,
                    0x0bu8, 0xd1u8, 0x7du8, 0x9bu8,
                    0x10u8, 0x0du8, 0xb4u8, 0xb3u8,
                ],
                output_str: "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3",
            },
        ];

        // Test that it works when accepting the message all at once

        let mut out = [0u8; 20];

        let mut sh = box Sha1::new();
        for t in tests.iter() {
            (*sh).input_str(t.input);
            sh.result(&mut out);
            assert!(t.output[] == out[]);

            let out_str = (*sh).result_str();
            assert_eq!(out_str.len(), 40);
            assert!(&out_str[] == t.output_str);

            sh.reset();
        }

        // Test that it works when accepting the message in pieces
        for t in tests.iter() {
            let len = t.input.len();
            let mut left = len;
            while left > 0 {
                let take = (left + 1) / 2;
                (*sh).input_str(&t.input[len - left..take + len - left]);
                left = left - take;
            }
            sh.result(&mut out);
            assert!(t.output[] == out[]);

            let out_str = (*sh).result_str();
            assert_eq!(out_str.len(), 40);
            assert!(&out_str[] == t.output_str);

            sh.reset();
        }
    }

    #[test]
    fn test_1million_random_sha1() {
        let mut sh = Sha1::new();
        test_digest_1million_random(
            &mut sh,
            64,
            "34aa973cd4c4daa4f61eeb2bdbad27316534016f");
    }
}

#[cfg(test)]
mod bench {
    use test::Bencher;
    use digest::Digest;
    use sha1::Sha1;

    #[bench]
    pub fn sha1_10(bh: & mut Bencher) {
        let mut sh = Sha1::new();
        let bytes = [1u8; 10];
        bh.iter( || {
            sh.input(&bytes);
        });
        bh.bytes = bytes.len() as u64;
    }

    #[bench]
    pub fn sha1_1k(bh: & mut Bencher) {
        let mut sh = Sha1::new();
        let bytes = [1u8; 1024];
        bh.iter( || {
            sh.input(&bytes);
        });
        bh.bytes = bytes.len() as u64;
    }

    #[bench]
    pub fn sha1_64k(bh: & mut Bencher) {
        let mut sh = Sha1::new();
        let bytes = [1u8; 65536];
        bh.iter( || {
            sh.input(&bytes);
        });
        bh.bytes = bytes.len() as u64;
    }

}
<|endoftext|>


<commit_before>use std::any::Any;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::panic;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, AtomicBool, ATOMIC_USIZE_INIT, Ordering};
use std::thread;

use Future;
use executor::{DEFAULT, Executor};
use lock::Lock;
use slot::Slot;

/// A structure representing one "task", or thread of execution throughout the
/// lifetime of a set of futures.
///
/// It's intended that futures are composed together to form a large "task" of
/// futures which is driven as a whole throughout its lifetime. This task is
/// persistent for the entire lifetime of the future until its completion,
/// carrying any local data and such.
///
/// Currently tasks serve two primary purposes:
///
/// * They're used to drive futures to completion, e.g. executors (more to be
///   changed here soon).
/// * They store task local data. That is, any task can contain any number of
///   pieces of arbitrary data which can be accessed at a later date. The data
///   is owned and carried in the task itself, and `TaskData` handles are used
///   to access the internals.
///
/// This structure is likely to expand more customizable functionality over
/// time! That is, it's not quite done yet...
pub struct Task {
    id: usize,
    ready: usize,
    list: Box<Any + Send>,
    handle: TaskHandle,
}

/// A scoped version of a task, returned by the `Task::scoped` method.
pub struct ScopedTask<'a> {
    task: &'a mut Task,
    reset: bool,
}

/// A handle to a task that can be sent to other threads.
///
/// Created by the `Task::handle` method.
#[derive(Clone)]
pub struct TaskHandle {
    inner: Arc<Inner>,
}

struct Inner {
    id: usize,
    slot: Slot<(Task, Box<Future<Item=(), Error=()>>)>,
    registered: AtomicBool,
    list: Lock<Box<Any + Send + Sync>>,
}

/// A reference to a piece of data that's stored inside of a `Task`.
///
/// This can be used with the `Task::get` and `Task::get_mut` methods to access
/// data inside of tasks.
pub struct TaskData {
    id: usize,
    ptr: *mut A,
}

unsafe impl Send for TaskData {}
unsafe impl Sync for TaskData {}

/// dox
pub struct TaskNotifyData {
    id: usize,
    ptr: *mut A,
}

unsafe impl Send for TaskNotifyData {}
unsafe impl Sync for TaskNotifyData {}

impl Task {
    /// Creates a new task ready to drive a future.
    pub fn new() -> Task {
        static NEXT: AtomicUsize = ATOMIC_USIZE_INIT;

        // TODO: Handle this overflow not by panicking, but for now also ensure
        //       that this aborts the process.
        let id = NEXT.fetch_add(1, Ordering::SeqCst);
        if id >= usize::max_value() - 50_000 {
            panic!("overflow in number of tasks created");
        }

        Task {
            id: id,
            list: Box::new(()),
            ready: 0,
            handle: TaskHandle {
                inner: Arc::new(Inner {
                    id: id,
                    slot: Slot::new(None),
                    registered: AtomicBool::new(false),
                    list: Lock::new(Box::new(())),
                }),
            },
        }
    }

    /// Inserts a new piece of task-local data into this task, returning a
    /// reference to it.
    ///
    /// Ownership of the data will be transferred to the task, and the data will
    /// be destroyed when the task itself is destroyed. The returned value can
    /// be passed to the `Task::{get, get_mut}` methods to get a reference back
    /// to the original data.
    ///
    /// Note that the returned handle is cloneable and copyable and can be sent
    /// to other futures which will be associated with the same task. All
    /// futures will then have access to this data when passed the reference
    /// back.
    pub fn insert(&mut self, a: A) -> TaskData
        where A: Any + Send + 'static,
    {
        // Right now our list of task-local data is just stored as a linked
        // list, so allocate a new node and insert it into the list.
        struct Node<T: ?Sized> {
            _next: Box<Any + Send>,
            data: T,
        }
        let prev = mem::replace(&mut self.list, Box::new(()));
        let mut next = Box::new(Node { _next: prev, data: a });
        let ret = TaskData { id: self.id, ptr: &mut next.data };
        self.list = next;
        return ret
    }

    /// dox
    pub fn insert_notify(&mut self, a: A) -> TaskNotifyData
        where A: Any + Send + Sync + 'static,
    {
        // Right now our list of task-local data is just stored as a linked
        // list, so allocate a new node and insert it into the list.
        struct Node<T: ?Sized> {
            _next: Box<Any + Sync + Send>,
            data: T,
        }
        let mut list = self.handle.inner.list.try_lock().unwrap();
        let prev = mem::replace(&mut *list, Box::new(()));
        let mut next = Box::new(Node { _next: prev, data: a });
        let ret = TaskNotifyData { id: self.id, ptr: &mut next.data };
        *list = next;
        return ret
    }

    /// Get a reference to the task-local data inside this task.
    ///
    /// This method should be passed a handle previously returned by
    /// `Task::insert`. That handle, when passed back into this method, will
    /// retrieve a reference to the original data.
    ///
    /// # Panics
    ///
    /// This method will panic if `data` does not belong to this task. That is,
    /// if another task generated the `data` handle passed in, this method will
    /// panic.
    pub fn get(&self, data: &TaskData) -> &A {
        assert_eq!(data.id, self.id);
        unsafe { &*data.ptr }
    }

    /// Get a mutable reference to the task-local data inside this task.
    ///
    /// This method should be passed a handle previously returned by
    /// `Task::insert`. That handle, when passed back into this method, will
    /// retrieve a reference to the original data.
    ///
    /// # Panics
    ///
    /// This method will panic if `data` does not belong to this task. That is,
    /// if another task generated the `data` handle passed in, this method will
    /// panic.
    pub fn get_mut(&mut self, data: &TaskData) -> &mut A {
        assert_eq!(data.id, self.id);
        unsafe { &mut *data.ptr }
    }

    /// During the `Future::schedule` method, notify to the task that a value is
    /// immediately ready.
    ///
    /// This method, more optimized than `TaskHandle::notify`, will inform the
    /// task that the future which is being scheduled is immediately ready to be
    /// `poll`ed again.
    pub fn notify(&mut self) {
        // TODO: optimize this
        self.handle().notify()
    }

    /// Gets a handle to this task which can be cloned to a piece of
    /// `Send+'static` data.
    ///
    /// This handle returned can be used to notify the task that a future is
    /// ready to get polled again. The returned handle implements the `Clone`
    /// trait and all clones will refer to this same task.
    ///
    /// Note that if data is immediately ready then the `Task::notify` method
    /// should be preferred.
    pub fn handle(&self) -> &TaskHandle {
        &self.handle
    }

    /// Creates a new temporary "scoped task" for setting the ready tokens.
    ///
    /// A scoped task is simply a borrowed version of this task with an
    /// associated destructor that restores the ready set when it goes out of
    /// scope. This returned object can use the `ScopedTask::ready` method to
    /// indicate that all further calls to `Task::may_contain` will return true.
    ///
    /// This can be useful when one call to `poll` may poll multiple futures or
    /// streams, but after one has been resolved the others may all immediately
    /// be ready so they shouldn't use the same readiness token sets as the
    /// previous one.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use futures::Task;
    ///
    /// fn poll(task: &mut Task) {
    ///     task.may_contain(1); // may return true or false
    ///
    ///     {
    ///         let mut task = task.scoped();
    ///
    ///         task.may_contain(1); // returns the same as before
    ///
    ///         task.ready();
    ///         assert!(task.may_contain(1)); // always returns true
    ///     }
    ///
    ///     task.may_contain(1); // returns the same as the first call
    /// }
    /// ```
    // TODO: terrible name
    pub fn scoped(&mut self) -> ScopedTask {
        ScopedTask { task: self, reset: false }
    }

    /// Consumes this task to run a future to completion.
    ///
    /// This function will consume the task provided and the task will be used
    /// to execute the `future` provided until it has been completed. The future
    /// wil be `poll`'ed until it is resolved, at which point the `Result<(),
    /// ()>` will be discarded.
    ///
    /// The future will be `poll`ed on the threads that events arrive on. That
    /// is, this method does not attempt to control which thread a future is
    /// polled on.
    ///
    /// # Panics
    ///
    /// Currently, if `poll` panics, then this method will propagate the panic
    /// to the thread that `poll` was called on. This is bad and it will change.
    pub fn run(self, mut future: Box<Future<Item=(), Error=()>>) {
        let mut me = self;
        loop {
            // Note that we need to poll at least once as the wake callback may
            // have received an empty set of tokens, but that's still a valid
            // reason to poll a future.
            assert_eq!(me.ready, 0);
            // me.tokens = me.handle.inner.tokens.take();
            let result = catch_unwind(move || {
                (future.poll(&mut me), future, me)
            });
            match result {
                Ok((ref r, _, _)) if r.is_ready() => return,
                Ok((_, f, t)) => {
                    future = f;
                    me = t;
                }
                // TODO: do something smarter
                Err(e) => panic::resume_unwind(e),
            }
            future = match future.tailcall() {
                Some(f) => f,
                None => future,
            };
            break
            // if !me.handle.inner.tokens.any() {
            //     break
            // }
        }

        // Ok, we've seen that there are no tokens which show interest in the
        // future. Schedule interest on the future for when something is ready
        // and then relinquish the future and the forget back to the slot, which
        // will then pick it up once a wake callback has fired.
        future.schedule(&mut me);

        let inner = me.handle.inner.clone();
        inner.slot.try_produce((me, future)).ok().unwrap();
    }
}

fn catch_unwind<F, U>(f: F) -> thread::Result
    where F: FnOnce() -> U + Send + 'static,
{
    panic::catch_unwind(panic::AssertUnwindSafe(f))
}

impl TaskHandle {
    /// Returns whether this task handle and another point to the same task.
    ///
    /// In other words, this method returns whether `notify` would end up
    /// notifying the same task. If two task handles need to be notified but
    /// they are equivalent, then only one needs to be actually notified.
    pub fn equivalent(&self, other: &TaskHandle) -> bool {
        &*self.inner as *const _ == &*other.inner as *const _
    }

    /// dox
    pub fn get(&self, data: &TaskNotifyData) -> &A {
        assert_eq!(data.id, self.inner.id);
        unsafe { &*data.ptr }
    }

    /// Notify the associated task that a future is ready to get polled.
    ///
    /// Futures should use this method to ensure that when a future can make
    /// progress as `Task` is notified that it should continue to `poll` the
    /// future at a later date.
    ///
    /// Currently it's guaranteed that if `notify` is called that `poll` will be
    /// scheduled to get called at some point in the future. A `poll` may
    /// already be running on another thread, but this will ensure that a poll
    /// happens again to receive this notification.
    pub fn notify(&self) {
        // First, see if we can actually register an `on_full` callback. The
        // `Slot` requires that only one registration happens, and this flag
        // guards that.
        if self.inner.registered.swap(true, Ordering::SeqCst) {
            return
        }

        // If we won the race to register a callback, do so now. Once the slot
        // is resolve we allow another registration **before we poll again**.
        // This allows any future which may be somewhat badly behaved to be
        // compatible with this.
        self.inner.slot.on_full(|slot| {
            let (task, future) = slot.try_consume().ok().unwrap();
            task.handle.inner.registered.store(false, Ordering::SeqCst);
            DEFAULT.execute(|| task.run(future))
        });
    }
}

impl<'a> ScopedTask<'a> {
    /// Flag this scoped task as "all events are ready".
    ///
    /// In other words, once this method is called, all future calls to
    /// `may_contain` on the associated `Task` will return `true`.
    pub fn ready(&mut self) -> &mut ScopedTask<'a>{
        if !self.reset {
            self.reset = true;
            self.task.ready += 1;
        }
        self
    }
}

impl<'a> Deref for ScopedTask<'a> {
    type Target = Task;
    fn deref(&self) -> &Task {
        &*self.task
    }
}

impl<'a> DerefMut for ScopedTask<'a> {
    fn deref_mut(&mut self) -> &mut Task {
        &mut *self.task
    }
}

impl<'a> Drop for ScopedTask<'a> {
    fn drop(&mut self) {
        if self.reset {
            self.task.ready -= 1;
        }
    }
}

impl Clone for TaskData {
    fn clone(&self) -> TaskData {
        TaskData {
            id: self.id,
            ptr: self.ptr,
        }
    }
}

impl Copy for TaskData {}

impl Clone for TaskNotifyData {
    fn clone(&self) -> TaskNotifyData {
        TaskNotifyData {
            id: self.id,
            ptr: self.ptr,
        }
    }
}

impl Copy for TaskNotifyData {}
<commit_msg>Remove bad doc-block on Task<commit_after>use std::any::Any;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::panic;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, AtomicBool, ATOMIC_USIZE_INIT, Ordering};
use std::thread;

use Future;
use executor::{DEFAULT, Executor};
use lock::Lock;
use slot::Slot;

/// A structure representing one "task", or thread of execution throughout the
/// lifetime of a set of futures.
///
/// It's intended that futures are composed together to form a large "task" of
/// futures which is driven as a whole throughout its lifetime. This task is
/// persistent for the entire lifetime of the future until its completion,
/// carrying any local data and such.
///
/// Currently tasks serve two primary purposes:
///
/// * They're used to drive futures to completion, e.g. executors (more to be
///   changed here soon).
/// * They store task local data. That is, any task can contain any number of
///   pieces of arbitrary data which can be accessed at a later date. The data
///   is owned and carried in the task itself, and `TaskData` handles are used
///   to access the internals.
///
/// This structure is likely to expand more customizable functionality over
/// time! That is, it's not quite done yet...
pub struct Task {
    id: usize,
    ready: usize,
    list: Box<Any + Send>,
    handle: TaskHandle,
}

/// A scoped version of a task, returned by the `Task::scoped` method.
pub struct ScopedTask<'a> {
    task: &'a mut Task,
    reset: bool,
}

/// A handle to a task that can be sent to other threads.
///
/// Created by the `Task::handle` method.
#[derive(Clone)]
pub struct TaskHandle {
    inner: Arc<Inner>,
}

struct Inner {
    id: usize,
    slot: Slot<(Task, Box<Future<Item=(), Error=()>>)>,
    registered: AtomicBool,
    list: Lock<Box<Any + Send + Sync>>,
}

/// A reference to a piece of data that's stored inside of a `Task`.
///
/// This can be used with the `Task::get` and `Task::get_mut` methods to access
/// data inside of tasks.
pub struct TaskData {
    id: usize,
    ptr: *mut A,
}

unsafe impl Send for TaskData {}
unsafe impl Sync for TaskData {}

/// dox
pub struct TaskNotifyData {
    id: usize,
    ptr: *mut A,
}

unsafe impl Send for TaskNotifyData {}
unsafe impl Sync for TaskNotifyData {}

impl Task {
    /// Creates a new task ready to drive a future.
    pub fn new() -> Task {
        static NEXT: AtomicUsize = ATOMIC_USIZE_INIT;

        // TODO: Handle this overflow not by panicking, but for now also ensure
        //       that this aborts the process.
        let id = NEXT.fetch_add(1, Ordering::SeqCst);
        if id >= usize::max_value() - 50_000 {
            panic!("overflow in number of tasks created");
        }

        Task {
            id: id,
            list: Box::new(()),
            ready: 0,
            handle: TaskHandle {
                inner: Arc::new(Inner {
                    id: id,
                    slot: Slot::new(None),
                    registered: AtomicBool::new(false),
                    list: Lock::new(Box::new(())),
                }),
            },
        }
    }

    /// Inserts a new piece of task-local data into this task, returning a
    /// reference to it.
    ///
    /// Ownership of the data will be transferred to the task, and the data will
    /// be destroyed when the task itself is destroyed. The returned value can
    /// be passed to the `Task::{get, get_mut}` methods to get a reference back
    /// to the original data.
    ///
    /// Note that the returned handle is cloneable and copyable and can be sent
    /// to other futures which will be associated with the same task. All
    /// futures will then have access to this data when passed the reference
    /// back.
    pub fn insert(&mut self, a: A) -> TaskData
        where A: Any + Send + 'static,
    {
        // Right now our list of task-local data is just stored as a linked
        // list, so allocate a new node and insert it into the list.
        struct Node<T: ?Sized> {
            _next: Box<Any + Send>,
            data: T,
        }
        let prev = mem::replace(&mut self.list, Box::new(()));
        let mut next = Box::new(Node { _next: prev, data: a });
        let ret = TaskData { id: self.id, ptr: &mut next.data };
        self.list = next;
        return ret
    }

    /// dox
    pub fn insert_notify(&mut self, a: A) -> TaskNotifyData
        where A: Any + Send + Sync + 'static,
    {
        // Right now our list of task-local data is just stored as a linked
        // list, so allocate a new node and insert it into the list.
        struct Node<T: ?Sized> {
            _next: Box<Any + Sync + Send>,
            data: T,
        }
        let mut list = self.handle.inner.list.try_lock().unwrap();
        let prev = mem::replace(&mut *list, Box::new(()));
        let mut next = Box::new(Node { _next: prev, data: a });
        let ret = TaskNotifyData { id: self.id, ptr: &mut next.data };
        *list = next;
        return ret
    }

    /// Get a reference to the task-local data inside this task.
    ///
    /// This method should be passed a handle previously returned by
    /// `Task::insert`. That handle, when passed back into this method, will
    /// retrieve a reference to the original data.
    ///
    /// # Panics
    ///
    /// This method will panic if `data` does not belong to this task. That is,
    /// if another task generated the `data` handle passed in, this method will
    /// panic.
    pub fn get(&self, data: &TaskData) -> &A {
        assert_eq!(data.id, self.id);
        unsafe { &*data.ptr }
    }

    /// Get a mutable reference to the task-local data inside this task.
    ///
    /// This method should be passed a handle previously returned by
    /// `Task::insert`. That handle, when passed back into this method, will
    /// retrieve a reference to the original data.
    ///
    /// # Panics
    ///
    /// This method will panic if `data` does not belong to this task. That is,
    /// if another task generated the `data` handle passed in, this method will
    /// panic.
    pub fn get_mut(&mut self, data: &TaskData) -> &mut A {
        assert_eq!(data.id, self.id);
        unsafe { &mut *data.ptr }
    }

    /// During the `Future::schedule` method, notify to the task that a value is
    /// immediately ready.
    ///
    /// This method, more optimized than `TaskHandle::notify`, will inform the
    /// task that the future which is being scheduled is immediately ready to be
    /// `poll`ed again.
    pub fn notify(&mut self) {
        // TODO: optimize this
        self.handle().notify()
    }

    /// Gets a handle to this task which can be cloned to a piece of
    /// `Send+'static` data.
    ///
    /// This handle returned can be used to notify the task that a future is
    /// ready to get polled again. The returned handle implements the `Clone`
    /// trait and all clones will refer to this same task.
    ///
    /// Note that if data is immediately ready then the `Task::notify` method
    /// should be preferred.
    pub fn handle(&self) -> &TaskHandle {
        &self.handle
    }

    /// dox
    // TODO: terrible name, remove this
    pub fn scoped(&mut self) -> ScopedTask {
        ScopedTask { task: self, reset: false }
    }

    /// Consumes this task to run a future to completion.
    ///
    /// This function will consume the task provided and the task will be used
    /// to execute the `future` provided until it has been completed. The future
    /// wil be `poll`'ed until it is resolved, at which point the `Result<(),
    /// ()>` will be discarded.
    ///
    /// The future will be `poll`ed on the threads that events arrive on. That
    /// is, this method does not attempt to control which thread a future is
    /// polled on.
    ///
    /// # Panics
    ///
    /// Currently, if `poll` panics, then this method will propagate the panic
    /// to the thread that `poll` was called on. This is bad and it will change.
    pub fn run(self, mut future: Box<Future<Item=(), Error=()>>) {
        let mut me = self;
        loop {
            // Note that we need to poll at least once as the wake callback may
            // have received an empty set of tokens, but that's still a valid
            // reason to poll a future.
            assert_eq!(me.ready, 0);
            // me.tokens = me.handle.inner.tokens.take();
            let result = catch_unwind(move || {
                (future.poll(&mut me), future, me)
            });
            match result {
                Ok((ref r, _, _)) if r.is_ready() => return,
                Ok((_, f, t)) => {
                    future = f;
                    me = t;
                }
                // TODO: do something smarter
                Err(e) => panic::resume_unwind(e),
            }
            future = match future.tailcall() {
                Some(f) => f,
                None => future,
            };
            break
            // if !me.handle.inner.tokens.any() {
            //     break
            // }
        }

        // Ok, we've seen that there are no tokens which show interest in the
        // future. Schedule interest on the future for when something is ready
        // and then relinquish the future and the forget back to the slot, which
        // will then pick it up once a wake callback has fired.
        future.schedule(&mut me);

        let inner = me.handle.inner.clone();
        inner.slot.try_produce((me, future)).ok().unwrap();
    }
}

fn catch_unwind<F, U>(f: F) -> thread::Result
    where F: FnOnce() -> U + Send + 'static,
{
    panic::catch_unwind(panic::AssertUnwindSafe(f))
}

impl TaskHandle {
    /// Returns whether this task handle and another point to the same task.
    ///
    /// In other words, this method returns whether `notify` would end up
    /// notifying the same task. If two task handles need to be notified but
    /// they are equivalent, then only one needs to be actually notified.
    pub fn equivalent(&self, other: &TaskHandle) -> bool {
        &*self.inner as *const _ == &*other.inner as *const _
    }

    /// dox
    pub fn get(&self, data: &TaskNotifyData) -> &A {
        assert_eq!(data.id, self.inner.id);
        unsafe { &*data.ptr }
    }

    /// Notify the associated task that a future is ready to get polled.
    ///
    /// Futures should use this method to ensure that when a future can make
    /// progress as `Task` is notified that it should continue to `poll` the
    /// future at a later date.
    ///
    /// Currently it's guaranteed that if `notify` is called that `poll` will be
    /// scheduled to get called at some point in the future. A `poll` may
    /// already be running on another thread, but this will ensure that a poll
    /// happens again to receive this notification.
    pub fn notify(&self) {
        // First, see if we can actually register an `on_full` callback. The
        // `Slot` requires that only one registration happens, and this flag
        // guards that.
        if self.inner.registered.swap(true, Ordering::SeqCst) {
            return
        }

        // If we won the race to register a callback, do so now. Once the slot
        // is resolve we allow another registration **before we poll again**.
        // This allows any future which may be somewhat badly behaved to be
        // compatible with this.
        self.inner.slot.on_full(|slot| {
            let (task, future) = slot.try_consume().ok().unwrap();
            task.handle.inner.registered.store(false, Ordering::SeqCst);
            DEFAULT.execute(|| task.run(future))
        });
    }
}

impl<'a> ScopedTask<'a> {
    /// Flag this scoped task as "all events are ready".
    ///
    /// In other words, once this method is called, all future calls to
    /// `may_contain` on the associated `Task` will return `true`.
    pub fn ready(&mut self) -> &mut ScopedTask<'a>{
        if !self.reset {
            self.reset = true;
            self.task.ready += 1;
        }
        self
    }
}

impl<'a> Deref for ScopedTask<'a> {
    type Target = Task;
    fn deref(&self) -> &Task {
        &*self.task
    }
}

impl<'a> DerefMut for ScopedTask<'a> {
    fn deref_mut(&mut self) -> &mut Task {
        &mut *self.task
    }
}

impl<'a> Drop for ScopedTask<'a> {
    fn drop(&mut self) {
        if self.reset {
            self.task.ready -= 1;
        }
    }
}

impl Clone for TaskData {
    fn clone(&self) -> TaskData {
        TaskData {
            id: self.id,
            ptr: self.ptr,
        }
    }
}

impl Copy for TaskData {}

impl Clone for TaskNotifyData {
    fn clone(&self) -> TaskNotifyData {
        TaskNotifyData {
            id: self.id,
            ptr: self.ptr,
        }
    }
}

impl Copy for TaskNotifyData {}
<|endoftext|>


<commit_before>use board::*;
use piece::Piece;
use square::*;
use mv_list::*;
use mv::Move;
use gen::legal_moves;

#[derive(Clone)]
pub struct Tree {
    board: Board,
    stack: Vec<StackElem>,
}

#[derive(Clone)]
struct StackElem {
    pub key: u64,
    pub captured: Option<(Piece, Square)>,
    pub state: State,
}

impl Tree {
    pub fn new(fen: &str) -> Tree {
        let board = Board::from_fen(fen).unwrap();

        Tree {
            board: board,
            stack: Vec::new(),
        }
    }

    pub fn board(&self) -> &Board {
        self.board
    }

    pub fn count_legal_moves(&self) -> (bool, MoveCounter) {
        let mut move_counter = MoveCounter::new();
        let in_check = legal_moves(&self.board, &mut move_counter);

        (in_check, move_counter)
    }

    pub fn generate_legal_moves(&mut self) -> (bool, MoveVec) {
        let mut move_vec = MoveVec::new();
        let in_check = legal_moves(&self.board, &mut move_vec);
        (in_check, move_vec)
    }

    pub fn key(&self) -> u64 {
        self.board.hash_key()
    }

    pub fn depth(&self) -> usize {
        self.stack.len()
    }

    pub fn make(&mut self, mv: Move) {
        let before_state = self.board.state().clone();
        let key = self.board.hash_key();
        let capture = self.board.make(mv);

        self.stack.push(StackElem {
            key: key,
            captured: capture,
            state: before_state,
        })
    }

    pub fn unmake(&mut self, mv: Move) {
        let elem = self.stack.pop().unwrap();
        self.board.unmake(mv, elem.captured, &elem.state, elem.key);
    }
}

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

    #[test]
    fn test_key() {
        // Hash should not care what order moves are done in
        let mut tree = Tree::new(STARTING_POSITION_FEN);

        let key_init = tree.key();

        let mv_a = Move::new_push(D2, D4);
        let mv_b = Move::new_push(G7, G5);
        let mv_c = Move::new_push(B1, A3);
        let mv_d = Move::new_push(G5, G4);

        tree.make(mv_a);
        tree.make(mv_b);
        tree.make(mv_c);
        tree.make(mv_d);

        let key_after_moves = tree.key();

        tree.unmake(mv_d);
        tree.unmake(mv_c);
        tree.unmake(mv_b);
        tree.unmake(mv_a);

        assert_eq!(tree.key(), key_init);

        tree.make(mv_c);
        tree.make(mv_b);
        tree.make(mv_a);
        tree.make(mv_d);

        assert_eq!(tree.key(), key_after_moves);
    }
}<commit_msg>fix typoe<commit_after>use board::*;
use piece::Piece;
use square::*;
use mv_list::*;
use mv::Move;
use gen::legal_moves;

#[derive(Clone)]
pub struct Tree {
    board: Board,
    stack: Vec<StackElem>,
}

#[derive(Clone)]
struct StackElem {
    pub key: u64,
    pub captured: Option<(Piece, Square)>,
    pub state: State,
}

impl Tree {
    pub fn new(fen: &str) -> Tree {
        let board = Board::from_fen(fen).unwrap();

        Tree {
            board: board,
            stack: Vec::new(),
        }
    }

    pub fn board(&self) -> &Board {
        &self.board
    }

    pub fn count_legal_moves(&self) -> (bool, MoveCounter) {
        let mut move_counter = MoveCounter::new();
        let in_check = legal_moves(&self.board, &mut move_counter);

        (in_check, move_counter)
    }

    pub fn generate_legal_moves(&mut self) -> (bool, MoveVec) {
        let mut move_vec = MoveVec::new();
        let in_check = legal_moves(&self.board, &mut move_vec);
        (in_check, move_vec)
    }

    pub fn key(&self) -> u64 {
        self.board.hash_key()
    }

    pub fn depth(&self) -> usize {
        self.stack.len()
    }

    pub fn make(&mut self, mv: Move) {
        let before_state = self.board.state().clone();
        let key = self.board.hash_key();
        let capture = self.board.make(mv);

        self.stack.push(StackElem {
            key: key,
            captured: capture,
            state: before_state,
        })
    }

    pub fn unmake(&mut self, mv: Move) {
        let elem = self.stack.pop().unwrap();
        self.board.unmake(mv, elem.captured, &elem.state, elem.key);
    }
}

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

    #[test]
    fn test_key() {
        // Hash should not care what order moves are done in
        let mut tree = Tree::new(STARTING_POSITION_FEN);

        let key_init = tree.key();

        let mv_a = Move::new_push(D2, D4);
        let mv_b = Move::new_push(G7, G5);
        let mv_c = Move::new_push(B1, A3);
        let mv_d = Move::new_push(G5, G4);

        tree.make(mv_a);
        tree.make(mv_b);
        tree.make(mv_c);
        tree.make(mv_d);

        let key_after_moves = tree.key();

        tree.unmake(mv_d);
        tree.unmake(mv_c);
        tree.unmake(mv_b);
        tree.unmake(mv_a);

        assert_eq!(tree.key(), key_init);

        tree.make(mv_c);
        tree.make(mv_b);
        tree.make(mv_a);
        tree.make(mv_d);

        assert_eq!(tree.key(), key_after_moves);
    }
}<|endoftext|>


<commit_before>use rand::distributions::Alphanumeric;
use rand::{self, Rng};
use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use std::{io, str};

use error::IoResultExt;

fn tmpname(prefix: &OsStr, suffix: &OsStr, rand_len: usize) -> OsString {
    let mut buf = OsString::with_capacity(prefix.len() + suffix.len() + rand_len);
    buf.push(prefix);

    // Push each character in one-by-one. Unfortunately, this is the only
    // safe(ish) simple way to do this without allocating a temporary
    // String/Vec.
    unsafe {
        rand::thread_rng()
            .sample_iter(&Alphanumeric)
            .take(rand_len)
            .for_each(|b| buf.push(str::from_utf8_unchecked(&[b as u8])))
    }
    buf.push(suffix);
    return buf;
}

pub fn create_helper<F, R>(
    base: &Path,
    prefix: &OsStr,
    suffix: &OsStr,
    random_len: usize,
    f: F,
) -> io::Result<R>
where
    F: Fn(PathBuf) -> io::Result<R>,
{
    let num_retries = if random_len != 0 { ::NUM_RETRIES } else { 1 };

    for _ in 0..num_retries {
        let path = base.join(tmpname(prefix, suffix, random_len));
        return match f(path) {
            Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => continue,
            res => res,
        };
    }

    Err(io::Error::new(
        io::ErrorKind::AlreadyExists,
        "too many temporary files exist",
    ))
    .with_err_path(|| base)
}
<commit_msg>fix: remove unecessary return<commit_after>use rand::distributions::Alphanumeric;
use rand::{self, Rng};
use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use std::{io, str};

use error::IoResultExt;

fn tmpname(prefix: &OsStr, suffix: &OsStr, rand_len: usize) -> OsString {
    let mut buf = OsString::with_capacity(prefix.len() + suffix.len() + rand_len);
    buf.push(prefix);

    // Push each character in one-by-one. Unfortunately, this is the only
    // safe(ish) simple way to do this without allocating a temporary
    // String/Vec.
    unsafe {
        rand::thread_rng()
            .sample_iter(&Alphanumeric)
            .take(rand_len)
            .for_each(|b| buf.push(str::from_utf8_unchecked(&[b as u8])))
    }
    buf.push(suffix);
    buf
}

pub fn create_helper<F, R>(
    base: &Path,
    prefix: &OsStr,
    suffix: &OsStr,
    random_len: usize,
    f: F,
) -> io::Result<R>
where
    F: Fn(PathBuf) -> io::Result<R>,
{
    let num_retries = if random_len != 0 { ::NUM_RETRIES } else { 1 };

    for _ in 0..num_retries {
        let path = base.join(tmpname(prefix, suffix, random_len));
        return match f(path) {
            Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => continue,
            res => res,
        };
    }

    Err(io::Error::new(
        io::ErrorKind::AlreadyExists,
        "too many temporary files exist",
    ))
    .with_err_path(|| base)
}
<|endoftext|>


<commit_before>use std::env;
use std::fmt;
use std::io;

use ansi_term::Color;
use env_logger::LogBuilder;
use log::{LogLevel, LogLevelFilter, LogRecord};
use ring::rand::{SecureRandom, SystemRandom};
use time;

use super::v3::MAX_PADDING_LEN;

struct ColorLevel(LogLevel);

impl fmt::Display for ColorLevel {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {
            LogLevel::Trace => Color::Purple.paint("TRACE"),
            LogLevel::Debug => Color::Blue.paint("DEBUG"),
            LogLevel::Info => Color::Green.paint("INFO "),
            LogLevel::Warn => Color::Yellow.paint("WARN "),
            LogLevel::Error => Color::Red.paint("ERROR"),
        }.fmt(f)
    }
}

pub fn init_logger() {
    let format = |record: &LogRecord| {
        let now = time::now();
        let ms = now.tm_nsec / 1000 / 1000;
        let t = time::strftime("%Y-%m-%d %T", &now).unwrap();
        format!(
            "{}.{:03} [{}]  {}",
            t,
            ms,
            ColorLevel(record.level()),
            record.args()
        )
    };

    let mut builder = LogBuilder::new();
    builder.format(format).filter(None, LogLevelFilter::Info);

    if env::var("RUST_LOG").is_ok() {
        builder.parse(&env::var("RUST_LOG").unwrap());
    }

    if env::var("FAKIO_LOG").is_ok() {
        builder.parse(&env::var("FAKIO_LOG").unwrap());
    }

    builder.init().unwrap();
}

/// `MAX_PADDING_LEN 255`
///
/// +-------+----------+
/// |  len  |   bytes  |
/// +-------+----------+
/// | 1bytes| [0, 255] |
/// +-------+----------+
pub struct RandomBytes {
    len: usize,
    bytes: [u8; 1 + MAX_PADDING_LEN],
}

impl RandomBytes {
    pub fn new() -> io::Result<RandomBytes> {
        let mut padding = [0u8; 1 + MAX_PADDING_LEN];
        let rand = SystemRandom::new();

        // 1. rand len
        rand.fill(&mut padding[..1])
            .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("rand failed by {}", e)))?;

        // 2. rand data
        let len = padding[0] as usize;
        rand.fill(&mut padding[1..len + 1])
            .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("rand failed by {}", e)))?;
        Ok(RandomBytes {
            len: len,
            bytes: padding,
        })
    }

    #[inline]
    pub fn get(&self) -> &[u8] {
        &self.bytes[..self.len + 1]
    }
}

static CHARS: &'static [u8] = b"0123456789abcdef";

pub fn to_hex(slice: &[u8]) -> String {
    let mut v = Vec::with_capacity(slice.len() * 2);
    for &byte in slice.iter() {
        v.push(CHARS[(byte >> 4) as usize]);
        v.push(CHARS[(byte & 0xf) as usize]);
    }

    unsafe { String::from_utf8_unchecked(v) }
}

#[cfg(test)]
mod test {
    use std::io::ErrorKind;

    #[test]
    fn test_random_bytes() {
        match super::RandomBytes::new() {
            Ok(r) => {
                let bytes = r.get();
                let size = bytes[0] as usize;
                assert_eq!(size + 1, bytes.len());
            }
            Err(e) => assert_eq!(e.kind() == ErrorKind::Other),
        }
    }
}
<commit_msg>fix test error<commit_after>use std::env;
use std::fmt;
use std::io;

use ansi_term::Color;
use env_logger::LogBuilder;
use log::{LogLevel, LogLevelFilter, LogRecord};
use ring::rand::{SecureRandom, SystemRandom};
use time;

use super::v3::MAX_PADDING_LEN;

struct ColorLevel(LogLevel);

impl fmt::Display for ColorLevel {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self.0 {
            LogLevel::Trace => Color::Purple.paint("TRACE"),
            LogLevel::Debug => Color::Blue.paint("DEBUG"),
            LogLevel::Info => Color::Green.paint("INFO "),
            LogLevel::Warn => Color::Yellow.paint("WARN "),
            LogLevel::Error => Color::Red.paint("ERROR"),
        }.fmt(f)
    }
}

pub fn init_logger() {
    let format = |record: &LogRecord| {
        let now = time::now();
        let ms = now.tm_nsec / 1000 / 1000;
        let t = time::strftime("%Y-%m-%d %T", &now).unwrap();
        format!(
            "{}.{:03} [{}]  {}",
            t,
            ms,
            ColorLevel(record.level()),
            record.args()
        )
    };

    let mut builder = LogBuilder::new();
    builder.format(format).filter(None, LogLevelFilter::Info);

    if env::var("RUST_LOG").is_ok() {
        builder.parse(&env::var("RUST_LOG").unwrap());
    }

    if env::var("FAKIO_LOG").is_ok() {
        builder.parse(&env::var("FAKIO_LOG").unwrap());
    }

    builder.init().unwrap();
}

/// `MAX_PADDING_LEN 255`
///
/// +-------+----------+
/// |  len  |   bytes  |
/// +-------+----------+
/// | 1bytes| [0, 255] |
/// +-------+----------+
pub struct RandomBytes {
    len: usize,
    bytes: [u8; 1 + MAX_PADDING_LEN],
}

impl RandomBytes {
    pub fn new() -> io::Result<RandomBytes> {
        let mut padding = [0u8; 1 + MAX_PADDING_LEN];
        let rand = SystemRandom::new();

        // 1. rand len
        rand.fill(&mut padding[..1])
            .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("rand failed by {}", e)))?;

        // 2. rand data
        let len = padding[0] as usize;
        rand.fill(&mut padding[1..len + 1])
            .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("rand failed by {}", e)))?;
        Ok(RandomBytes {
            len: len,
            bytes: padding,
        })
    }

    #[inline]
    pub fn get(&self) -> &[u8] {
        &self.bytes[..self.len + 1]
    }
}

static CHARS: &'static [u8] = b"0123456789abcdef";

pub fn to_hex(slice: &[u8]) -> String {
    let mut v = Vec::with_capacity(slice.len() * 2);
    for &byte in slice.iter() {
        v.push(CHARS[(byte >> 4) as usize]);
        v.push(CHARS[(byte & 0xf) as usize]);
    }

    unsafe { String::from_utf8_unchecked(v) }
}

#[cfg(test)]
mod test {
    use std::io::ErrorKind;

    #[test]
    fn test_random_bytes() {
        match super::RandomBytes::new() {
            Ok(r) => {
                let bytes = r.get();
                let size = bytes[0] as usize;
                assert_eq!(size + 1, bytes.len());
            }
            Err(e) => assert_eq!(e.kind(), ErrorKind::Other),
        }
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;

use string_cache::Atom;

use serde::ser::{Serialize, Serializer};
use serde::de::{Deserialize, Deserializer, Error as DeserializationError, Type as DeserializationType};

use std::cmp::PartialEq;
use std::hash::{Hash, Hasher};

/// A marker for a request that a expects a specific value.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Exactly<T> {
    /// No constraint.
    Always,

    /// Expect a specific value.
    Exactly(T),

    /// Never accept a constraint. This can happen, for instance, we have have
    /// attempted to `and` two conflicting `Exactly`
    Never,
}

impl<T> Exactly<T> where T: PartialEq {
    /// Combine two constraints.
    pub fn and(self, other: Self) -> Self {
        use self::Exactly::*;
        match (self, other) {
            (Never, _) | (_, Never) => Never,
            (Always, x) | (x, Always) => x,
            (Exactly(x), Exactly(y)) =>
                if x == y {
                    Exactly(y)
                } else {
                    Never
                }
        }
    }

    pub fn is_empty(&self) -> bool {
        match *self {
            Exactly::Always => true,
            _ => false,
        }
    }

    pub fn matches(&self, value: &T) -> bool {
        match *self {
            Exactly::Always => true,
            Exactly::Exactly(ref id) => id == value,
            _ => false
        }
    }
}

impl<T> Default for Exactly<T> {
    fn default() -> Self {
        Exactly::Always
    }
}

/// A variant of `PhantomData` that supports [De]serialization
#[derive(Clone, Debug, PartialEq, Hash, Eq)]
pub struct Phantom<T> {
    phantom: PhantomData<T>
}

impl<T> Default for Phantom<T> {
    fn default() -> Self {
        Self::new()
    }
}

impl<T> Phantom<T> {
    pub fn new() -> Self {
        Phantom {
            phantom: PhantomData
        }
    }
}
impl<T> Serialize for Phantom<T> {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer {
            ().serialize(serializer)
    }
}
impl<T> Deserialize for Phantom<T> {
    fn deserialize<D>(_: &mut D) -> Result<Self, D::Error>
        where D: Deserializer {
        // Nothing to consume
        Ok(Phantom {
            phantom: PhantomData
        })
    }
}

/// A unique id for values of a given kind.
///
/// # Performance
///
/// This data structure is tuned for specific use cases and should be used accordingly.
///
/// - Using an instances of `Id` as a key in a `HashMap` or `HashSet` is much faster than
///   using a `String`.
/// - Comparing two instances of `Id` is much faster than comparing two `String`s.
/// - Instances of `Id` take very little memory.
/// - Cloning an instance of `Id` is relatively fast, but should be avoided if possible.
/// - Calling `Id::new`, on the other hand, is *very slow*. **Always prefer cloning to calling
///   `Id::new`**.
///
/// # (De)serialization
///
/// Serialized values of this type are represented by plain strings.
///
/// ```
/// extern crate serde;
/// extern crate serde_json;
/// extern crate foxbox_taxonomy;
///
/// #[derive(Debug)]
/// struct UniqueId;
///
/// let my_id = foxbox_taxonomy::util::Id::<UniqueId>::new("Unique Identifier".to_owned());
///
/// let my_serialized_id = serde_json::to_string(&my_id).unwrap();
/// assert_eq!(my_serialized_id, "\"Unique Identifier\"");
///
/// let my_deserialized_id: foxbox_taxonomy::util::Id<UniqueId> =
///     serde_json::from_str("\"Unique Identifier\"").unwrap();
/// assert_eq!(my_deserialized_id, my_id);
/// ```
#[derive(Debug, Clone)]
pub struct Id<T> {
    id: Atom,

    phantom: Phantom<T>,
}

impl<T> Id<T> {
    pub fn new(id: String) -> Self {
        Id {
            id: Atom::from(id),
            phantom: Phantom::new(),
        }
    }

    pub fn as_atom(&self) -> &Atom {
        &self.id
    }
}

impl<T> PartialEq for Id<T> {
    fn eq(&self, other: &Self) -> bool {
        self.id.eq(&other.id)
    }
}

impl<T> Eq for Id<T> {
}

impl<T> Hash for Id<T> {
    fn hash<H>(&self, state: &mut H) where H: Hasher {
        self.id.hash(state)
    }
}

impl<T> Serialize for Id<T> {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer {
        self.id.as_ref().serialize(serializer)
    }
}

impl<T> Deserialize for Id<T> {
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer {
        let deserialized_string = try!(String::deserialize(deserializer));

        Ok(Id {
            id: Atom::from(deserialized_string),
            phantom: Phantom::new(),
        })
    }
}

/// A bunch of results grouped in an array of (key, result).
pub type ResultSet<I, T, E> = Vec<(I, Result<T, E>)>;

/// By default, the (de)serialization of trivial enums by Serde is surprising, e.g.
/// in JSON,  `enum Foo {A, B, C}` will produce `{"\"A\": []"}` for `A`, where `"\"A\""`
/// would be expected.
///
/// Implementing serialization is very simple, but deserialization is much more annoying.
/// This struct lets us implement simply the deserialization to a predictable and well-specified
/// list of strings.
///
/// # Example
///
/// ```
/// extern crate serde;
/// use serde::de::{Deserialize, Deserializer};
///
/// extern crate foxbox_taxonomy;
/// use foxbox_taxonomy::util::TrivialEnumVisitor;
///
/// enum Foo { A, B, C }
///
/// impl Deserialize for Foo {
///   fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
///     deserializer.visit_string(TrivialEnumVisitor::new(|source| {
///       match source {
///         "A" => Ok(Foo::A),
///         "B" => Ok(Foo::B),
///         "C" => Ok(Foo::C),
///          _ => Err(())
///       }
///    }))
///   }
/// }
///
/// # fn main() {}
/// ```
pub struct TrivialEnumVisitor<T> where T: Deserialize {
    parser: Box<Fn(&str) -> Result<T, ()>>
}

impl<T> TrivialEnumVisitor<T> where T: Deserialize {
    pub fn new<F>(parser: F) -> Self
        where F: Fn(&str) -> Result<T, ()> + 'static {
            TrivialEnumVisitor {
                parser: Box::new(parser)
            }
        }
    fn parse<E>(&self, source: &str) -> Result<T, E>
        where E: DeserializationError
    {
        (self.parser)(source)
            .map_err(|()| E::unknown_field(&source.to_owned()))
    }
}

use serde::de::Visitor;
impl<T> Visitor for TrivialEnumVisitor<T> where T: Deserialize {
    type Value = T;
    fn visit_str<E>(&mut self, v: &str) -> Result<T, E>
        where E: DeserializationError,
    {
        self.parse(v)
    }

    fn visit_string<E>(&mut self, v: String) -> Result<T, E>
        where E: DeserializationError,
    {
        self.parse(&v)
    }

    fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<T, E>
        where E: DeserializationError,
    {
        use std::str;
        match str::from_utf8(v) {
            Ok(s) => self.parse(s),
            Err(_) => Err(E::type_mismatch(DeserializationType::String)),
        }
    }

    fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<T, E>
        where E: DeserializationError,
    {
        match String::from_utf8(v) {
            Ok(s) => self.parse(&s),
            Err(_) => Err(DeserializationError::type_mismatch(DeserializationType::String)),
        }
    }
}
<commit_msg>Issue #21 - Implement ToString for Id<commit_after>use std::marker::PhantomData;

use string_cache::Atom;

use serde::ser::{Serialize, Serializer};
use serde::de::{Deserialize, Deserializer, Error as DeserializationError, Type as DeserializationType};

use std::cmp::PartialEq;
use std::hash::{Hash, Hasher};
use std::string::ToString;

/// A marker for a request that a expects a specific value.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Exactly<T> {
    /// No constraint.
    Always,

    /// Expect a specific value.
    Exactly(T),

    /// Never accept a constraint. This can happen, for instance, we have have
    /// attempted to `and` two conflicting `Exactly`
    Never,
}

impl<T> Exactly<T> where T: PartialEq {
    /// Combine two constraints.
    pub fn and(self, other: Self) -> Self {
        use self::Exactly::*;
        match (self, other) {
            (Never, _) | (_, Never) => Never,
            (Always, x) | (x, Always) => x,
            (Exactly(x), Exactly(y)) =>
                if x == y {
                    Exactly(y)
                } else {
                    Never
                }
        }
    }

    pub fn is_empty(&self) -> bool {
        match *self {
            Exactly::Always => true,
            _ => false,
        }
    }

    pub fn matches(&self, value: &T) -> bool {
        match *self {
            Exactly::Always => true,
            Exactly::Exactly(ref id) => id == value,
            _ => false
        }
    }
}

impl<T> Default for Exactly<T> {
    fn default() -> Self {
        Exactly::Always
    }
}

/// A variant of `PhantomData` that supports [De]serialization
#[derive(Clone, Debug, PartialEq, Hash, Eq)]
pub struct Phantom<T> {
    phantom: PhantomData<T>
}

impl<T> Default for Phantom<T> {
    fn default() -> Self {
        Self::new()
    }
}

impl<T> Phantom<T> {
    pub fn new() -> Self {
        Phantom {
            phantom: PhantomData
        }
    }
}
impl<T> Serialize for Phantom<T> {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer {
            ().serialize(serializer)
    }
}
impl<T> Deserialize for Phantom<T> {
    fn deserialize<D>(_: &mut D) -> Result<Self, D::Error>
        where D: Deserializer {
        // Nothing to consume
        Ok(Phantom {
            phantom: PhantomData
        })
    }
}

/// A unique id for values of a given kind.
///
/// # Performance
///
/// This data structure is tuned for specific use cases and should be used accordingly.
///
/// - Using an instances of `Id` as a key in a `HashMap` or `HashSet` is much faster than
///   using a `String`.
/// - Comparing two instances of `Id` is much faster than comparing two `String`s.
/// - Instances of `Id` take very little memory.
/// - Cloning an instance of `Id` is relatively fast, but should be avoided if possible.
/// - Calling `Id::new`, on the other hand, is *very slow*. **Always prefer cloning to calling
///   `Id::new`**.
///
/// # (De)serialization
///
/// Serialized values of this type are represented by plain strings.
///
/// ```
/// extern crate serde;
/// extern crate serde_json;
/// extern crate foxbox_taxonomy;
///
/// #[derive(Debug)]
/// struct UniqueId;
///
/// let my_id = foxbox_taxonomy::util::Id::<UniqueId>::new("Unique Identifier".to_owned());
///
/// assert_eq!(my_id.to_string(), "Unique Identifier");
///
/// let my_serialized_id = serde_json::to_string(&my_id).unwrap();
/// assert_eq!(my_serialized_id, "\"Unique Identifier\"");
///
/// let my_deserialized_id: foxbox_taxonomy::util::Id<UniqueId> =
///     serde_json::from_str("\"Unique Identifier\"").unwrap();
/// assert_eq!(my_deserialized_id, my_id);
/// ```
#[derive(Debug, Clone)]
pub struct Id<T> {
    id: Atom,

    phantom: Phantom<T>,
}

impl<T> Id<T> {
    pub fn new(id: String) -> Self {
        Id {
            id: Atom::from(id),
            phantom: Phantom::new(),
        }
    }

    pub fn as_atom(&self) -> &Atom {
        &self.id
    }
}

impl<T> ToString for Id<T> {
    fn to_string(&self) -> String {
        String::from(self.id.as_ref())
    }
}

impl<T> PartialEq for Id<T> {
    fn eq(&self, other: &Self) -> bool {
        self.id.eq(&other.id)
    }
}

impl<T> Eq for Id<T> {
}

impl<T> Hash for Id<T> {
    fn hash<H>(&self, state: &mut H) where H: Hasher {
        self.id.hash(state)
    }
}

impl<T> Serialize for Id<T> {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: Serializer {
        self.id.as_ref().serialize(serializer)
    }
}

impl<T> Deserialize for Id<T> {
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer {
        let deserialized_string = try!(String::deserialize(deserializer));

        Ok(Id {
            id: Atom::from(deserialized_string),
            phantom: Phantom::new(),
        })
    }
}

/// A bunch of results grouped in an array of (key, result).
pub type ResultSet<I, T, E> = Vec<(I, Result<T, E>)>;

/// By default, the (de)serialization of trivial enums by Serde is surprising, e.g.
/// in JSON,  `enum Foo {A, B, C}` will produce `{"\"A\": []"}` for `A`, where `"\"A\""`
/// would be expected.
///
/// Implementing serialization is very simple, but deserialization is much more annoying.
/// This struct lets us implement simply the deserialization to a predictable and well-specified
/// list of strings.
///
/// # Example
///
/// ```
/// extern crate serde;
/// use serde::de::{Deserialize, Deserializer};
///
/// extern crate foxbox_taxonomy;
/// use foxbox_taxonomy::util::TrivialEnumVisitor;
///
/// enum Foo { A, B, C }
///
/// impl Deserialize for Foo {
///   fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> where D: Deserializer {
///     deserializer.visit_string(TrivialEnumVisitor::new(|source| {
///       match source {
///         "A" => Ok(Foo::A),
///         "B" => Ok(Foo::B),
///         "C" => Ok(Foo::C),
///          _ => Err(())
///       }
///    }))
///   }
/// }
///
/// # fn main() {}
/// ```
pub struct TrivialEnumVisitor<T> where T: Deserialize {
    parser: Box<Fn(&str) -> Result<T, ()>>
}

impl<T> TrivialEnumVisitor<T> where T: Deserialize {
    pub fn new<F>(parser: F) -> Self
        where F: Fn(&str) -> Result<T, ()> + 'static {
            TrivialEnumVisitor {
                parser: Box::new(parser)
            }
        }
    fn parse<E>(&self, source: &str) -> Result<T, E>
        where E: DeserializationError
    {
        (self.parser)(source)
            .map_err(|()| E::unknown_field(&source.to_owned()))
    }
}

use serde::de::Visitor;
impl<T> Visitor for TrivialEnumVisitor<T> where T: Deserialize {
    type Value = T;
    fn visit_str<E>(&mut self, v: &str) -> Result<T, E>
        where E: DeserializationError,
    {
        self.parse(v)
    }

    fn visit_string<E>(&mut self, v: String) -> Result<T, E>
        where E: DeserializationError,
    {
        self.parse(&v)
    }

    fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<T, E>
        where E: DeserializationError,
    {
        use std::str;
        match str::from_utf8(v) {
            Ok(s) => self.parse(s),
            Err(_) => Err(E::type_mismatch(DeserializationType::String)),
        }
    }

    fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<T, E>
        where E: DeserializationError,
    {
        match String::from_utf8(v) {
            Ok(s) => self.parse(&s),
            Err(_) => Err(DeserializationError::type_mismatch(DeserializationType::String)),
        }
    }
}
<|endoftext|>


<commit_before>
//! Helper functions for hue and saturation selection

use image::{
    GenericImage,
    Rgba,
    RgbaImage,
};

/// Selects color at coordinate in a rectangle show hue and saturation
pub fn select(rect: [u32; 4], x: u32, y: u32) -> Rgba<u8> {
    let inv_rect_width = 1.0_f64 / rect[2] as f64;
    let half_inv_rect_height = 0.5_f64 / rect[3] as f64;
    let inv60 = 1.0_f64 / 60.0_f64;

    let fx = (x - rect[0]) as f64 * inv_rect_width;
    let hue = fx * 360.0_f64;
    // Saturation is 0.5 * fy, so by halving the height we save operations.
    let saturation = (y - rect[1]) as f64 * half_inv_rect_height;
    let hi = (hue * inv60) as int;
    let f = hue * inv60 - hi as f64;
    let hi = hi % 6;
    let v = 255; // use white as color without saturation.
    let p = (255.0 * (1.0 - saturation)) as u8;
    let q = (255.0 * (1.0 - f * saturation)) as u8;
    let t = (255.0 * (1.0 - (1.0 - f) * saturation)) as u8;
    Rgba([
        match hi {
            0 | 1 => p,
            2 => t,
            3 | 4 => v,
            _ => q
        },
        match hi {
            0 => t,
            1 | 2 => v,
            3 => q,
            _ => p
        },
        match hi {
            1 => q,
            2 | 3 => p,
            4 => t,
            _ => v
        },
        255
    ])
}

/// Sets colors to hue/saturation image.
/// White is used as color without saturation.
/// This is at the top of the image,
/// while saturated colors are at the bottom.
pub fn fill_image(
    image: &mut RgbaImage,
    rect: [u32; 4]
) {
    let inv_rect_width = 1.0_f64 / rect[2] as f64;
    let half_inv_rect_height = 0.5_f64 / rect[3] as f64;
    let inv60 = 1.0_f64 / 60.0_f64;
    for x in range(rect[0], rect[0] + rect[2]) {
        for y in range(rect[1], rect[1] + rect[3]) {
            let fx = (x - rect[0]) as f64 * inv_rect_width;
            let hue = fx * 360.0_f64;
            // Saturation is 0.5 * fy, so by halving the height we save operations.
            let saturation = (y - rect[1]) as f64 * half_inv_rect_height;
            let hi = (hue * inv60) as int;
            let f = hue * inv60 - hi as f64;
            let hi = hi % 6;
            let v = 255; // use white as color without saturation.
            let p = (255.0 * (1.0 - saturation)) as u8;
            let q = (255.0 * (1.0 - f * saturation)) as u8;
            let t = (255.0 * (1.0 - (1.0 - f) * saturation)) as u8;
            *image.get_pixel_mut(x, y) = Rgba([
                match hi {
                    0 | 1 => p,
                    2 => t,
                    3 | 4 => v,
                    _ => q
                },
                match hi {
                    0 => t,
                    1 | 2 => v,
                    3 => q,
                    _ => p
                },
                match hi {
                    1 => q,
                    2 | 3 => p,
                    4 => t,
                    _ => v
                },
                255
            ]);
        }
    }
}
<commit_msg>Upgraded to latest Rust<commit_after>
//! Helper functions for hue and saturation selection

use image::{
    GenericImage,
    Rgba,
    RgbaImage,
};

/// Selects color at coordinate in a rectangle show hue and saturation
pub fn select(rect: [u32; 4], x: u32, y: u32) -> Rgba<u8> {
    let inv_rect_width = 1.0_f64 / rect[2] as f64;
    let half_inv_rect_height = 0.5_f64 / rect[3] as f64;
    let inv60 = 1.0_f64 / 60.0_f64;

    let fx = (x - rect[0]) as f64 * inv_rect_width;
    let hue = fx * 360.0_f64;
    // Saturation is 0.5 * fy, so by halving the height we save operations.
    let saturation = (y - rect[1]) as f64 * half_inv_rect_height;
    let hi = (hue * inv60) as isize;
    let f = hue * inv60 - hi as f64;
    let hi = hi % 6;
    let v = 255; // use white as color without saturation.
    let p = (255.0 * (1.0 - saturation)) as u8;
    let q = (255.0 * (1.0 - f * saturation)) as u8;
    let t = (255.0 * (1.0 - (1.0 - f) * saturation)) as u8;
    Rgba([
        match hi {
            0 | 1 => p,
            2 => t,
            3 | 4 => v,
            _ => q
        },
        match hi {
            0 => t,
            1 | 2 => v,
            3 => q,
            _ => p
        },
        match hi {
            1 => q,
            2 | 3 => p,
            4 => t,
            _ => v
        },
        255
    ])
}

/// Sets colors to hue/saturation image.
/// White is used as color without saturation.
/// This is at the top of the image,
/// while saturated colors are at the bottom.
pub fn fill_image(
    image: &mut RgbaImage,
    rect: [u32; 4]
) {
    let inv_rect_width = 1.0_f64 / rect[2] as f64;
    let half_inv_rect_height = 0.5_f64 / rect[3] as f64;
    let inv60 = 1.0_f64 / 60.0_f64;
    for x in (rect[0]..rect[0] + rect[2]) {
        for y in (rect[1]..rect[1] + rect[3]) {
            let fx = (x - rect[0]) as f64 * inv_rect_width;
            let hue = fx * 360.0_f64;
            // Saturation is 0.5 * fy, so by halving the height we save operations.
            let saturation = (y - rect[1]) as f64 * half_inv_rect_height;
            let hi = (hue * inv60) as isize;
            let f = hue * inv60 - hi as f64;
            let hi = hi % 6;
            let v = 255; // use white as color without saturation.
            let p = (255.0 * (1.0 - saturation)) as u8;
            let q = (255.0 * (1.0 - f * saturation)) as u8;
            let t = (255.0 * (1.0 - (1.0 - f) * saturation)) as u8;
            *image.get_pixel_mut(x, y) = Rgba([
                match hi {
                    0 | 1 => p,
                    2 => t,
                    3 | 4 => v,
                    _ => q
                },
                match hi {
                    0 => t,
                    1 | 2 => v,
                    3 => q,
                    _ => p
                },
                match hi {
                    1 => q,
                    2 | 3 => p,
                    4 => t,
                    _ => v
                },
                255
            ]);
        }
    }
}
<|endoftext|>


<commit_before>//! Unix-specific extensions to general I/O primitives.

#![stable(feature = "rust1", since = "1.0.0")]

use crate::fs;
use crate::io;
use crate::os::raw;
use crate::sys;
use crate::sys_common::{AsInner, FromInner, IntoInner};

/// Raw file descriptors.
#[stable(feature = "rust1", since = "1.0.0")]
pub type RawFd = raw::c_int;

/// A trait to extract the raw unix file descriptor from an underlying
/// object.
///
/// This is only available on unix platforms and must be imported in order
/// to call the method. Windows platforms have a corresponding `AsRawHandle`
/// and `AsRawSocket` set of traits.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd {
    /// Extracts the raw file descriptor.
    ///
    /// This method does **not** pass ownership of the raw file descriptor
    /// to the caller. The descriptor is only guaranteed to be valid while
    /// the original object has not yet been destroyed.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn as_raw_fd(&self) -> RawFd;
}

/// A trait to express the ability to construct an object from a raw file
/// descriptor.
#[stable(feature = "from_raw_os", since = "1.1.0")]
pub trait FromRawFd {
    /// Constructs a new instance of `Self` from the given raw file
    /// descriptor.
    ///
    /// This function **consumes ownership** of the specified file
    /// descriptor. The returned object will take responsibility for closing
    /// it when the object goes out of scope.
    ///
    /// This function is also unsafe as the primitives currently returned
    /// have the contract that they are the sole owner of the file
    /// descriptor they are wrapping. Usage of this function could
    /// accidentally allow violating this contract which can cause memory
    /// unsafety in code that relies on it being true.
    #[stable(feature = "from_raw_os", since = "1.1.0")]
    unsafe fn from_raw_fd(fd: RawFd) -> Self;
}

/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
#[stable(feature = "into_raw_os", since = "1.4.0")]
pub trait IntoRawFd {
    /// Consumes this object, returning the raw underlying file descriptor.
    ///
    /// This function **transfers ownership** of the underlying file descriptor
    /// to the caller. Callers are then the unique owners of the file descriptor
    /// and must close the descriptor once it's no longer needed.
    #[stable(feature = "into_raw_os", since = "1.4.0")]
    fn into_raw_fd(self) -> RawFd;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for fs::File {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().raw()
    }
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for fs::File {
    unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
        fs::File::from_inner(sys::fs::File::from_inner(fd))
    }
}
#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for fs::File {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stdin {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDIN_FILENO
    }
}

#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stdout {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDOUT_FILENO
    }
}

#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stderr {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDERR_FILENO
    }
}

#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StdinLock<'a> {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDIN_FILENO
    }
}

#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StdoutLock<'a> {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDOUT_FILENO
    }
}

#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StderrLock<'a> {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDERR_FILENO
    }
}
<commit_msg>Add missing examples for Fd traits<commit_after>//! Unix-specific extensions to general I/O primitives.

#![stable(feature = "rust1", since = "1.0.0")]

use crate::fs;
use crate::io;
use crate::os::raw;
use crate::sys;
use crate::sys_common::{AsInner, FromInner, IntoInner};

/// Raw file descriptors.
#[stable(feature = "rust1", since = "1.0.0")]
pub type RawFd = raw::c_int;

/// A trait to extract the raw unix file descriptor from an underlying
/// object.
///
/// This is only available on unix platforms and must be imported in order
/// to call the method. Windows platforms have a corresponding `AsRawHandle`
/// and `AsRawSocket` set of traits.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd {
    /// Extracts the raw file descriptor.
    ///
    /// This method does **not** pass ownership of the raw file descriptor
    /// to the caller. The descriptor is only guaranteed to be valid while
    /// the original object has not yet been destroyed.
    ///
    /// # Example
    ///
    /// ```no_run
    /// use std::fs::File;
    /// use std::os::unix::io::{AsRawFd, RawFd};
    ///
    /// fn main() -> std::io::Result<()> {
    ///     let mut f = File::open("foo.txt")?;
    ///     // Note that `raw_fd` is only valid as long as `f` exists.
    ///     let raw_fd: RawFd = f.as_raw_fd();
    ///     Ok(())
    /// }
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn as_raw_fd(&self) -> RawFd;
}

/// A trait to express the ability to construct an object from a raw file
/// descriptor.
#[stable(feature = "from_raw_os", since = "1.1.0")]
pub trait FromRawFd {
    /// Constructs a new instance of `Self` from the given raw file
    /// descriptor.
    ///
    /// This function **consumes ownership** of the specified file
    /// descriptor. The returned object will take responsibility for closing
    /// it when the object goes out of scope.
    ///
    /// This function is also unsafe as the primitives currently returned
    /// have the contract that they are the sole owner of the file
    /// descriptor they are wrapping. Usage of this function could
    /// accidentally allow violating this contract which can cause memory
    /// unsafety in code that relies on it being true.
    ///
    /// # Example
    ///
    /// ```no_run
    /// use std::fs::File;
    /// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd};
    ///
    /// fn main() -> std::io::Result<()> {
    ///     let f = File::open("foo.txt")?;
    ///     let raw_fd: RawFd = f.into_raw_fd();
    ///     // SAFETY: no other functions should call `from_raw_fd`, so there
    ///     // is only one owner for the file descriptor.
    ///     let f = unsafe { File::from_raw_fd(raw_fd) };
    ///     Ok(())
    /// }
    /// ```
    #[stable(feature = "from_raw_os", since = "1.1.0")]
    unsafe fn from_raw_fd(fd: RawFd) -> Self;
}

/// A trait to express the ability to consume an object and acquire ownership of
/// its raw file descriptor.
#[stable(feature = "into_raw_os", since = "1.4.0")]
pub trait IntoRawFd {
    /// Consumes this object, returning the raw underlying file descriptor.
    ///
    /// This function **transfers ownership** of the underlying file descriptor
    /// to the caller. Callers are then the unique owners of the file descriptor
    /// and must close the descriptor once it's no longer needed.
    ///
    /// # Example
    ///
    /// ```no_run
    /// use std::fs::File;
    /// use std::os::unix::io::{IntoRawFd, RawFd};
    ///
    /// fn main() -> std::io::Result<()> {
    ///     let f = File::open("foo.txt")?;
    ///     let raw_fd: RawFd = f.into_raw_fd();
    ///     Ok(())
    /// }
    /// ```
    #[stable(feature = "into_raw_os", since = "1.4.0")]
    fn into_raw_fd(self) -> RawFd;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for fs::File {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().fd().raw()
    }
}
#[stable(feature = "from_raw_os", since = "1.1.0")]
impl FromRawFd for fs::File {
    unsafe fn from_raw_fd(fd: RawFd) -> fs::File {
        fs::File::from_inner(sys::fs::File::from_inner(fd))
    }
}
#[stable(feature = "into_raw_os", since = "1.4.0")]
impl IntoRawFd for fs::File {
    fn into_raw_fd(self) -> RawFd {
        self.into_inner().into_fd().into_raw()
    }
}

#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stdin {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDIN_FILENO
    }
}

#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stdout {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDOUT_FILENO
    }
}

#[stable(feature = "asraw_stdio", since = "1.21.0")]
impl AsRawFd for io::Stderr {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDERR_FILENO
    }
}

#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StdinLock<'a> {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDIN_FILENO
    }
}

#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StdoutLock<'a> {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDOUT_FILENO
    }
}

#[stable(feature = "asraw_stdio_locks", since = "1.35.0")]
impl<'a> AsRawFd for io::StderrLock<'a> {
    fn as_raw_fd(&self) -> RawFd {
        libc::STDERR_FILENO
    }
}
<|endoftext|>