<commit_before>//#![feature(test)]     //benchmark using nightly

pub mod math;
//mod des;
extern crate num;

#[cfg(test)]
mod tests {
    use super::math::math;
    use math::math::Mod;
    use super::num::traits::NumCast;

    #[test]
    fn mod_signed() {
        use math::math::Mod;
        assert_eq!(5%2, 1);
        assert_eq!(-5%2, -1);
        let a: i32 = -5;
        assert_eq!(a.modulo(2), 1);
        assert_eq!((-5).modulo(2), 1);
        //vector of tests: v.i.0 mod v.i.1 = v.i.2
        let v: Vec<(i32,i32,i32)> = vec![(-98, 308, 210), (-443, 363, 283), (-413, 443, 30),
                                        (-96, 59, 22),    (-268, 24, 20),   (-449, 414, 379),
                                        (-176, 45, 4),    (-469, 413, 357), (-486, 40, 34),
                                        (-359, 126, 19),  (-270, 138, 6),   (-107, 430, 323),
                                        (-112, 340, 228), (-411, 310, 209), (-304, 398, 94),
                                        (-60, 60, 0),     (-200, 446, 246), (-82, 495, 413),
                                        (-132, 277, 145), (-2, 139, 137),   (-465, 61, 23),
                                        (-209, 122, 35),  (-438, 393, 348), (-437, 31, 28),
                                        (-316, 301, 286), (-26, 97, 71),    (-16, 156, 140),
                                        (-127, 193, 66),  (-446, 170, 64),  (-404, 216, 28) ];
        for (a,b,c) in v {
            assert_eq!(a.modulo(b), c);
        }
    }

    #[test]
    #[ignore]   //big numbers: can be slow (~10 seconds)
    fn prime_factorize() {
        fn is_prime_naive(n: u32) -> bool {
            n > 1 && !(2 .. 1 + n/2).into_iter().any(|i| n%i==0)
        }
        fn reform_from_prime_factors(f: Vec<(u32,u32)>) -> u32 {
            f.into_iter().fold(1u32, |acc, (n,e)| acc*n.pow(e))
        }

        let vals = vec![22176180, 137235605, 912673, 47];
        for i in vals {
            let v = math::prime_factors(i);
            println!("\n{:?}", v);
            for &(j,_) in &v {
                assert!(is_prime_naive(j));
            }
            assert_eq!(reform_from_prime_factors(v), i);
        }
    }

    #[test]
    fn gcd_base() {
        assert_eq!(0, math::gcd(0,0));
        assert_eq!(4, math::gcd(4,0));
        assert_eq!(4, math::gcd(0,4));
    }

    #[test]
    fn gcd() {
        assert_eq!( 1, math::gcd(14u16, 15u16));
        assert_eq!( 7, math::gcd(14i64, 21i64));
        assert_eq!(13, math::gcd(13u8, 26u8));
        assert_eq!( 1, math::gcd(42i32, 7919i32));
        assert_eq!( 1, math::gcd(61157u32, 32414u32));
        assert_eq!(42, math::gcd((42*61157) as u64, (42*32414) as u64));

        assert_eq!( 1, math::gcd(14, -15));
    }

    #[test]
    fn ext_euclid_alg() {
        //common case: stallings p99
        let (a,b) = (1759, 550);
        let (x,y) = math::ext_euclidean_alg(a, b);
        assert_eq!(x*a + y*b, 1);

        //out of order, gcd != 1:
        //https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Example
        let (a,b) = (46, 240);
        let (x,y) = math::ext_euclidean_alg(a, b);
        assert_eq!(x*a + y*b, 2);

        //u64s sometimes don't fit into i32s, but they can (only panic if overflow)
        let (a,b): (u64,u64) = (67571, 42578);
        let (x,y) = math::ext_euclidean_alg(a, b);
        assert_eq!(x*(a as i32) + y*(b as i32), 1);

        let (a,b) = (1234, 4321);
        let (x,y) = math::ext_euclidean_alg(a, b);
        assert_eq!(x*a + y*b, 1);
    }

    #[test]
    #[should_panic]
    fn ext_euclid_alg_exceed() {
        //can't cast a large u64 down to an i32
        let (a,b): (u64,u64) = (1099511627776, 549755813888);   // 2**40, 2**39
        math::ext_euclidean_alg(a, b);
    }

    #[test]
    fn modular_inverse() {
        //be super sure
        //input tests: random coprime pairs
        let v: Vec<(u32,u32)> = vec![(5,24),    (121, 133), (97,31),    (100, 199), (24,49),
                                    (35, 761),  (723, 997), (927, 718), (153, 566), (256, 27),
                                    (394, 805), (173, 386), (768, 391), (399, 59),  (14, 885),
                                    (385, 509), (357, 143), (272, 617), (509, 847), (218, 461),
                                    (718, 413), (725, 482), (298, 223), (533, 250), (478, 383),
                                    (863, 641), (931, 324), (221, 324), (824, 537), (409, 203),
                                    (526, 231), (452, 601), (688, 547), (721, 274), (722, 629),
                                    (169, 165), (735, 703), (843, 407), (581, 876), (909, 989)];
        for (a,p) in v {
            let y = math::mult_inverse(a,p);
            assert!(y > 0);
            let x: u32 = NumCast::from(y).unwrap();
            assert_eq!((a*x)%p, 1);
            assert_eq!((a*x).modulo(p), 1);
        }
    }

    #[test]
    fn modular_inverse_signed() {
        let v: Vec<(i32,u32)> = vec![(-219, 524), (499, 650), (817, 333),  (-913, 30),
                                    (-973, 746),  (143, 128), (-995, 497), (-18, 521),
                                    (-6, 235),    (769, 573), (-801, 614), (-764, 285),
                                    (-373, 297),  (952, 815), (699, 784),  (255, 922)];

        for (a,p) in v {
            let y = math::mult_inverse_signed(a,p);
            assert!(y > 0);
            let x: i32 = NumCast::from(y).unwrap();
            assert_eq!((a*x).modulo(p as i32), 1);
        }
    }

    //  MISC BENCHMARKS:

    /*
    extern crate test;
    use self::test::Bencher;
    */

    /* Testing: performance for different primitive types
     *  Conclusion:
     *      unsigned seem to be a faster than signed (particularly 64-bit)
     *      32-bit quite a bit faster than 64-bit
     *      16-bit between them (unsigned, anyway)
     *      u32 ≅ i32
     *      i64 100% slower than _32
     *      u64 ~60% slower than _32
     *  Prescription:
     *      Try to avoid i64s
     *      Signed results should probably be i32s not i64s
     */
    /*
    #[bench]
    fn bench_gcd_u32(b: &mut Bencher) {
        b.iter(|| math::gcd(61157u32, 32414u32))
    }
    #[bench]
    fn bench_gcd_i32(b: &mut Bencher) {
        b.iter(|| math::gcd(61157i32, 32414i32))
    }
    #[bench]
    fn bench_gcd_u64(b: &mut Bencher) {
        b.iter(|| math::gcd(61157u64, 32414u64))
    }
    #[bench]
    fn bench_gcd_i64(b: &mut Bencher) {
        b.iter(|| math::gcd(61157i64, 32414i64))
    }
    */
    /* Test different methods of swapping values
     * (After being rebuilt on nightly, presumably w/ optimizations):
     *  All took 17 ns
     */
    /*
    use std::mem;
    #[bench]
    fn swap_with_swap(b: &mut Bencher) {
        let (mut x, mut y) = (61157i64, 32414i64);
        b.iter(|| { for _ in 0..1000 { mem::swap(&mut x, &mut y); } })
    }

    #[bench]
    fn swap_with_tmp(b: &mut Bencher) {
        let (mut x, mut y) = (61157i64, 32414i64);
        b.iter(|| { for _ in 0..1000 { let tmp = x; x = y; y = tmp; } })
    }

    #[bench]
    fn swap_with_magic(b: &mut Bencher) {
        let (mut x, mut y) = (61157i64, 32414i64);
        b.iter(|| { for _ in 0..1000 { x ^= y; y ^= x; x ^= y; } })
    }
    */
}

<commit_msg>touched up tests<commit_after>//#![feature(test)]     //benchmark using nightly

pub mod math;
//mod des;
extern crate num;

#[cfg(test)]
mod tests {
    //math module
    use super::math::math;
    //number traits
    use math::math::Mod;
    use super::num::traits::NumCast;

    // Test the `modulo` operator
    #[test]
    fn mod_signed() {
        use math::math::Mod;
        assert_eq!(5%2, 1);
        assert_eq!(-5%2, -1);
        let a: i32 = -5;
        assert_eq!(a.modulo(2), 1);
        assert_eq!((-5).modulo(2), 1);
        //vector of tests: v.i.0 mod v.i.1 = v.i.2
        let v: Vec<(i32,i32,i32)> = vec![(-98, 308, 210), (-443, 363, 283), (-413, 443, 30),
                                        (-96, 59, 22),    (-268, 24, 20),   (-449, 414, 379),
                                        (-176, 45, 4),    (-469, 413, 357), (-486, 40, 34),
                                        (-359, 126, 19),  (-270, 138, 6),   (-107, 430, 323),
                                        (-112, 340, 228), (-411, 310, 209), (-304, 398, 94),
                                        (-60, 60, 0),     (-200, 446, 246), (-82, 495, 413),
                                        (-132, 277, 145), (-2, 139, 137),   (-465, 61, 23),
                                        (-209, 122, 35),  (-438, 393, 348), (-437, 31, 28),
                                        (-316, 301, 286), (-26, 97, 71),    (-16, 156, 140),
                                        (-127, 193, 66),  (-446, 170, 64),  (-404, 216, 28) ];
        for (a,b,c) in v {
            assert_eq!(a.modulo(b), c);
        }
    }

    //test greatest common denominator
    #[test]
    fn gcd() {
        //base case tests
        assert_eq!(0, math::gcd(0,0));
        assert_eq!(4, math::gcd(4,0));
        assert_eq!(4, math::gcd(0,4));
        //actual tests
        assert_eq!( 1, math::gcd(14u16, 15u16));
        assert_eq!( 7, math::gcd(14i64, 21i64));
        assert_eq!(13, math::gcd(13u8, 26u8));
        assert_eq!( 1, math::gcd(42i32, 7919i32));
        assert_eq!( 1, math::gcd(61157u32, 32414u32));
        assert_eq!(42, math::gcd((42*61157) as u64, (42*32414) as u64));
        //negatives
        assert_eq!( 1, math::gcd( 14, -15));
        assert_eq!( 4, math::gcd(-36,  20));
        assert_eq!( 1, math::gcd(-25, -33));    //correct? or -1?
        assert_eq!( 3, math::gcd(-21,  48));
        assert_eq!( 1, math::gcd(-11, -20));
        assert_eq!( 1, math::gcd(  9, -13));
        assert_eq!(43, math::gcd( 43, -43));
        assert_eq!(13, math::gcd(-13,  26));
        assert_eq!( 1, math::gcd(-27,  41));
        assert_eq!( 4, math::gcd( 36, -16));
    }

    //Extended Euclidean Algorithm
    #[test]
    fn ext_euclid_alg() {
        //common case: stallings p99
        let (a,b) = (1759, 550);
        let (x,y) = math::ext_euclidean_alg(a, b);
        assert_eq!(x*a + y*b, 1);

        //out of order, gcd != 1:
        //https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Example
        let (a,b) = (46, 240);
        let (x,y) = math::ext_euclidean_alg(a, b);
        assert_eq!(x*a + y*b, 2);

        //u64s sometimes don't fit into i32s, but they can (only panic if overflow)
        let (a,b): (u64,u64) = (67571, 42578);
        let (x,y) = math::ext_euclidean_alg(a, b);
        assert_eq!(x*(a as i32) + y*(b as i32), 1);

        let (a,b) = (1234, 4321);
        let (x,y) = math::ext_euclidean_alg(a, b);
        assert_eq!(x*a + y*b, 1);
    }

    //Make sure NumCasts::from().unwrap() catches numbers that are too large
    #[test]
    #[should_panic]
    fn ext_euclid_alg_exceed() {
        //can't cast a large u64 down to an i32
        let (a,b): (u64,u64) = (1099511627776, 549755813888);   // 2**40, 2**39
        math::ext_euclidean_alg(a, b);
    }

    //Modular inverse
    #[test]
    fn modular_inverse_unsigned() {
        //be super sure
        //input tests: random coprime pairs
        let v: Vec<(u32,u32)> = vec![(5,24),    (121, 133), (97,31),    (100, 199), (24,49),
                                    (35, 761),  (723, 997), (927, 718), (153, 566), (256, 27),
                                    (394, 805), (173, 386), (768, 391), (399, 59),  (14, 885),
                                    (385, 509), (357, 143), (272, 617), (509, 847), (218, 461),
                                    (718, 413), (725, 482), (298, 223), (533, 250), (478, 383),
                                    (863, 641), (931, 324), (221, 324), (824, 537), (409, 203),
                                    (526, 231), (452, 601), (688, 547), (721, 274), (722, 629),
                                    (169, 165), (735, 703), (843, 407), (581, 876), (909, 989)];
        for (a,p) in v {
            let y = math::mult_inverse(a,p);
            assert!(y > 0);
            let x: u32 = NumCast::from(y).unwrap();
            assert_eq!((a*x)%p, 1);
            assert_eq!((a*x).modulo(p), 1);
        }
    }

    #[test]
    fn modular_inverse_signed() {
        let v: Vec<(i32,u32)> = vec![(-219, 524), (499, 650), (817, 333),  (-913, 30),
                                    (-973, 746),  (143, 128), (-995, 497), (-18, 521),
                                    (-6, 235),    (769, 573), (-801, 614), (-764, 285),
                                    (-373, 297),  (952, 815), (699, 784),  (255, 922)];

        for (a,p) in v {
            let y = math::mult_inverse_signed(a,p);
            assert!(y > 0);
            let x: i32 = NumCast::from(y).unwrap();
            assert_eq!((a*x).modulo(p as i32), 1);
        }
    }

    //Find the prime factors of a number
    //Shouldn't actually use this because it scales poorly
    #[test]
    #[ignore]   //big numbers: can be slow (~10 seconds)
    fn prime_factorize() {
        fn is_prime_naive(n: u32) -> bool {
            n > 1 && !(2 .. 1 + n/2).into_iter().any(|i| n%i==0)
        }
        fn reform_from_prime_factors(f: Vec<(u32,u32)>) -> u32 {
            f.into_iter().fold(1u32, |acc, (n,e)| acc*n.pow(e))
        }

        let vals = vec![22176180, 137235605, 912673, 47];
        for i in vals {
            let v = math::prime_factors(i);
            println!("\n{:?}", v);
            for &(j,_) in &v {
                assert!(is_prime_naive(j));
            }
            assert_eq!(reform_from_prime_factors(v), i);
        }
    }
    //  MISC BENCHMARKS:

    /*
    extern crate test;
    use self::test::Bencher;
    */

    /* Testing: performance for different primitive types
     *  Conclusion:
     *      unsigned seem to be a faster than signed (particularly 64-bit)
     *      32-bit quite a bit faster than 64-bit
     *      16-bit between them (unsigned, anyway)
     *      u32 ≅ i32
     *      i64 100% slower than _32
     *      u64 ~60% slower than _32
     *  Prescription:
     *      Try to avoid i64s
     *      Signed results should probably be i32s not i64s
     */
    /*
    #[bench]
    fn bench_gcd_u32(b: &mut Bencher) {
        b.iter(|| math::gcd(61157u32, 32414u32))
    }
    #[bench]
    fn bench_gcd_i32(b: &mut Bencher) {
        b.iter(|| math::gcd(61157i32, 32414i32))
    }
    #[bench]
    fn bench_gcd_u64(b: &mut Bencher) {
        b.iter(|| math::gcd(61157u64, 32414u64))
    }
    #[bench]
    fn bench_gcd_i64(b: &mut Bencher) {
        b.iter(|| math::gcd(61157i64, 32414i64))
    }
    */
    /* Test different methods of swapping values
     * (After being rebuilt on nightly, presumably w/ optimizations):
     *  All took 17 ns
     */
    /*
    use std::mem;
    #[bench]
    fn swap_with_swap(b: &mut Bencher) {
        let (mut x, mut y) = (61157i64, 32414i64);
        b.iter(|| { for _ in 0..1000 { mem::swap(&mut x, &mut y); } })
    }

    #[bench]
    fn swap_with_tmp(b: &mut Bencher) {
        let (mut x, mut y) = (61157i64, 32414i64);
        b.iter(|| { for _ in 0..1000 { let tmp = x; x = y; y = tmp; } })
    }

    #[bench]
    fn swap_with_magic(b: &mut Bencher) {
        let (mut x, mut y) = (61157i64, 32414i64);
        b.iter(|| { for _ in 0..1000 { x ^= y; y ^= x; x ^= y; } })
    }
    */
}

<|endoftext|>


<commit_before>//! MLI intends to provide modern, data-driven abstractions for machine learning.
//!
//! MLI provides traits that work much like Combine's `Parser`,
//! Serde's `Serialize` and `Deserialize`, std's `Iterator`, and future's `Future` and `Stream`.
//! One should only need to have to create tensor processing primitives and then string them together to craft
//! a large system that continues to be useful as a primitive in an even larger system.
//!
//! ## Goals
//! - Very fast CPU forwards and backwards propogation.
//! - Abstraction over multiple backends.
//! - Automatic serialization/deserialization  derivations of all state data (using serde).
//! - Get complete reuse out of tensor code without any overhead for abstractions.
//! - Allow building tensor pipelines that can talk over streams to allow multi-node setups.
//!   - It is a non-goal to implement the orchestration of these pipelines in this crate.
//!
//! ## Const Generics
//! Const generics must land before this API can be stabilized. This API will not be able to interact
//! with tensor sizes and dimensions to allow static checking without const generics. Until that lands in stable
//! and nalgebra is updated to use it, this library will continue to be in an unstable state.

#![no_std]
<commit_msg>basic back and forward prop definitons<commit_after>//! MLI intends to provide modern, data-driven abstractions for machine learning.
//!
//! MLI provides traits that work much like Combine's `Parser`,
//! Serde's `Serialize` and `Deserialize`, std's `Iterator`, and future's `Future` and `Stream`.
//! One should only need to have to create tensor processing primitives and then string them together to craft
//! a large system that continues to be useful as a primitive in an even larger system.
//!
//! ## Goals
//! - Very fast CPU forwards and backwards propogation.
//! - Abstraction over multiple backends.
//! - Automatic serialization/deserialization  derivations of all state data (using serde).
//! - Get complete reuse out of tensor code without any overhead for abstractions.
//! - Allow building tensor pipelines that can talk over streams to allow multi-node setups.
//!   - It is a non-goal to implement the orchestration of these pipelines in this crate.
//!
//! ## Const Generics
//! Const generics must land before this API can be stabilized. This API will not be able to interact
//! with tensor sizes and dimensions to allow static checking without const generics. Until that lands in stable
//! and nalgebra is updated to use it, this library will continue to be in an unstable state.

#![no_std]

/// This trait is implemented by algorithms that back-propogate `In` into `Out`.
trait Backward<In, Out> {
    fn backward(&self, input: In) -> Out;
}

/// This trait is implemented by algorithms that forward-propogate `In` into `Out`.
trait Forward<In, Out> {
    fn forward(&self, input: In) -> Out;
}
<|endoftext|>


<commit_before>#![warn(missing_docs)]

//! A fast and lightweight math library
//!
//! `reikna` contains implementations of various useful
//! functions, structs, and algorithms from various branches
//! of mathematics, including number theory, graph theory,
//! and calculus. The library is designed with speed and
//! ease of use in mind.
//!
//! # Usage
//!
//! This library is on `crates.io`, and can be added to your
//! project by placing the following into your `Cargo.toml`
//!
//! ``` text
//! [dependencies]
//! reikna = "0.6.0"
//! ```
//!
//! and then importing the crate with
//!
//! ```text
//! #[macro_use] extern crate reikna;
//! ```
//!
//! Make sure to include the #[macro_use] part!
//!
//! # Modules
//!
//! A list of the modules currently included in this crate, along
//! with a brief description of each.
//!
//! * `aliquot` -- Functions for calcuating aliquot sums, divisor sums,
//!                and testing for perfect numbers and similar concepts.
//!
//! * `continued_fraction` -- Generate and expand continued fractions.
//!
//! * `derivative` -- Estimate derivatives of functions, along with slope
//!                   and concavity.
//!
//! * `factor` -- Compute the GCD, LCM, and prime factorization of numbers.
//!
//! * `figurate` -- Compute the value of various kinds of figurate numbers.
//!
//! * `func` -- Utility type alias and macro, used heavily in certain
//!             other modules.
//!
//! * `integral` -- Estimate integrals of functions using numeric integration.
//!
//! * `partition` -- Compute the value of the number theory partition
//!                  function.
//!
//! * `prime` -- Prime sieves, basic factoring algorithms, and primality
//!              tests.
//!
//! * `prime_count` -- Compute the value of the prime-counting function.
//!
//! * `totient` -- Compute Euler's Totient Function.
//!
//! # Examples
//!
//! ## Compute the number of primes under one million
//!
//! ```
//! # extern crate reikna;
//! # fn main() {
//! use reikna::prime::prime_sieve;
//!
//! let primes = prime_sieve(1_000_000);
//! println!("there are {} primes under one million!", primes.len());
//! # }
//! ```
//!
//! ## Factor a large integer
//!
//! ```
//! # extern crate reikna;
//! # fn main() {
//! use reikna::factor::quick_factorize;
//!
//! let my_number = 15_814_272_409_530_912_054;
//! let factors = quick_factorize(my_number);
//! println!("The prime factorization of {} is:", my_number);
//! println!("{:?}", factors);
//! }
//! ```
//!
//! Outputs:
//!
//! ```text
//! The prime factorization of 15814272409530912054 is:
//! [2, 3, 3, 23, 23, 61, 10007, 2720741641]
//! ```
//!
//! ## Relationship between the last digits of prime numbers
//!
//! Primes are considered to be pseudo-random, yet there exists
//! a relationship between the last digit of a prime number and the
//! last digit of the next prime number. For example, a prime ending
//! in `1` has only a 16% chance of being followed by another prime
//! that ends in one, at least in the range [1, 1,000,000].
//!
//!
//! ```
//! extern crate reikna;
//!
//! use reikna::prime::prime_sieve;
//!
//! pub fn main() {
//!
//!     // generate primes less than one million, removing
//!     // the single digit ones.
//!     let primes = &prime_sieve(1_000_000)[4..];
//!
//!
//!     let mut data = [[0u64; 10]; 10]; // 10x10 array to store the data
//!
//!     // loop through the primes and count digit frequency
//!     let mut old_last_digit = primes[0] % 10;
//!     for i in 1..primes.len() {
//!         let last_digit = primes[i] % 10;
//!         data[old_last_digit as usize][last_digit as usize] += 1;
//!         old_last_digit = last_digit;
//!     }
//!
//!     // store the totals into the 0's column, since it's not
//!     // being used for anything
//!     for i in 1..10 {
//!         data[0][i] = data[i].iter().fold(0, |acc, x| acc + x);
//!     }
//!
//!     // print out the data
//!     for i in vec![1, 3, 7, 9] {
//!         println!("primes ending in '{}':", i);
//!         println!(" * total -- {}", data[0][i]);
//!
//!         for k in vec![1, 3, 7, 9] {
//!             println!(" * % next prime ending in '{}' -- {}%",
//!                      k, data[i][k] as f64 / data[0][i] as f64 * 100.0);
//!         }
//!
//!         println!("");
//!     }
//! }
//! ```
//! By changing the max value, it can be observed that the bias
//! shrinks as the max grows.

#[macro_use] mod macros;

#[macro_use] pub mod func;
             pub mod aliquot;
             pub mod continued_fraction;
             pub mod derivative;
             pub mod factor;
             pub mod figurate;
             pub mod integral;
             pub mod partition;
#[macro_use] pub mod prime;
             pub mod prime_count;
             pub mod totient;

<commit_msg>update crates.io link<commit_after>#![warn(missing_docs)]

//! A fast and lightweight math library
//!
//! `reikna` contains implementations of various useful
//! functions, structs, and algorithms from various branches
//! of mathematics, including number theory, graph theory,
//! and calculus. The library is designed with speed and
//! ease of use in mind.
//!
//! # Usage
//!
//! This library is on `crates.io`, and can be added to your
//! project by placing the following into your `Cargo.toml`
//!
//! ``` text
//! [dependencies]
//! reikna = "0.10.0"
//! ```
//!
//! and then importing the crate with
//!
//! ```text
//! #[macro_use] extern crate reikna;
//! ```
//!
//! Make sure to include the #[macro_use] part!
//!
//! # Modules
//!
//! A list of the modules currently included in this crate, along
//! with a brief description of each.
//!
//! * `aliquot` -- Functions for calcuating aliquot sums, divisor sums,
//!                and testing for perfect numbers and similar concepts.
//!
//! * `continued_fraction` -- Generate and expand continued fractions.
//!
//! * `derivative` -- Estimate derivatives of functions, along with slope
//!                   and concavity.
//!
//! * `factor` -- Compute the GCD, LCM, and prime factorization of numbers.
//!
//! * `figurate` -- Compute the value of various kinds of figurate numbers.
//!
//! * `func` -- Utility type alias and macro, used heavily in certain
//!             other modules.
//!
//! * `integral` -- Estimate integrals of functions using numeric integration.
//!
//! * `partition` -- Compute the value of the number theory partition
//!                  function.
//!
//! * `prime` -- Prime sieves, basic factoring algorithms, and primality
//!              tests.
//!
//! * `prime_count` -- Compute the value of the prime-counting function.
//!
//! * `totient` -- Compute Euler's Totient Function.
//!
//! # Examples
//!
//! ## Compute the number of primes under one million
//!
//! ```
//! # extern crate reikna;
//! # fn main() {
//! use reikna::prime::prime_sieve;
//!
//! let primes = prime_sieve(1_000_000);
//! println!("there are {} primes under one million!", primes.len());
//! # }
//! ```
//!
//! ## Factor a large integer
//!
//! ```
//! # extern crate reikna;
//! # fn main() {
//! use reikna::factor::quick_factorize;
//!
//! let my_number = 15_814_272_409_530_912_054;
//! let factors = quick_factorize(my_number);
//! println!("The prime factorization of {} is:", my_number);
//! println!("{:?}", factors);
//! }
//! ```
//!
//! Outputs:
//!
//! ```text
//! The prime factorization of 15814272409530912054 is:
//! [2, 3, 3, 23, 23, 61, 10007, 2720741641]
//! ```
//!
//! ## Relationship between the last digits of prime numbers
//!
//! Primes are considered to be pseudo-random, yet there exists
//! a relationship between the last digit of a prime number and the
//! last digit of the next prime number. For example, a prime ending
//! in `1` has only a 16% chance of being followed by another prime
//! that ends in one, at least in the range [1, 1,000,000].
//!
//!
//! ```
//! extern crate reikna;
//!
//! use reikna::prime::prime_sieve;
//!
//! pub fn main() {
//!
//!     // generate primes less than one million, removing
//!     // the single digit ones.
//!     let primes = &prime_sieve(1_000_000)[4..];
//!
//!
//!     let mut data = [[0u64; 10]; 10]; // 10x10 array to store the data
//!
//!     // loop through the primes and count digit frequency
//!     let mut old_last_digit = primes[0] % 10;
//!     for i in 1..primes.len() {
//!         let last_digit = primes[i] % 10;
//!         data[old_last_digit as usize][last_digit as usize] += 1;
//!         old_last_digit = last_digit;
//!     }
//!
//!     // store the totals into the 0's column, since it's not
//!     // being used for anything
//!     for i in 1..10 {
//!         data[0][i] = data[i].iter().fold(0, |acc, x| acc + x);
//!     }
//!
//!     // print out the data
//!     for i in vec![1, 3, 7, 9] {
//!         println!("primes ending in '{}':", i);
//!         println!(" * total -- {}", data[0][i]);
//!
//!         for k in vec![1, 3, 7, 9] {
//!             println!(" * % next prime ending in '{}' -- {}%",
//!                      k, data[i][k] as f64 / data[0][i] as f64 * 100.0);
//!         }
//!
//!         println!("");
//!     }
//! }
//! ```
//! By changing the max value, it can be observed that the bias
//! shrinks as the max grows.

#[macro_use] mod macros;

#[macro_use] pub mod func;
             pub mod aliquot;
             pub mod continued_fraction;
             pub mod derivative;
             pub mod factor;
             pub mod figurate;
             pub mod integral;
             pub mod partition;
#[macro_use] pub mod prime;
             pub mod prime_count;
             pub mod totient;

<|endoftext|>


<commit_before>extern crate libc;
extern crate nix;

mod error;
mod buffer;
mod history;
mod parser;
mod instr;
mod term;

use std::os::unix::io::RawFd;

pub use error::Error;
use history::History;
use buffer::Buffer;
use term::Term;

fn readline_edit(term: &mut Term, history: &History, prompt: &str) -> Result<String, Error> {
    let mut buffer = Buffer::new();
    let mut seq: Vec<u8> = Vec::new();
    let mut history_cursor = history::Cursor::new(history);
    loop {
        try!(term.write(&buffer.get_line(prompt)));
        let byte = try!(try!(term.read_byte()).ok_or(Error::EndOfFile));
        seq.push(byte);

        match parser::parse(&seq) {
            parser::Result::Error => return Err(Error::InvalidUTF8),
            parser::Result::Incomplete => continue,
            parser::Result::Success(token) => {
                match instr::interpret_token(token) {
                    instr::Instr::Done                   => {
                        return Ok(buffer.to_string());
                    },
                    instr::Instr::DeleteCharLeftOfCursor => buffer.delete_char_left_of_cursor(),
                    instr::Instr::MoveCursorLeft         => buffer.move_left(),
                    instr::Instr::MoveCursorRight        => buffer.move_right(),
                    instr::Instr::MoveCursorStart        => buffer.move_start(),
                    instr::Instr::MoveCursorEnd          => buffer.move_end(),
                    instr::Instr::HistoryPrev            => {
                        if history_cursor.incr() {
                            buffer.swap()
                        }
                        history_cursor.get().map(|s| buffer.replace(s));
                    },
                    instr::Instr::HistoryNext            => {
                        if history_cursor.decr() {
                            buffer.swap()
                        }
                        history_cursor.get().map(|s| buffer.replace(s));
                    },
                    instr::Instr::Noop                   => (),
                    instr::Instr::Cancel                 => return Err(Error::EndOfFile),
                    instr::Instr::InsertAtCursor         => try!(buffer.insert_bytes_at_cursor(&seq))
                };
                seq.clear();
            }
        };
    }
}

pub struct Copperline {
    term: Term,
    history: History
}

impl Copperline {

    pub fn new() -> Copperline {
        Copperline::from_raw_fd(libc::STDIN_FILENO, libc::STDOUT_FILENO)
    }

    fn from_raw_fd(ifd: RawFd, ofd: RawFd) -> Copperline {
        Copperline {
            term: Term::new(ifd, ofd),
            history: History::new()
        }
    }

    pub fn read_line(&mut self, prompt: &str) -> Result<String, Error> {
        if Term::is_unsupported_term() || !self.term.is_a_tty() {
            return Err(Error::UnsupportedTerm);
        }
        try!(self.term.enable_raw_mode());
        let result = readline_edit(&mut self.term, &self.history, prompt);
        try!(self.term.disable_raw_mode());
        println!("");
        result
    }

    pub fn get_current_history_length(&self) -> usize {
        self.history.len()
    }

    pub fn add_history(&mut self, line: String) {
        self.history.push(line)
    }

    pub fn get_history_item(&self, idx: usize) -> Option<&String> {
        self.history.get(idx)
    }

    pub fn remove_history_item(&mut self, idx: usize) -> Option<String> {
        self.history.remove(idx)
    }

    pub fn clear_history(&mut self) {
        self.history.clear()
    }

}
<commit_msg>add low-level constructors<commit_after>extern crate libc;
extern crate nix;

mod error;
mod buffer;
mod history;
mod parser;
mod instr;
mod term;

use std::os::unix::io::{RawFd, AsRawFd};

pub use error::Error;
use history::History;
use buffer::Buffer;
use term::Term;

fn readline_edit(term: &mut Term, history: &History, prompt: &str) -> Result<String, Error> {
    let mut buffer = Buffer::new();
    let mut seq: Vec<u8> = Vec::new();
    let mut history_cursor = history::Cursor::new(history);
    loop {
        try!(term.write(&buffer.get_line(prompt)));
        let byte = try!(try!(term.read_byte()).ok_or(Error::EndOfFile));
        seq.push(byte);

        match parser::parse(&seq) {
            parser::Result::Error => return Err(Error::InvalidUTF8),
            parser::Result::Incomplete => continue,
            parser::Result::Success(token) => {
                match instr::interpret_token(token) {
                    instr::Instr::Done                   => {
                        return Ok(buffer.to_string());
                    },
                    instr::Instr::DeleteCharLeftOfCursor => buffer.delete_char_left_of_cursor(),
                    instr::Instr::MoveCursorLeft         => buffer.move_left(),
                    instr::Instr::MoveCursorRight        => buffer.move_right(),
                    instr::Instr::MoveCursorStart        => buffer.move_start(),
                    instr::Instr::MoveCursorEnd          => buffer.move_end(),
                    instr::Instr::HistoryPrev            => {
                        if history_cursor.incr() {
                            buffer.swap()
                        }
                        history_cursor.get().map(|s| buffer.replace(s));
                    },
                    instr::Instr::HistoryNext            => {
                        if history_cursor.decr() {
                            buffer.swap()
                        }
                        history_cursor.get().map(|s| buffer.replace(s));
                    },
                    instr::Instr::Noop                   => (),
                    instr::Instr::Cancel                 => return Err(Error::EndOfFile),
                    instr::Instr::InsertAtCursor         => try!(buffer.insert_bytes_at_cursor(&seq))
                };
                seq.clear();
            }
        };
    }
}

pub struct Copperline {
    term: Term,
    history: History
}

impl Copperline {

    pub fn new() -> Copperline {
        Copperline::new_from_raw_fds(libc::STDIN_FILENO, libc::STDOUT_FILENO)
    }

    pub fn new_from_io<I: AsRawFd, O: AsRawFd>(i: &I, o: &O) -> Copperline {
        Copperline::new_from_raw_fds(i.as_raw_fd(), o.as_raw_fd())
    }

    pub fn new_from_raw_fds(ifd: RawFd, ofd: RawFd) -> Copperline {
        Copperline {
            term: Term::new(ifd, ofd),
            history: History::new()
        }
    }

    pub fn read_line(&mut self, prompt: &str) -> Result<String, Error> {
        if Term::is_unsupported_term() || !self.term.is_a_tty() {
            return Err(Error::UnsupportedTerm);
        }
        try!(self.term.enable_raw_mode());
        let result = readline_edit(&mut self.term, &self.history, prompt);
        try!(self.term.disable_raw_mode());
        println!("");
        result
    }

    pub fn get_current_history_length(&self) -> usize {
        self.history.len()
    }

    pub fn add_history(&mut self, line: String) {
        self.history.push(line)
    }

    pub fn get_history_item(&self, idx: usize) -> Option<&String> {
        self.history.get(idx)
    }

    pub fn remove_history_item(&mut self, idx: usize) -> Option<String> {
        self.history.remove(idx)
    }

    pub fn clear_history(&mut self) {
        self.history.clear()
    }

}
<|endoftext|>


<commit_before>//! Url Encoded middleware for Iron
//!
//! This middleware focuses on parsing the incoming url parameters from client requests.
#![crate_id = "urlencoded"]
#![license = "MIT"]

extern crate url;
extern crate iron;
extern crate serialize;

use iron::{Request, Response, Middleware, Alloy};
use iron::mixin::GetUrl;
use iron::middleware::{Status, Continue};

use std::collections::HashMap;

/// Stores a `HashMap` of a `String` and a `Vec<Strings>` to address
/// client data that is sent with multiple values for a single key.
#[deriving(Clone)]
pub struct Encoded(pub HashMap<String, Vec<String>>);

/// This middleware is used for parsing url parameters and storing
/// the data as conveniently accessible data `insert`ed into an Alloy.
#[deriving(Clone)]
pub struct UrlEncoded;

/// Creates a `UrlEncoded` instance to `link` to `server.chain`. Calling the
/// function will `insert` a new `HashMap` into the `alloy`.
impl UrlEncoded {
    pub fn new() -> UrlEncoded {
        UrlEncoded
    }
}

impl Middleware for UrlEncoded {

    fn enter(&mut self, req: &mut Request, res: &mut Response, alloy: &mut Alloy) -> Status {

        let raw_url = req.url();

        let path = match raw_url {
            Some(k) => {
                url::path_from_str(k.as_slice())
            },
            None => {
                return Continue;
            }
        };

        let query = match path {
            Ok(e) => {
                e.query
            },
            Err(_) => {
                return Continue;
            }
        };
        alloy.insert::<Encoded>(Encoded(create_hash(query)));
        Continue
    }
}

fn create_hash(q: Vec<(String, String)>) -> HashMap<String, Vec<String>> {

    let mut hashStrVec: HashMap<String, Vec<String>> = HashMap::new();

    for (k, v) in q.move_iter() {
        hashStrVec.find_with_or_insert_with(
            k, v,
            |_, already, new| {
                already.push(new);
            },
            |_, v| vec![v]
        );
    }
    hashStrVec
}

#[test]
fn test_create_hash() {
    let my_vec = vec!(("band".to_string(), "arctic monkeys".to_string()),("band".to_string(), "temper trap".to_string()),("color".to_string(),"green".to_string()));
    let answer = create_hash(my_vec);
    let mut control = HashMap::new();
    control.insert("band".to_string(), vec!("arctic monkeys".to_string(), "temper trap".to_string()));
    control.insert("color".to_string(), vec!("green".to_string()));
    assert!(answer==control);
}<commit_msg>(refactor) Updated for rearrangement<commit_after>//! Url Encoded middleware for Iron
//!
//! This middleware focuses on parsing the incoming url parameters from client requests.
#![crate_id = "urlencoded"]
#![license = "MIT"]

extern crate url;
extern crate iron;
extern crate serialize;

use iron::{Request, Response, Middleware, Alloy, Status, Continue};
use iron::mixin::GetUrl;

use std::collections::HashMap;

/// Stores a `HashMap` of a `String` and a `Vec<Strings>` to address
/// client data that is sent with multiple values for a single key.
#[deriving(Clone)]
pub struct Encoded(pub HashMap<String, Vec<String>>);

/// This middleware is used for parsing url parameters and storing
/// the data as conveniently accessible data `insert`ed into an Alloy.
#[deriving(Clone)]
pub struct UrlEncoded;

/// Creates a `UrlEncoded` instance to `link` to `server.chain`. Calling the
/// function will `insert` a new `HashMap` into the `alloy`.
impl UrlEncoded {
    pub fn new() -> UrlEncoded {
        UrlEncoded
    }
}

impl Middleware for UrlEncoded {

    fn enter(&mut self, req: &mut Request, res: &mut Response, alloy: &mut Alloy) -> Status {

        let raw_url = req.url();

        let path = match raw_url {
            Some(k) => {
                url::path_from_str(k.as_slice())
            },
            None => {
                return Continue;
            }
        };

        let query = match path {
            Ok(e) => {
                e.query
            },
            Err(_) => {
                return Continue;
            }
        };
        alloy.insert::<Encoded>(Encoded(create_hash(query)));
        Continue
    }
}

fn create_hash(q: Vec<(String, String)>) -> HashMap<String, Vec<String>> {

    let mut hashStrVec: HashMap<String, Vec<String>> = HashMap::new();

    for (k, v) in q.move_iter() {
        hashStrVec.find_with_or_insert_with(
            k, v,
            |_, already, new| {
                already.push(new);
            },
            |_, v| vec![v]
        );
    }
    hashStrVec
}

#[test]
fn test_create_hash() {
    let my_vec = vec!(("band".to_string(), "arctic monkeys".to_string()),("band".to_string(), "temper trap".to_string()),("color".to_string(),"green".to_string()));
    let answer = create_hash(my_vec);
    let mut control = HashMap::new();
    control.insert("band".to_string(), vec!("arctic monkeys".to_string(), "temper trap".to_string()));
    control.insert("color".to_string(), vec!("green".to_string()));
    assert!(answer==control);
}
<|endoftext|>


<commit_before>/*!
Miscellaneous utilities grab-bag.

 */

#![crate_name="calx"]
#![feature(core, collections, std_misc, thread_sleep)]
#![feature(plugin, custom_attribute)]
#![plugin(regex_macros, glium_macros)]

extern crate collections;
extern crate rustc_serialize;
extern crate time;
extern crate rand;
extern crate regex;
extern crate image;
extern crate glutin;
#[macro_use]
extern crate glium;

use std::env;
use std::path::{Path, PathBuf};
use std::num::wrapping::Wrapping;

pub use rgb::{Rgb, Rgba};
pub use geom::{V2, V3, Rect, RectIter};
pub use img::{color_key};
pub use atlas::{AtlasBuilder, Atlas, AtlasItem};
pub use dijkstra::{DijkstraNode, Dijkstra};
pub use encode_rng::{EncodeRng};

mod atlas;
mod dijkstra;
mod geom;
mod encode_rng;
mod img;
mod primitive;
mod rgb;

pub mod backend;
pub mod color;
pub mod text;
pub mod timing;
pub mod vorud;

pub trait Color: Sized {
    fn to_rgba(&self) -> [f32; 4];
    fn from_color<C: Color>(color: &C) -> Self;

    fn from_rgba(rgba: [f32; 4]) -> Self {
        Color::from_color(&rgb::Rgba::new(
                (rgba[0] * 255.0) as u8,
                (rgba[1] * 255.0) as u8,
                (rgba[2] * 255.0) as u8,
                (rgba[3] * 255.0) as u8))
    }
}

/// Clamp a value to range.
pub fn clamp<C: PartialOrd+Copy>(mn: C, mx: C, x: C) -> C {
    if x < mn { mn }
    else if x > mx { mx }
    else { x }
}

/// Deterministic noise.
pub fn noise(n: i32) -> f32 {
    let n = Wrapping(n);
    let n = (n << 13) ^ n;
    let m = (n * (n * n * Wrapping(15731) + Wrapping(789221)) + Wrapping(1376312589))
        & Wrapping(0x7fffffff);
    let Wrapping(m) = m;
    1.0 - m as f32 / 1073741824.0
}

/// Rectangle anchoring points.
#[derive(Copy, PartialEq, Debug)]
pub enum Anchor {
    TopLeft,
    TopRight,
    BottomLeft,
    BottomRight,
    Top,
    Left,
    Right,
    Bottom,
    Center
}

/// Return the application data directory path for the current platform.
#[cfg(target_os = "macos")]
pub fn app_data_path(app_name: &str) -> PathBuf {
    Path::new(
        format!("{}/Library/Application Support/{}",
                env::var("HOME").unwrap(), app_name))
    .to_path_buf()
}

#[cfg(target_os = "windows")]
pub fn app_data_path(app_name: &str) -> PathBuf {
    Path::new(
    format!("{}\\{}", env::var("APPDATA").unwrap(), app_name))
    .to_path_buf()
}

#[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
pub fn app_data_path(app_name: &str) -> PathBuf {
    Path::new(
        &format!("{}/.config/{}", env::var("HOME").unwrap(), app_name))
    .to_path_buf()
}

#[cfg(test)]
mod test {
    #[test]
    fn test_noise() {
        use super::noise;

        for i in 0i32..100 {
            assert!(noise(i) >= -1.0 && noise(i) <= 1.0);
        }
    }
}
<commit_msg>Windows application path is suitable for a portable application<commit_after>/*!
Miscellaneous utilities grab-bag.

 */

#![crate_name="calx"]
#![feature(core, collections, std_misc, thread_sleep)]
#![feature(plugin, custom_attribute)]
#![plugin(regex_macros, glium_macros)]

extern crate collections;
extern crate rustc_serialize;
extern crate time;
extern crate rand;
extern crate regex;
extern crate image;
extern crate glutin;
#[macro_use]
extern crate glium;

use std::env;
use std::path::{Path, PathBuf};
use std::num::wrapping::Wrapping;

pub use rgb::{Rgb, Rgba};
pub use geom::{V2, V3, Rect, RectIter};
pub use img::{color_key};
pub use atlas::{AtlasBuilder, Atlas, AtlasItem};
pub use dijkstra::{DijkstraNode, Dijkstra};
pub use encode_rng::{EncodeRng};

mod atlas;
mod dijkstra;
mod geom;
mod encode_rng;
mod img;
mod primitive;
mod rgb;

pub mod backend;
pub mod color;
pub mod text;
pub mod timing;
pub mod vorud;

pub trait Color: Sized {
    fn to_rgba(&self) -> [f32; 4];
    fn from_color<C: Color>(color: &C) -> Self;

    fn from_rgba(rgba: [f32; 4]) -> Self {
        Color::from_color(&rgb::Rgba::new(
                (rgba[0] * 255.0) as u8,
                (rgba[1] * 255.0) as u8,
                (rgba[2] * 255.0) as u8,
                (rgba[3] * 255.0) as u8))
    }
}

/// Clamp a value to range.
pub fn clamp<C: PartialOrd+Copy>(mn: C, mx: C, x: C) -> C {
    if x < mn { mn }
    else if x > mx { mx }
    else { x }
}

/// Deterministic noise.
pub fn noise(n: i32) -> f32 {
    let n = Wrapping(n);
    let n = (n << 13) ^ n;
    let m = (n * (n * n * Wrapping(15731) + Wrapping(789221)) + Wrapping(1376312589))
        & Wrapping(0x7fffffff);
    let Wrapping(m) = m;
    1.0 - m as f32 / 1073741824.0
}

/// Rectangle anchoring points.
#[derive(Copy, PartialEq, Debug)]
pub enum Anchor {
    TopLeft,
    TopRight,
    BottomLeft,
    BottomRight,
    Top,
    Left,
    Right,
    Bottom,
    Center
}

/// Return the application data directory path for the current platform.
#[cfg(target_os = "macos")]
pub fn app_data_path(app_name: &str) -> PathBuf {
    Path::new(
        format!("{}/Library/Application Support/{}",
                env::var("HOME").unwrap(), app_name))
    .to_path_buf()
}

#[cfg(target_os = "windows")]
pub fn app_data_path(_app_name: &str) -> PathBuf {
    use std::os;

    // Unless the Windows app was installed with an actual installer instead
    // of just being a portable .exe file, it shouldn't go around creating
    // strange directories but just use the local directory instead.

    // Path::new(
    // format!("{}\\{}", env::var("APPDATA").unwrap(), app_name))
    // .to_path_buf();

    match os::self_exe_path() {
        Some(p) => p.to_path_buf(),
        // If couldn't get self exe path, just use the local relative path and
        // hope for the best.
        _ => Path::new(".").to_path_buf()
    }
}

#[cfg(all(not(target_os = "windows"), not(target_os = "macos")))]
pub fn app_data_path(app_name: &str) -> PathBuf {
    Path::new(
        &format!("{}/.config/{}", env::var("HOME").unwrap(), app_name))
    .to_path_buf()
}

#[cfg(test)]
mod test {
    #[test]
    fn test_noise() {
        use super::noise;

        for i in 0i32..100 {
            assert!(noise(i) >= -1.0 && noise(i) <= 1.0);
        }
    }
}
<|endoftext|>


<commit_before>//! Winit allows you to build a window on as many platforms as possible.
//!
//! # Building a window
//!
//! Before you can build a [`Window`], you first need to build an [`EventLoop`]. This is done with the
//! [`EventLoop::new()`] function.
//!
//! ```no_run
//! use winit::event_loop::EventLoop;
//! let event_loop = EventLoop::new();
//! ```
//!
//! Once this is done there are two ways to create a [`Window`]:
//!
//!  - Calling [`Window::new(&event_loop)`][window_new].
//!  - Calling [`let builder = WindowBuilder::new()`][window_builder_new] then [`builder.build(&event_loop)`][window_builder_build].
//!
//! The first way is the simplest way and will give you default values for everything.
//!
//! The second way allows you to customize the way your [`Window`] will look and behave by modifying
//! the fields of the [`WindowBuilder`] object before you create the [`Window`].
//!
//! # Event handling
//!
//! Once a [`Window`] has been created, it will *generate events*. For example whenever the user moves
//! the [`Window`], resizes the [`Window`], moves the mouse, etc. an event is generated.
//!
//! The events generated by a [`Window`] can be retreived from the [`EventLoop`] the [`Window`] was created
//! with.
//!
//! You do this by calling [`event_loop.run(...)`][event_loop_run]. This function will run forever
//! unless `control_flow` is set to [`ControlFlow`]`::`[`Exit`], at which point [`Event`]`::`[`LoopDestroyed`]
//! is emitted and the entire program terminates.
//!
//! ```no_run
//! use winit::{
//!     event::{Event, WindowEvent},
//!     event_loop::ControlFlow,
//! };
//! # use winit::event_loop::EventLoop;
//! # let event_loop = EventLoop::new();
//!
//! event_loop.run(move |event, _, control_flow| {
//!     match event {
//!         Event::WindowEvent {
//!             event: WindowEvent::CloseRequested,
//!             ..
//!         } => {
//!             println!("The close button was pressed; stopping");
//!             *control_flow = ControlFlow::Exit
//!         },
//!         _ => *control_flow = ControlFlow::Wait,
//!     }
//! });
//! ```
//!
//! If you use multiple [`Window`]s, [`Event`]`::`[`WindowEvent`] has a member named `window_id`. You can
//! compare it with the value returned by the [`id()`][window_id_fn] method of [`Window`] in order to know which
//! [`Window`] has received the event.
//!
//! # Drawing on the window
//!
//! Winit doesn't provide any function that allows drawing on a [`Window`]. However it allows you to
//! retrieve the raw handle of the window (see the [`platform`] module), which in turn allows you
//! to create an OpenGL/Vulkan/DirectX/Metal/etc. context that will draw on the [`Window`].
//!
//! [`EventLoop`]: ./event_loop/struct.EventLoop.html
//! [`EventLoop::new()`]: ./event_loop/struct.EventLoop.html#method.new
//! [event_loop_run]: ./event_loop/struct.EventLoop.html#method.run
//! [`ControlFlow`]: ./event_loop/enum.ControlFlow.html
//! [`Exit`]: ./event_loop/enum.ControlFlow.html#variant.Exit
//! [`Window`]: ./window/struct.Window.html
//! [`WindowBuilder`]: ./window/struct.WindowBuilder.html
//! [window_new]: ./window/struct.Window.html#method.new
//! [window_builder_new]: ./window/struct.WindowBuilder.html#method.new
//! [window_builder_build]: ./window/struct.WindowBuilder.html#method.build
//! [window_id_fn]: ./window/struct.Window.html#method.id
//! [`Event`]: ./event/enum.Event.html
//! [`WindowEvent`]: ./event/enum.Event.html#variant.WindowEvent
//! [`LoopDestroyed`]: ./event/enum.Event.html#variant.LoopDestroyed
//! [`platform`]: ./platform/index.html

#![deny(rust_2018_idioms)]

#[allow(unused_imports)]
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
#[cfg(feature = "serde")]
#[macro_use]
extern crate serde;
#[macro_use]
#[cfg(target_os = "windows")]
extern crate derivative;
#[macro_use]
#[cfg(target_os = "windows")]
extern crate bitflags;
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[macro_use]
extern crate objc;

pub mod dpi;
#[macro_use]
pub mod error;
pub mod event;
pub mod event_loop;
mod icon;
pub mod monitor;
mod platform_impl;
pub mod window;

pub mod platform;
<commit_msg>Improve the example in lib.rs (#957)<commit_after>//! Winit allows you to build a window on as many platforms as possible.
//!
//! # Building a window
//!
//! Before you can build a [`Window`], you first need to build an [`EventLoop`]. This is done with the
//! [`EventLoop::new()`] function.
//!
//! ```no_run
//! use winit::event_loop::EventLoop;
//! let event_loop = EventLoop::new();
//! ```
//!
//! Once this is done there are two ways to create a [`Window`]:
//!
//!  - Calling [`Window::new(&event_loop)`][window_new].
//!  - Calling [`let builder = WindowBuilder::new()`][window_builder_new] then [`builder.build(&event_loop)`][window_builder_build].
//!
//! The first way is the simplest way and will give you default values for everything.
//!
//! The second way allows you to customize the way your [`Window`] will look and behave by modifying
//! the fields of the [`WindowBuilder`] object before you create the [`Window`].
//!
//! # Event handling
//!
//! Once a [`Window`] has been created, it will *generate events*. For example whenever the user moves
//! the [`Window`], resizes the [`Window`], moves the mouse, etc. an event is generated.
//!
//! The events generated by a [`Window`] can be retreived from the [`EventLoop`] the [`Window`] was created
//! with.
//!
//! You do this by calling [`event_loop.run(...)`][event_loop_run]. This function will run forever
//! unless `control_flow` is set to [`ControlFlow`]`::`[`Exit`], at which point [`Event`]`::`[`LoopDestroyed`]
//! is emitted and the entire program terminates.
//!
//! ```no_run
//! use winit::{
//!     event::{Event, WindowEvent},
//!     event_loop::{ControlFlow, EventLoop},
//!     window::WindowBuilder,
//! };
//!
//! let event_loop = EventLoop::new();
//! let window = WindowBuilder::new().build(&event_loop).unwrap();
//!
//! event_loop.run(move |event, _, control_flow| {
//!     match event {
//!         Event::EventsCleared => {
//!             // Application update code.
//!
//!             // Queue a RedrawRequested event.
//!             window.request_redraw();
//!         },
//!         Event::WindowEvent {
//!             event: WindowEvent::RedrawRequested,
//!             ..
//!         } => {
//!             // Redraw the application.
//!             //
//!             // It's preferrable to render in this event rather than in EventsCleared, since
//!             // rendering in here allows the program to gracefully handle redraws requested
//!             // by the OS.
//!         },
//!         Event::WindowEvent {
//!             event: WindowEvent::CloseRequested,
//!             ..
//!         } => {
//!             println!("The close button was pressed; stopping");
//!             *control_flow = ControlFlow::Exit
//!         },
//!         // ControlFlow::Poll continuously runs the event loop, even if the OS hasn't
//!         // dispatched any events. This is ideal for games and similar applications.
//!         _ => *control_flow = ControlFlow::Poll,
//!         // ControlFlow::Wait pauses the event loop if no events are available to process.
//!         // This is ideal for non-game applications that only update in response to user
//!         // input, and uses significantly less power/CPU time than ControlFlow::Poll.
//!         // _ => *control_flow = ControlFlow::Wait,
//!     }
//! });
//! ```
//!
//! If you use multiple [`Window`]s, [`Event`]`::`[`WindowEvent`] has a member named `window_id`. You can
//! compare it with the value returned by the [`id()`][window_id_fn] method of [`Window`] in order to know which
//! [`Window`] has received the event.
//!
//! # Drawing on the window
//!
//! Winit doesn't provide any function that allows drawing on a [`Window`]. However it allows you to
//! retrieve the raw handle of the window (see the [`platform`] module), which in turn allows you
//! to create an OpenGL/Vulkan/DirectX/Metal/etc. context that will draw on the [`Window`].
//!
//! [`EventLoop`]: ./event_loop/struct.EventLoop.html
//! [`EventLoop::new()`]: ./event_loop/struct.EventLoop.html#method.new
//! [event_loop_run]: ./event_loop/struct.EventLoop.html#method.run
//! [`ControlFlow`]: ./event_loop/enum.ControlFlow.html
//! [`Exit`]: ./event_loop/enum.ControlFlow.html#variant.Exit
//! [`Window`]: ./window/struct.Window.html
//! [`WindowBuilder`]: ./window/struct.WindowBuilder.html
//! [window_new]: ./window/struct.Window.html#method.new
//! [window_builder_new]: ./window/struct.WindowBuilder.html#method.new
//! [window_builder_build]: ./window/struct.WindowBuilder.html#method.build
//! [window_id_fn]: ./window/struct.Window.html#method.id
//! [`Event`]: ./event/enum.Event.html
//! [`WindowEvent`]: ./event/enum.Event.html#variant.WindowEvent
//! [`LoopDestroyed`]: ./event/enum.Event.html#variant.LoopDestroyed
//! [`platform`]: ./platform/index.html

#![deny(rust_2018_idioms)]

#[allow(unused_imports)]
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
#[cfg(feature = "serde")]
#[macro_use]
extern crate serde;
#[macro_use]
#[cfg(target_os = "windows")]
extern crate derivative;
#[macro_use]
#[cfg(target_os = "windows")]
extern crate bitflags;
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[macro_use]
extern crate objc;

pub mod dpi;
#[macro_use]
pub mod error;
pub mod event;
pub mod event_loop;
mod icon;
pub mod monitor;
mod platform_impl;
pub mod window;

pub mod platform;
<|endoftext|>


<commit_before>// Copyright 2012-2014 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.

//! Support code for encoding and decoding types.

#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/rustc-serialize/")]
#![cfg_attr(test, deny(warnings))]

// test harness access
#[cfg(test)]
extern crate test;

extern crate unicode;

pub use self::serialize::{Decoder, Encoder, Decodable, Encodable,
                          DecoderHelpers, EncoderHelpers};

mod serialize;
mod collection_impls;

pub mod base64;
pub mod hex;
pub mod json;

mod rustc_serialize {
    pub use serialize::*;
}
<commit_msg>Allow unstable warnings during tests<commit_after>// Copyright 2012-2014 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.

//! Support code for encoding and decoding types.

#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/rustc-serialize/")]
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(test, allow(unstable))]

// test harness access
#[cfg(test)]
extern crate test;

extern crate unicode;

pub use self::serialize::{Decoder, Encoder, Decodable, Encodable,
                          DecoderHelpers, EncoderHelpers};

mod serialize;
mod collection_impls;

pub mod base64;
pub mod hex;
pub mod json;

mod rustc_serialize {
    pub use serialize::*;
}
<|endoftext|>


<commit_before>#![crate_id="civet"]
#![crate_type="rlib"]

extern crate libc;
extern crate debug;
extern crate native;
extern crate collections;

use std::io;
use std::io::net::ip::{IpAddr, Ipv4Addr};
use std::io::{IoResult,util};
use std::collections::HashMap;

use raw::{RequestInfo,Header};
use raw::{get_header,get_headers,get_request_info};
use status::{ToStatusCode};

pub use raw::Config;

mod raw;
pub mod status;

pub struct Connection<'a> {
    request: Request<'a>
}

pub struct Request<'a> {
    conn: &'a raw::Connection,
    request_info: RequestInfo<'a>
}

pub struct CopiedRequest {
    pub headers: HashMap<String, String>,
    pub method: Option<String>,
    pub url: Option<String>,
    pub http_version: Option<String>,
    pub query_string: Option<String>,
    pub remote_user: Option<String>,
    pub remote_ip: IpAddr,
    pub remote_port: u16,
    pub is_ssl: bool
}

impl<'a> Request<'a> {
    pub fn copy(&self) -> CopiedRequest {
        let mut headers = HashMap::new();

        for (key, value) in self.headers().iter() {
            headers.insert(key.to_str(), value.to_str());
        }

        CopiedRequest {
            headers: headers,
            method: self.method().map(|a| a.to_str()),
            url: self.url().map(|a| a.to_str()),
            http_version: self.http_version().map(|a| a.to_str()),
            query_string: self.query_string().map(|a| a.to_str()),
            remote_user: self.remote_user().map(|a| a.to_str()),
            remote_ip: self.remote_ip(),
            remote_port: self.remote_port(),
            is_ssl: self.is_ssl()
        }
    }

    pub fn get_header<S: Str>(&mut self, string: S) -> Option<String> {
        get_header(self.conn, string.as_slice())
    }

    pub fn count_headers(&self) -> uint {
        self.request_info.num_headers() as uint
    }

    pub fn method<'a>(&'a self) -> Option<&'a str> {
        self.request_info.method()
    }

    pub fn url<'a>(&'a self) -> Option<&'a str> {
        self.request_info.url()
    }

    pub fn http_version<'a>(&'a self) -> Option<&'a str> {
        self.request_info.http_version()
    }

    pub fn query_string<'a>(&'a self) -> Option<&'a str> {
        self.request_info.query_string()
    }

    pub fn remote_user<'a>(&'a self) -> Option<&'a str> {
        self.request_info.remote_user()
    }

    pub fn remote_ip(&self) -> IpAddr {
        let ip = self.request_info.remote_ip();
        Ipv4Addr((ip >> 24) as u8,
                 (ip >> 16) as u8,
                 (ip >>  8) as u8,
                 (ip >>  0) as u8)
    }

    pub fn remote_port(&self) -> u16 {
        self.request_info.remote_port() as u16
    }

    pub fn is_ssl(&self) -> bool {
        self.request_info.is_ssl()
    }

    pub fn headers<'a>(&'a self) -> Headers<'a> {
        Headers { conn: self.conn }
    }
}

pub struct Response {
    status: status::StatusCode,
    headers: HashMap<String, String>,
    body: Box<Reader + Send>,
}

impl Response {
    pub fn new<S: ToStatusCode, R: Reader + Send>(
        status: S,
        headers: HashMap<String, String>,
        body: R) -> Response
    {
        Response {
            status: status.to_status().unwrap(),
            headers: headers,
            body: box body,
        }
    }
}

impl<'a> Connection<'a> {
    fn new<'a>(conn: &'a raw::Connection) -> Result<Connection<'a>, String> {
        match request_info(conn) {
            Ok(info) => {
                let request = Request { conn: conn, request_info: info };
                Ok(Connection {
                    request: request
                })
            },
            Err(err) => Err(err)
        }
    }

}

impl<'a> Writer for Connection<'a> {
    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
        write_bytes(self.request.conn, buf).map_err(|_| {
            io::standard_error(io::IoUnavailable)
        })
    }
}

impl<'a> Reader for Request<'a> {
    fn read(&mut self, buf: &mut[u8]) -> IoResult<uint> {
        let ret = raw::read(self.conn, buf);

        if ret == 0 {
            Err(io::standard_error(io::EndOfFile))
        } else {
            Ok(ret as uint)
        }
    }
}

pub struct Headers<'a> {
    conn: &'a raw::Connection
}

impl<'a> Headers<'a> {
    pub fn find<S: Str>(&self, string: S) -> Option<String> {
        get_header(self.conn, string.as_slice())
    }

    pub fn iter<'a>(&'a self) -> HeaderIterator<'a> {
        HeaderIterator::new(self.conn)
    }
}

pub struct HeaderIterator<'a> {
    headers: Vec<Header<'a>>,
    position: uint
}

impl<'a> HeaderIterator<'a> {
    fn new<'b>(conn: &'b raw::Connection) -> HeaderIterator<'b> {
        HeaderIterator { headers: get_headers(conn), position: 0 }
    }
}

impl<'a> Iterator<(&'a str, &'a str)> for HeaderIterator<'a> {
    fn next(&mut self) -> Option<(&'a str, &'a str)> {
        let pos = self.position;
        let headers = &self.headers;

        if self.headers.len() <= pos {
            None
        } else {
            let header = headers.get(pos);
            self.position += 1;
            header.name().map(|name| (name, header.value().unwrap()))
        }
    }
}

pub trait Handler {
    fn call(&self, req: &mut Request) -> IoResult<Response>;
}

impl Handler for fn(&mut Request) -> IoResult<Response> {
    fn call(&self, req: &mut Request) -> IoResult<Response> {
        (*self)(req)
    }
}

// TODO: Why is 'static needed here and below?
pub struct Server(raw::Server<Box<Handler + 'static + Share>>);

impl Server {
    pub fn start<H: 'static + Handler + Share>(options: Config, handler: H)
        -> IoResult<Server>
    {
        fn internal_handler(conn: &mut raw::Connection,
                            handler: &Box<Handler>) -> Result<(), ()> {
            let mut connection = Connection::new(conn).unwrap();
            let response = handler.call(&mut connection.request);
            let writer = &mut connection;

            fn err<W: Writer>(writer: &mut W) {
                let _ = writeln!(writer, "HTTP/1.1 500 Internal Server Error");
            }

            let Response { status, headers, mut body } = match response {
                Ok(r) => r,
                Err(_) => return Err(err(writer)),
            };
            let (code, string) = status.to_code();
            try!(write!(writer, "HTTP/1.1 {} {}\r\n", code, string).map_err(|_| ()));

            for (key, value) in headers.iter() {
                try!(write!(writer, "{}: {}\r\n", key, value).map_err(|_| ()));
            }

            try!(write!(writer, "\r\n").map_err(|_| ()));
            try!(util::copy(&mut body, writer).map_err(|_| ()));

            Ok(())
        }

        let raw_callback = raw::ServerCallback::new(internal_handler,
                                                    box handler);
        Ok(Server(try!(raw::Server::start(options, raw_callback))))
    }
}

fn write_bytes(connection: &raw::Connection, bytes: &[u8]) -> Result<(), String> {
    let ret = raw::write(connection, bytes);

    if ret == -1 {
        return Err("Couldn't write bytes to the connection".to_str())
    }

    Ok(())
}

fn request_info<'a>(connection: &'a raw::Connection)
    -> Result<RequestInfo<'a>, String>
{
    match get_request_info(connection) {
        Some(info) => Ok(info),
        None => Err("Couldn't get request info for connection".to_str())
    }
}

#[cfg(test)]
mod test {
    use std::collections::HashMap;
    use std::io::net::ip::SocketAddr;
    use std::io::net::tcp::TcpStream;
    use std::io::test::next_test_ip4;
    use std::io::{IoResult, MemReader};
    use std::sync::Mutex;
    use super::{Server, Config, Request, Response, Handler};

    fn noop(_: &mut Request) -> IoResult<Response> { unreachable!() }

    fn request(addr: SocketAddr, req: &str) -> String {
        let mut s = TcpStream::connect(addr.ip.to_str().as_slice(),
                                       addr.port).unwrap();
        s.write_str(req.trim_left()).unwrap();
        s.read_to_str().unwrap()
    }

    #[test]
    fn smoke() {
        let addr = next_test_ip4();
        Server::start(Config { port: addr.port, threads: 1 }, noop).unwrap();
    }

    #[test]
    fn dupe_port() {
        let addr = next_test_ip4();
        let s1 = Server::start(Config { port: addr.port, threads: 1 }, noop);
        assert!(s1.is_ok());
        let s2 = Server::start(Config { port: addr.port, threads: 1 }, noop);
        assert!(s2.is_err());
    }

    #[test]
    fn drops_handler() {
        static mut DROPPED: bool = false;
        struct Foo;
        impl Handler for Foo {
            fn call(&self, _req: &mut Request) -> IoResult<Response> {
                fail!()
            }
        }
        impl Drop for Foo {
            fn drop(&mut self) { unsafe { DROPPED = true; } }
        }

        let addr = next_test_ip4();
        drop(Server::start(Config { port: addr.port, threads: 1 }, Foo));
        unsafe { assert!(DROPPED); }
    }

    #[test]
    fn invokes() {
        struct Foo(Mutex<Sender<()>>);
        impl Handler for Foo {
            fn call(&self, _req: &mut Request) -> IoResult<Response> {
                let Foo(ref tx) = *self;
                tx.lock().send(());
                Ok(Response::new(200, HashMap::new(), MemReader::new(vec![])))
            }
        }

        let addr = next_test_ip4();
        let (tx, rx) = channel();
        let handler = Foo(Mutex::new(tx));
        let _s = Server::start(Config { port: addr.port, threads: 1 }, handler);
        request(addr, r"
GET / HTTP/1.1

");
        rx.recv();
    }

    #[test]
    fn header_sent() {
        struct Foo(Mutex<Sender<String>>);
        impl Handler for Foo {
            fn call(&self, req: &mut Request) -> IoResult<Response> {
                let Foo(ref tx) = *self;
                tx.lock().send(req.get_header("Foo").unwrap());
                Ok(Response::new(200, HashMap::new(), MemReader::new(vec![])))
            }
        }

        let addr = next_test_ip4();
        let (tx, rx) = channel();
        let handler = Foo(Mutex::new(tx));
        let _s = Server::start(Config { port: addr.port, threads: 1 }, handler);
        request(addr, r"
GET / HTTP/1.1
Foo: bar

");
        assert_eq!(rx.recv().as_slice(), "bar");
    }

    #[test]
    fn failing_handler() {
        struct Foo;
        impl Handler for Foo {
            fn call(&self, _req: &mut Request) -> IoResult<Response> {
                fail!()
            }
        }

        let addr = next_test_ip4();
        let _s = Server::start(Config { port: addr.port, threads: 1 }, Foo);
        request(addr, r"
GET / HTTP/1.1
Foo: bar

");
    }
}
<commit_msg>Turn task failure into a 500 error<commit_after>#![crate_id="civet"]
#![crate_type="rlib"]

extern crate libc;
extern crate debug;
extern crate native;
extern crate collections;

use std::io;
use std::io::net::ip::{IpAddr, Ipv4Addr};
use std::io::{IoResult,util};
use std::collections::HashMap;

use raw::{RequestInfo,Header};
use raw::{get_header,get_headers,get_request_info};
use status::{ToStatusCode};

pub use raw::Config;

mod raw;
pub mod status;

pub struct Connection<'a> {
    request: Request<'a>,
    written: bool,
}

pub struct Request<'a> {
    conn: &'a raw::Connection,
    request_info: RequestInfo<'a>
}

pub struct CopiedRequest {
    pub headers: HashMap<String, String>,
    pub method: Option<String>,
    pub url: Option<String>,
    pub http_version: Option<String>,
    pub query_string: Option<String>,
    pub remote_user: Option<String>,
    pub remote_ip: IpAddr,
    pub remote_port: u16,
    pub is_ssl: bool
}

impl<'a> Request<'a> {
    pub fn copy(&self) -> CopiedRequest {
        let mut headers = HashMap::new();

        for (key, value) in self.headers().iter() {
            headers.insert(key.to_str(), value.to_str());
        }

        CopiedRequest {
            headers: headers,
            method: self.method().map(|a| a.to_str()),
            url: self.url().map(|a| a.to_str()),
            http_version: self.http_version().map(|a| a.to_str()),
            query_string: self.query_string().map(|a| a.to_str()),
            remote_user: self.remote_user().map(|a| a.to_str()),
            remote_ip: self.remote_ip(),
            remote_port: self.remote_port(),
            is_ssl: self.is_ssl()
        }
    }

    pub fn get_header<S: Str>(&mut self, string: S) -> Option<String> {
        get_header(self.conn, string.as_slice())
    }

    pub fn count_headers(&self) -> uint {
        self.request_info.num_headers() as uint
    }

    pub fn method<'a>(&'a self) -> Option<&'a str> {
        self.request_info.method()
    }

    pub fn url<'a>(&'a self) -> Option<&'a str> {
        self.request_info.url()
    }

    pub fn http_version<'a>(&'a self) -> Option<&'a str> {
        self.request_info.http_version()
    }

    pub fn query_string<'a>(&'a self) -> Option<&'a str> {
        self.request_info.query_string()
    }

    pub fn remote_user<'a>(&'a self) -> Option<&'a str> {
        self.request_info.remote_user()
    }

    pub fn remote_ip(&self) -> IpAddr {
        let ip = self.request_info.remote_ip();
        Ipv4Addr((ip >> 24) as u8,
                 (ip >> 16) as u8,
                 (ip >>  8) as u8,
                 (ip >>  0) as u8)
    }

    pub fn remote_port(&self) -> u16 {
        self.request_info.remote_port() as u16
    }

    pub fn is_ssl(&self) -> bool {
        self.request_info.is_ssl()
    }

    pub fn headers<'a>(&'a self) -> Headers<'a> {
        Headers { conn: self.conn }
    }
}

pub struct Response {
    status: status::StatusCode,
    headers: HashMap<String, String>,
    body: Box<Reader + Send>,
}

impl Response {
    pub fn new<S: ToStatusCode, R: Reader + Send>(
        status: S,
        headers: HashMap<String, String>,
        body: R) -> Response
    {
        Response {
            status: status.to_status().unwrap(),
            headers: headers,
            body: box body,
        }
    }
}

impl<'a> Connection<'a> {
    fn new<'a>(conn: &'a raw::Connection) -> Result<Connection<'a>, String> {
        match request_info(conn) {
            Ok(info) => {
                let request = Request { conn: conn, request_info: info };
                Ok(Connection {
                    request: request,
                    written: false,
                })
            },
            Err(err) => Err(err)
        }
    }

}

impl<'a> Writer for Connection<'a> {
    fn write(&mut self, buf: &[u8]) -> IoResult<()> {
        self.written = true;
        write_bytes(self.request.conn, buf).map_err(|_| {
            io::standard_error(io::IoUnavailable)
        })
    }
}

impl<'a> Reader for Request<'a> {
    fn read(&mut self, buf: &mut[u8]) -> IoResult<uint> {
        let ret = raw::read(self.conn, buf);

        if ret == 0 {
            Err(io::standard_error(io::EndOfFile))
        } else {
            Ok(ret as uint)
        }
    }
}

#[unsafe_destructor]
impl<'a> Drop for Connection<'a> {
    fn drop(&mut self) {
        if !self.written {
            let _ = writeln!(self, "HTTP/1.1 500 Internal Server Error");
        }
    }
}

pub struct Headers<'a> {
    conn: &'a raw::Connection
}

impl<'a> Headers<'a> {
    pub fn find<S: Str>(&self, string: S) -> Option<String> {
        get_header(self.conn, string.as_slice())
    }

    pub fn iter<'a>(&'a self) -> HeaderIterator<'a> {
        HeaderIterator::new(self.conn)
    }
}

pub struct HeaderIterator<'a> {
    headers: Vec<Header<'a>>,
    position: uint
}

impl<'a> HeaderIterator<'a> {
    fn new<'b>(conn: &'b raw::Connection) -> HeaderIterator<'b> {
        HeaderIterator { headers: get_headers(conn), position: 0 }
    }
}

impl<'a> Iterator<(&'a str, &'a str)> for HeaderIterator<'a> {
    fn next(&mut self) -> Option<(&'a str, &'a str)> {
        let pos = self.position;
        let headers = &self.headers;

        if self.headers.len() <= pos {
            None
        } else {
            let header = headers.get(pos);
            self.position += 1;
            header.name().map(|name| (name, header.value().unwrap()))
        }
    }
}

pub trait Handler {
    fn call(&self, req: &mut Request) -> IoResult<Response>;
}

impl Handler for fn(&mut Request) -> IoResult<Response> {
    fn call(&self, req: &mut Request) -> IoResult<Response> {
        (*self)(req)
    }
}

// TODO: Why is 'static needed here and below?
pub struct Server(raw::Server<Box<Handler + 'static + Share>>);

impl Server {
    pub fn start<H: 'static + Handler + Share>(options: Config, handler: H)
        -> IoResult<Server>
    {
        fn internal_handler(conn: &mut raw::Connection,
                            handler: &Box<Handler>) -> Result<(), ()> {
            let mut connection = Connection::new(conn).unwrap();
            let response = handler.call(&mut connection.request);
            let writer = &mut connection;

            fn err<W: Writer>(writer: &mut W) {
                let _ = writeln!(writer, "HTTP/1.1 500 Internal Server Error");
            }

            let Response { status, headers, mut body } = match response {
                Ok(r) => r,
                Err(_) => return Err(err(writer)),
            };
            let (code, string) = status.to_code();
            try!(write!(writer, "HTTP/1.1 {} {}\r\n", code, string).map_err(|_| ()));

            for (key, value) in headers.iter() {
                try!(write!(writer, "{}: {}\r\n", key, value).map_err(|_| ()));
            }

            try!(write!(writer, "\r\n").map_err(|_| ()));
            try!(util::copy(&mut body, writer).map_err(|_| ()));

            Ok(())
        }

        let raw_callback = raw::ServerCallback::new(internal_handler,
                                                    box handler);
        Ok(Server(try!(raw::Server::start(options, raw_callback))))
    }
}

fn write_bytes(connection: &raw::Connection, bytes: &[u8]) -> Result<(), String> {
    let ret = raw::write(connection, bytes);

    if ret == -1 {
        return Err("Couldn't write bytes to the connection".to_str())
    }

    Ok(())
}

fn request_info<'a>(connection: &'a raw::Connection)
    -> Result<RequestInfo<'a>, String>
{
    match get_request_info(connection) {
        Some(info) => Ok(info),
        None => Err("Couldn't get request info for connection".to_str())
    }
}

#[cfg(test)]
mod test {
    use std::collections::HashMap;
    use std::io::net::ip::SocketAddr;
    use std::io::net::tcp::TcpStream;
    use std::io::test::next_test_ip4;
    use std::io::{IoResult, MemReader};
    use std::sync::Mutex;
    use super::{Server, Config, Request, Response, Handler};

    fn noop(_: &mut Request) -> IoResult<Response> { unreachable!() }

    fn request(addr: SocketAddr, req: &str) -> String {
        let mut s = TcpStream::connect(addr.ip.to_str().as_slice(),
                                       addr.port).unwrap();
        s.write_str(req.trim_left()).unwrap();
        s.read_to_str().unwrap()
    }

    #[test]
    fn smoke() {
        let addr = next_test_ip4();
        Server::start(Config { port: addr.port, threads: 1 }, noop).unwrap();
    }

    #[test]
    fn dupe_port() {
        let addr = next_test_ip4();
        let s1 = Server::start(Config { port: addr.port, threads: 1 }, noop);
        assert!(s1.is_ok());
        let s2 = Server::start(Config { port: addr.port, threads: 1 }, noop);
        assert!(s2.is_err());
    }

    #[test]
    fn drops_handler() {
        static mut DROPPED: bool = false;
        struct Foo;
        impl Handler for Foo {
            fn call(&self, _req: &mut Request) -> IoResult<Response> {
                fail!()
            }
        }
        impl Drop for Foo {
            fn drop(&mut self) { unsafe { DROPPED = true; } }
        }

        let addr = next_test_ip4();
        drop(Server::start(Config { port: addr.port, threads: 1 }, Foo));
        unsafe { assert!(DROPPED); }
    }

    #[test]
    fn invokes() {
        struct Foo(Mutex<Sender<()>>);
        impl Handler for Foo {
            fn call(&self, _req: &mut Request) -> IoResult<Response> {
                let Foo(ref tx) = *self;
                tx.lock().send(());
                Ok(Response::new(200, HashMap::new(), MemReader::new(vec![])))
            }
        }

        let addr = next_test_ip4();
        let (tx, rx) = channel();
        let handler = Foo(Mutex::new(tx));
        let _s = Server::start(Config { port: addr.port, threads: 1 }, handler);
        request(addr, r"
GET / HTTP/1.1

");
        rx.recv();
    }

    #[test]
    fn header_sent() {
        struct Foo(Mutex<Sender<String>>);
        impl Handler for Foo {
            fn call(&self, req: &mut Request) -> IoResult<Response> {
                let Foo(ref tx) = *self;
                tx.lock().send(req.get_header("Foo").unwrap());
                Ok(Response::new(200, HashMap::new(), MemReader::new(vec![])))
            }
        }

        let addr = next_test_ip4();
        let (tx, rx) = channel();
        let handler = Foo(Mutex::new(tx));
        let _s = Server::start(Config { port: addr.port, threads: 1 }, handler);
        request(addr, r"
GET / HTTP/1.1
Foo: bar

");
        assert_eq!(rx.recv().as_slice(), "bar");
    }

    #[test]
    fn failing_handler() {
        struct Foo;
        impl Handler for Foo {
            fn call(&self, _req: &mut Request) -> IoResult<Response> {
                fail!()
            }
        }

        let addr = next_test_ip4();
        let _s = Server::start(Config { port: addr.port, threads: 1 }, Foo);
        request(addr, r"
GET / HTTP/1.1
Foo: bar

");
    }

    #[test]
    fn failing_handler_is_500() {
        struct Foo;
        impl Handler for Foo {
            fn call(&self, _req: &mut Request) -> IoResult<Response> {
                fail!()
            }
        }

        let addr = next_test_ip4();
        let _s = Server::start(Config { port: addr.port, threads: 1 }, Foo);
        let response = request(addr, r"
GET / HTTP/1.1
Foo: bar

");
        assert!(response.as_slice().contains("500 Internal"),
                "not a failing response: {}", response);
    }
}
<|endoftext|>


<commit_before>#![feature(libc)]
#![feature(collections)]
#![feature(std_misc)]
//! Simple [libtecla](http://www.astro.caltech.edu/~mcs/tecla/libtecla.html) wrapper.

extern crate libc;
use libc::{c_char, c_int, size_t};

use std::ffi::{CString, CStr};
use std::string::as_string;
use std::str::from_utf8_unchecked;
use std::ptr;

pub type CplMatchFn = fn(*mut WordCompletion, *mut c_char, *const c_char, c_int) -> c_int;

#[repr(C)]
pub struct GetLine;
#[repr(C)]
pub struct ExpandFile;
/*pub struct FileExpansion {
    exists: c_int,
    nfile: c_int,
    files: *mut char,
}*/
#[repr(C)]
pub struct WordCompletion;

// will add functions as needed
#[link(name = "tecla")]
extern {
    fn new_GetLine(linelen: size_t, histlen: size_t) -> *mut GetLine;
    fn del_GetLine(gl: *mut GetLine) -> *mut GetLine;
    fn gl_get_line(gl: *mut GetLine,
                   prompt: *const c_char,
                   start_line: *const c_char,
                   start_pos: c_int) -> *const c_char;
    fn gl_query_char(gl: *mut GetLine, prompt: *const c_char, defchar: c_char) -> c_int;
    fn new_ExpandFile() -> *mut ExpandFile;
    fn del_ExpandFile(ef: *mut ExpandFile) -> *mut ExpandFile;
    // fn ef_expand_file(ef: *mut ExpandFile,
    //                  path: *const c_char,
    //                  pathlen: c_int) -> *mut FileExpansion;
    // fn el_list_expansions(result: *mut FileExpansion,
    //                      fp: *mut FILE,
    //                      term_width: c_int) -> c_int;
    // fn ef_last_error(ef: *mut ExpandFile) -> *const c_char;
    fn new_WordCompletion() -> *mut WordCompletion;
    fn del_WordCompletion(cpl: *mut WordCompletion) -> WordCompletion;
    /*fn gl_completion_action(gl: *mut GetLine,
                            data: *const void,
                            match_fn: CplMatchFn,
                            list_only: c_int,
                            name: *const c_char,
                            keyseq: *const c_char) -> c_int;*/
    fn gl_customize_completion(gl: *mut GetLine,
                               data: *const c_char,
                               match_fn: &CplMatchFn) -> c_int;
    fn gl_save_history(gl: *mut GetLine,
                       filename: *const c_char,
                       comment: *const c_char,
                       max_lines: c_int);
    fn gl_load_history(gl: *mut GetLine,
                       filename: *const c_char,
                       comment: *const c_char);
    fn gl_ignore_signal(gl: *mut GetLine, signo: c_int);
    fn gl_erase_terminal(gl: *mut GetLine) -> c_int;
    fn cpl_file_completions(cpl: *mut WordCompletion,
                            data: *const c_char,
                            line: *const c_char,
                            word_end: c_int) -> c_int;
    fn cpl_add_completion(cpl: *mut WordCompletion,
                          line: *const c_char,
                          word_start: c_int,
                          word_end: c_int,
                          suffix: *const c_char,
                          type_suffix: *const c_char,
                          cont_suffix: *const c_char) -> c_int;
}

///Creates new GetLine object
pub fn new_gl(linelen: u64, histlen: u64) -> *mut GetLine {
    let mut res: *mut GetLine;
    unsafe {
        res = new_GetLine(linelen, histlen);
    }
    res
}

///Deletes GetLine object
pub fn del_gl(gl: *mut GetLine) -> *mut GetLine {
    unsafe {
        del_GetLine(gl)
    }
}

///Creates new WordCompletion object
pub fn new_wc() -> *mut WordCompletion {
    unsafe {
        new_WordCompletion()
    }
}

///Deletes WordCompletion object
pub fn del_wc(cpl: *mut WordCompletion) -> WordCompletion {
    unsafe {
        del_WordCompletion(cpl)
    }
}

///Creates new ExpandFile object
pub fn new_ef() -> *mut ExpandFile {
    unsafe {
        new_ExpandFile()
    }
}

///Deletes ExpandFile object
pub fn del_ef(ef: *mut ExpandFile) -> *mut ExpandFile {
    unsafe {
        del_ExpandFile(ef)
    }
}

///Gets line from user using GetLine object
pub fn get_line(gl: *mut GetLine, prompt: &str) -> String {
    let c_prompt = CString::new(prompt.as_bytes()).unwrap();
    let start: *const i8 = ptr::null();
    let mut res: &str;
    unsafe {
        let out = CStr::from_ptr(gl_get_line(gl, c_prompt.as_ptr(), start, -1));
        res = from_utf8_unchecked(out.to_bytes());
    }
    as_string(res).clone()
}

///Returns the character read, or 0 if unreadable
pub fn query_char(gl: *mut GetLine, prompt: &str, defchar: char) -> char {
    let c_prompt = CString::new(prompt.as_bytes()).unwrap();
    let mut res: u8;
    unsafe {
        let out = gl_query_char(gl, c_prompt.as_ptr(), defchar as c_char);
        if out > 0 {
            res = out as u8;
        } else {
            res = 0;
        }
    }
    res as char
}

///Saves history to a file
pub fn save_history(gl: *mut GetLine, file: &str, comment: &str, max: usize) {
    let c_file = CString::new(file.as_bytes()).unwrap();
    let c_comment = CString::new(comment.as_bytes()).unwrap();
    let c_max = max as c_int;
    unsafe {
        gl_save_history(gl, c_file.as_ptr(), c_comment.as_ptr(), c_max)
    }
}

///Loads history from a file
pub fn load_history(gl: *mut GetLine, file: &str, comment: &str) {
    let c_file = CString::new(file.as_bytes()).unwrap();
    let c_comment = CString::new(comment.as_bytes()).unwrap();
    unsafe {
        gl_load_history(gl, c_file.as_ptr(), c_comment.as_ptr())
    }
}

///Ignore specified signal
pub fn ignore(gl: *mut GetLine, sig: isize) {
    unsafe {
        gl_ignore_signal(gl, sig as c_int)
    }
}

///Clear screen
pub fn clear(gl: *mut GetLine) -> i32 {
    unsafe {
        gl_erase_terminal(gl)
    }
}

///Sets the completion function
pub fn custom_complete(gl: *mut GetLine, data: &mut str, func: CplMatchFn) -> i32 {
    let c_data = CString::new(data.as_bytes()).unwrap();
    unsafe {
        gl_customize_completion(gl, c_data.as_ptr(), &func)
    }
}

///Calls built-in libtecla file completion function
pub fn builtin_complete(cpl: *mut WordCompletion,
                        data: *mut c_char,
                        line: *const c_char,
                        word_end: i32) -> i32 {
    unsafe {
        cpl_file_completions(cpl, data, line, word_end)
    }
}

///Calls cpl_add_completion
pub fn add_completion(wc: *mut WordCompletion,
                      line: *const c_char,
                      word_start: c_int,
                      word_end: c_int,
                      suffix: *const c_char,
                      type_suffix: *const c_char,
                      cont_suffix: *const c_char) -> c_int {
    unsafe {
        cpl_add_completion(wc, line, word_start, word_end, suffix, type_suffix, cont_suffix)
    }
}
<commit_msg>changed the mutability of data in one function. hopefully it doesn't break everything<commit_after>#![feature(libc)]
#![feature(collections)]
#![feature(std_misc)]
//! Simple [libtecla](http://www.astro.caltech.edu/~mcs/tecla/libtecla.html) wrapper.

extern crate libc;
use libc::{c_char, c_int, size_t};

use std::ffi::{CString, CStr};
use std::string::as_string;
use std::str::from_utf8_unchecked;
use std::ptr;

pub type CplMatchFn = fn(*mut WordCompletion, *mut c_char, *const c_char, c_int) -> c_int;

#[repr(C)]
pub struct GetLine;
#[repr(C)]
pub struct ExpandFile;
/*pub struct FileExpansion {
    exists: c_int,
    nfile: c_int,
    files: *mut char,
}*/
#[repr(C)]
pub struct WordCompletion;

// will add functions as needed
#[link(name = "tecla")]
extern {
    fn new_GetLine(linelen: size_t, histlen: size_t) -> *mut GetLine;
    fn del_GetLine(gl: *mut GetLine) -> *mut GetLine;
    fn gl_get_line(gl: *mut GetLine,
                   prompt: *const c_char,
                   start_line: *const c_char,
                   start_pos: c_int) -> *const c_char;
    fn gl_query_char(gl: *mut GetLine, prompt: *const c_char, defchar: c_char) -> c_int;
    fn new_ExpandFile() -> *mut ExpandFile;
    fn del_ExpandFile(ef: *mut ExpandFile) -> *mut ExpandFile;
    // fn ef_expand_file(ef: *mut ExpandFile,
    //                  path: *const c_char,
    //                  pathlen: c_int) -> *mut FileExpansion;
    // fn el_list_expansions(result: *mut FileExpansion,
    //                      fp: *mut FILE,
    //                      term_width: c_int) -> c_int;
    // fn ef_last_error(ef: *mut ExpandFile) -> *const c_char;
    fn new_WordCompletion() -> *mut WordCompletion;
    fn del_WordCompletion(cpl: *mut WordCompletion) -> WordCompletion;
    /*fn gl_completion_action(gl: *mut GetLine,
                            data: *const void,
                            match_fn: CplMatchFn,
                            list_only: c_int,
                            name: *const c_char,
                            keyseq: *const c_char) -> c_int;*/
    fn gl_customize_completion(gl: *mut GetLine,
                               data: *const c_char,
                               match_fn: &CplMatchFn) -> c_int;
    fn gl_save_history(gl: *mut GetLine,
                       filename: *const c_char,
                       comment: *const c_char,
                       max_lines: c_int);
    fn gl_load_history(gl: *mut GetLine,
                       filename: *const c_char,
                       comment: *const c_char);
    fn gl_ignore_signal(gl: *mut GetLine, signo: c_int);
    fn gl_erase_terminal(gl: *mut GetLine) -> c_int;
    fn cpl_file_completions(cpl: *mut WordCompletion,
                            data: *const c_char,
                            line: *const c_char,
                            word_end: c_int) -> c_int;
    fn cpl_add_completion(cpl: *mut WordCompletion,
                          line: *const c_char,
                          word_start: c_int,
                          word_end: c_int,
                          suffix: *const c_char,
                          type_suffix: *const c_char,
                          cont_suffix: *const c_char) -> c_int;
}

///Creates new GetLine object
pub fn new_gl(linelen: u64, histlen: u64) -> *mut GetLine {
    let mut res: *mut GetLine;
    unsafe {
        res = new_GetLine(linelen, histlen);
    }
    res
}

///Deletes GetLine object
pub fn del_gl(gl: *mut GetLine) -> *mut GetLine {
    unsafe {
        del_GetLine(gl)
    }
}

///Creates new WordCompletion object
pub fn new_wc() -> *mut WordCompletion {
    unsafe {
        new_WordCompletion()
    }
}

///Deletes WordCompletion object
pub fn del_wc(cpl: *mut WordCompletion) -> WordCompletion {
    unsafe {
        del_WordCompletion(cpl)
    }
}

///Creates new ExpandFile object
pub fn new_ef() -> *mut ExpandFile {
    unsafe {
        new_ExpandFile()
    }
}

///Deletes ExpandFile object
pub fn del_ef(ef: *mut ExpandFile) -> *mut ExpandFile {
    unsafe {
        del_ExpandFile(ef)
    }
}

///Gets line from user using GetLine object
pub fn get_line(gl: *mut GetLine, prompt: &str) -> String {
    let c_prompt = CString::new(prompt.as_bytes()).unwrap();
    let start: *const i8 = ptr::null();
    let mut res: &str;
    unsafe {
        let out = CStr::from_ptr(gl_get_line(gl, c_prompt.as_ptr(), start, -1));
        res = from_utf8_unchecked(out.to_bytes());
    }
    as_string(res).clone()
}

///Returns the character read, or 0 if unreadable
pub fn query_char(gl: *mut GetLine, prompt: &str, defchar: char) -> char {
    let c_prompt = CString::new(prompt.as_bytes()).unwrap();
    let mut res: u8;
    unsafe {
        let out = gl_query_char(gl, c_prompt.as_ptr(), defchar as c_char);
        if out > 0 {
            res = out as u8;
        } else {
            res = 0;
        }
    }
    res as char
}

///Saves history to a file
pub fn save_history(gl: *mut GetLine, file: &str, comment: &str, max: usize) {
    let c_file = CString::new(file.as_bytes()).unwrap();
    let c_comment = CString::new(comment.as_bytes()).unwrap();
    let c_max = max as c_int;
    unsafe {
        gl_save_history(gl, c_file.as_ptr(), c_comment.as_ptr(), c_max)
    }
}

///Loads history from a file
pub fn load_history(gl: *mut GetLine, file: &str, comment: &str) {
    let c_file = CString::new(file.as_bytes()).unwrap();
    let c_comment = CString::new(comment.as_bytes()).unwrap();
    unsafe {
        gl_load_history(gl, c_file.as_ptr(), c_comment.as_ptr())
    }
}

///Ignore specified signal
pub fn ignore(gl: *mut GetLine, sig: isize) {
    unsafe {
        gl_ignore_signal(gl, sig as c_int)
    }
}

///Clear screen
pub fn clear(gl: *mut GetLine) -> i32 {
    unsafe {
        gl_erase_terminal(gl)
    }
}

///Sets the completion function
pub fn custom_complete(gl: *mut GetLine, data: &str, func: CplMatchFn) -> i32 {
    let c_data = CString::new(data.as_bytes()).unwrap();
    unsafe {
        gl_customize_completion(gl, c_data.as_ptr(), &func)
    }
}

///Calls built-in libtecla file completion function
pub fn builtin_complete(cpl: *mut WordCompletion,
                        data: *mut c_char,
                        line: *const c_char,
                        word_end: i32) -> i32 {
    unsafe {
        cpl_file_completions(cpl, data, line, word_end)
    }
}

///Calls cpl_add_completion
pub fn add_completion(wc: *mut WordCompletion,
                      line: *const c_char,
                      word_start: c_int,
                      word_end: c_int,
                      suffix: *const c_char,
                      type_suffix: *const c_char,
                      cont_suffix: *const c_char) -> c_int {
    unsafe {
        cpl_add_completion(wc, line, word_start, word_end, suffix, type_suffix, cont_suffix)
    }
}
<|endoftext|>