<commit_before>extern crate channel;
extern crate crossbeam;

use std::thread;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::time::Duration;

use channel::{bounded, select, unbounded};
use channel::{RecvError, RecvTimeoutError, SendError, SendTimeoutError, TryRecvError, TrySendError};

fn ms(ms: u64) -> Duration {
    Duration::from_millis(ms)
}

// TODO: clone rx/tx, then drop and check disconnected

#[test]
fn smoke1() {
    let mut iters = 0;
    let (tx1, rx1) = unbounded();
    let (tx2, rx2) = unbounded();

    tx1.send(1).unwrap();
    loop {
        iters += 1;
        if let Ok(v) = rx1.select() {
            assert_eq!(v, 1);
            break;
        }
        if let Ok(_) = rx2.select() {
            panic!();
        }
    }

    tx2.send(2).unwrap();
    loop {
        iters += 1;
        if let Ok(_) = rx1.select() {
            panic!();
        }
        if let Ok(v) = rx2.select() {
            assert_eq!(v, 2);
            break;
        }
    }

    assert!(iters < 50);
}

#[test]
fn smoke2() {
    let mut iters = 0;
    let (_tx1, rx1) = unbounded::<i32>();
    let (_tx2, rx2) = unbounded::<i32>();
    let (_tx3, rx3) = unbounded::<i32>();
    let (_tx4, rx4) = unbounded::<i32>();
    let (tx5, rx5) = unbounded::<i32>();

    tx5.send(5).unwrap();

    loop {
        iters += 1;
        if let Ok(_) = rx1.select() {
            panic!();
        }
        if let Ok(_) = rx2.select() {
            panic!();
        }
        if let Ok(_) = rx3.select() {
            panic!();
        }
        if let Ok(_) = rx4.select() {
            panic!();
        }
        if let Ok(x) = rx5.select() {
            assert_eq!(x, 5);
            break;
        }
    }

    assert!(iters < 50);
}

#[test]
fn disconnected() {
    let mut iters = 0;
    let (tx1, rx1) = unbounded::<i32>();
    let (tx2, rx2) = unbounded::<i32>();

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(50));
            drop(tx1);
        });

        loop {
            iters += 1;
            if let Ok(_) = rx1.select() {
                panic!();
            }
            if let Ok(_) = rx2.select() {
                panic!();
            }
            if select::disconnected() {
                panic!();
            }
            if select::timeout(ms(100)) {
                break;
            }
        }
    });

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(50));
            drop(tx2);
        });

        loop {
            iters += 1;
            if let Ok(_) = rx1.select() {
                panic!();
            }
            if let Ok(_) = rx2.select() {
                panic!();
            }
            if select::disconnected() {
                break;
            }
            if select::timeout(ms(100)) {
                panic!();
            }
        }
    });

    assert!(iters < 50);
}

#[test]
fn blocked() {
    let mut iters = 0;
    let (tx1, rx1) = unbounded::<i32>();
    let (tx2, rx2) = unbounded::<i32>();

    drop(tx1);
    loop {
        iters += 1;
        if let Ok(_) = rx1.select() {
            panic!();
        }
        if let Ok(_) = rx2.select() {
            panic!();
        }
        if select::disconnected() {
            panic!();
        }
        if select::blocked() {
            break;
        }
        if select::timeout(ms(0)) {
            panic!();
        }
    }

    tx2.send(2);
    loop {
        iters += 1;
        if let Ok(_) = rx1.select() {
            panic!();
        }
        if let Ok(x) = rx2.select() {
            assert_eq!(x, 2);
            break;
        }
        if select::disconnected() {
            panic!();
        }
        if select::blocked() {
            panic!();
        }
        if select::timeout(ms(0)) {
            panic!();
        }
    }

    drop(tx2);
    loop {
        iters += 1;
        if let Ok(_) = rx1.select() {
            panic!();
        }
        if let Ok(x) = rx2.select() {
            panic!();
        }
        if select::disconnected() {
            break;
        }
        if select::blocked() {
            panic!();
        }
        if select::timeout(ms(0)) {
            panic!();
        }
    }

    assert!(iters < 50);
}

#[test]
fn timeout() {
    let mut iters = 0;
    let (tx1, rx1) = unbounded::<i32>();
    let (tx2, rx2) = unbounded::<i32>();

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(150));
            tx2.send(2);
        });

        loop {
            iters += 1;
            if let Ok(_) = rx1.select() {
                panic!();
            }
            if let Ok(_) = rx2.select() {
                panic!();
            }
            if select::timeout(ms(100)) {
                break;
            }
        }

        loop {
            iters += 1;
            if let Ok(_) = rx1.select() {
                panic!();
            }
            if let Ok(x) = rx2.select() {
                assert_eq!(x, 2);
                break;
            }
            if select::timeout(ms(100)) {
                panic!();
            }
        }
    });

    assert!(iters < 50);
}

#[test]
fn unblocks() {
    let mut iters = 0;
    let (tx1, rx1) = bounded(0);
    let (tx2, rx2) = bounded(0);

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(50));
            tx2.send(2);
        });

        loop {
            iters += 1;
            if let Ok(_) = rx1.select() {
                panic!();
            }
            if let Ok(x) = rx2.select() {
                assert_eq!(x, 2);
                break;
            }
            if select::timeout(ms(100)) {
                panic!();
            }
        }
    });

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(50));
            assert_eq!(rx1.recv().unwrap(), 1);
        });

        loop {
            iters += 1;
            if let Ok(()) = tx1.select(1) {
                break;
            }
            if let Ok(()) = tx2.select(2) {
                panic!();
            }
            if select::timeout(ms(100)) {
                panic!();
            }
        }
    });

    assert!(iters < 50);
}

#[test]
fn both_ready() {
    let mut iters = 0;
    let (tx1, rx1) = bounded(0);
    let (tx2, rx2) = bounded(0);

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(50));
            tx1.send(1).unwrap();
            assert_eq!(rx2.recv().unwrap(), 2);
        });

        for _ in 0..2 {
            loop {
                iters += 1;
                if let Ok(x) = rx1.select() {
                    assert_eq!(x, 1);
                    break;
                }
                if let Ok(()) = tx2.select(2) {
                    break;
                }
            }
        }
    });
}

#[test]
fn no_starvation() {
    const N: usize = 10;

    let done_rx = &(0..N).map(|_| AtomicBool::new(false)).collect::<Vec<_>>();
    let done_tx = &(0..N).map(|_| AtomicBool::new(false)).collect::<Vec<_>>();

    while !done_rx.iter().all(|x| x.load(SeqCst)) || !done_tx.iter().all(|x| x.load(SeqCst)) {
        crossbeam::scope(|s| {
            let rxs = (0..N).map(|i| {
                let (tx, rx) = unbounded();
                tx.send(i).unwrap();
                rx
            }).collect::<Vec<_>>();

            let txs = (0..N).map(|i| {
                let (tx, rx) = bounded(0);
                s.spawn(move || {
                    if let Ok(x) = rx.recv() {
                        assert_eq!(x, i);
                        done_tx[i].store(true, SeqCst);
                    }
                });
                tx
            }).collect::<Vec<_>>();

            let mut iters = 0;

            'select: loop {
                iters += 1;

                for rx in &rxs {
                    if let Ok(x) = rx.select() {
                        done_rx[x].store(true, SeqCst);
                        break 'select;
                    }
                }

                for (i, tx) in txs.iter().enumerate() {
                    if let Ok(()) = tx.select(i) {
                        break 'select;
                    }
                }
            }

            assert!(iters < 50);
        });
    }
}

#[test]
fn loop_try() {
    for _ in 0..20 {
        let (tx1, rx1) = bounded::<i32>(0);
        let (tx2, rx2) = bounded::<i32>(0);

        crossbeam::scope(|s| {
            s.spawn(|| {
                loop {
                    match tx1.try_send(1) {
                        Ok(()) => break,
                        Err(TrySendError::Disconnected(_)) => break,
                        Err(TrySendError::Full(_)) => continue,
                    }
                }
            });

            s.spawn(|| {
                loop {
                    match rx2.try_recv() {
                        Ok(x) => {
                            assert_eq!(x, 2);
                            break;
                        }
                        Err(TryRecvError::Disconnected) => break,
                        Err(TryRecvError::Empty) => continue,
                    }
                }
            });

            s.spawn(|| {
                let mut iters = 0;
                thread::sleep(ms(50));

                loop {
                    iters += 1;
                    if let Ok(x) = rx1.select() {
                        assert_eq!(x, 1);
                        break;
                    }
                    if let Ok(x) = tx2.select(2) {
                        break;
                    }
                    if select::disconnected() {
                        panic!();
                    }
                    if select::timeout(ms(50)) {
                        panic!();
                    }
                }

                drop(rx1);
                drop(tx2);
                assert!(iters < 50);
            });
        });
    }
}

#[test]
fn stress() {
    let (tx1, rx1) = unbounded();
    let (tx2, rx2) = bounded(5);
    let (tx3, rx3) = bounded(100);

    crossbeam::scope(|s| {
        s.spawn(|| {
            for i in 0..10_000 {
                tx1.send(i);
                rx3.recv().unwrap();

                tx2.send(i);
                rx3.recv().unwrap();
            }
        });

        for i in 0..10_000 {
            let mut iters = 0;

            for _ in 0..2 {
                loop {
                    iters += 1;
                    if let Ok(x) = rx1.select() {
                        assert_eq!(x, i);
                        break;
                    }
                    if let Ok(x) = rx2.select() {
                        assert_eq!(x, i);
                        break;
                    }
                }

                tx3.send(()).unwrap();
            }

            assert!(iters < 50);
        }
    });
}
<commit_msg>More selection tests<commit_after>extern crate channel;
extern crate crossbeam;

use std::thread;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst;
use std::time::Duration;

use channel::{bounded, select, unbounded};
use channel::{RecvError, RecvTimeoutError, SendError, SendTimeoutError, TryRecvError, TrySendError};

fn ms(ms: u64) -> Duration {
    Duration::from_millis(ms)
}

// TODO: clone rx/tx, then drop and check disconnected

#[test]
fn smoke1() {
    let mut iters = 0;
    let (tx1, rx1) = unbounded();
    let (tx2, rx2) = unbounded();

    tx1.send(1).unwrap();
    loop {
        iters += 1;
        if let Ok(v) = rx1.select() {
            assert_eq!(v, 1);
            break;
        }
        if let Ok(_) = rx2.select() {
            panic!();
        }
    }

    tx2.send(2).unwrap();
    loop {
        iters += 1;
        if let Ok(_) = rx1.select() {
            panic!();
        }
        if let Ok(v) = rx2.select() {
            assert_eq!(v, 2);
            break;
        }
    }

    assert!(iters < 50);
}

#[test]
fn smoke2() {
    let mut iters = 0;
    let (_tx1, rx1) = unbounded::<i32>();
    let (_tx2, rx2) = unbounded::<i32>();
    let (_tx3, rx3) = unbounded::<i32>();
    let (_tx4, rx4) = unbounded::<i32>();
    let (tx5, rx5) = unbounded::<i32>();

    tx5.send(5).unwrap();

    loop {
        iters += 1;
        if let Ok(_) = rx1.select() {
            panic!();
        }
        if let Ok(_) = rx2.select() {
            panic!();
        }
        if let Ok(_) = rx3.select() {
            panic!();
        }
        if let Ok(_) = rx4.select() {
            panic!();
        }
        if let Ok(x) = rx5.select() {
            assert_eq!(x, 5);
            break;
        }
    }

    assert!(iters < 50);
}

#[test]
fn disconnected() {
    let mut iters = 0;
    let (tx1, rx1) = unbounded::<i32>();
    let (tx2, rx2) = unbounded::<i32>();

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(50));
            drop(tx1);
        });

        loop {
            iters += 1;
            if let Ok(_) = rx1.select() {
                panic!();
            }
            if let Ok(_) = rx2.select() {
                panic!();
            }
            if select::disconnected() {
                panic!();
            }
            if select::timeout(ms(100)) {
                break;
            }
        }
    });

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(50));
            drop(tx2);
        });

        loop {
            iters += 1;
            if let Ok(_) = rx1.select() {
                panic!();
            }
            if let Ok(_) = rx2.select() {
                panic!();
            }
            if select::disconnected() {
                break;
            }
            if select::timeout(ms(100)) {
                panic!();
            }
        }
    });

    assert!(iters < 50);
}

#[test]
fn blocked() {
    let mut iters = 0;
    let (tx1, rx1) = unbounded::<i32>();
    let (tx2, rx2) = unbounded::<i32>();

    drop(tx1);
    loop {
        iters += 1;
        if let Ok(_) = rx1.select() {
            panic!();
        }
        if let Ok(_) = rx2.select() {
            panic!();
        }
        if select::disconnected() {
            panic!();
        }
        if select::blocked() {
            break;
        }
        if select::timeout(ms(0)) {
            panic!();
        }
    }

    tx2.send(2);
    loop {
        iters += 1;
        if let Ok(_) = rx1.select() {
            panic!();
        }
        if let Ok(x) = rx2.select() {
            assert_eq!(x, 2);
            break;
        }
        if select::disconnected() {
            panic!();
        }
        if select::blocked() {
            panic!();
        }
        if select::timeout(ms(0)) {
            panic!();
        }
    }

    drop(tx2);
    loop {
        iters += 1;
        if let Ok(_) = rx1.select() {
            panic!();
        }
        if let Ok(x) = rx2.select() {
            panic!();
        }
        if select::disconnected() {
            break;
        }
        if select::blocked() {
            panic!();
        }
        if select::timeout(ms(0)) {
            panic!();
        }
    }

    assert!(iters < 50);
}

#[test]
fn timeout() {
    let mut iters = 0;
    let (tx1, rx1) = unbounded::<i32>();
    let (tx2, rx2) = unbounded::<i32>();

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(150));
            tx2.send(2);
        });

        loop {
            iters += 1;
            if let Ok(_) = rx1.select() {
                panic!();
            }
            if let Ok(_) = rx2.select() {
                panic!();
            }
            if select::timeout(ms(100)) {
                break;
            }
        }

        loop {
            iters += 1;
            if let Ok(_) = rx1.select() {
                panic!();
            }
            if let Ok(x) = rx2.select() {
                assert_eq!(x, 2);
                break;
            }
            if select::timeout(ms(100)) {
                panic!();
            }
        }
    });

    assert!(iters < 50);
}

#[test]
fn unblocks() {
    let mut iters = 0;
    let (tx1, rx1) = bounded(0);
    let (tx2, rx2) = bounded(0);

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(50));
            tx2.send(2);
        });

        loop {
            iters += 1;
            if let Ok(_) = rx1.select() {
                panic!();
            }
            if let Ok(x) = rx2.select() {
                assert_eq!(x, 2);
                break;
            }
            if select::timeout(ms(100)) {
                panic!();
            }
        }
    });

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(50));
            assert_eq!(rx1.recv().unwrap(), 1);
        });

        loop {
            iters += 1;
            if let Ok(()) = tx1.select(1) {
                break;
            }
            if let Ok(()) = tx2.select(2) {
                panic!();
            }
            if select::timeout(ms(100)) {
                panic!();
            }
        }
    });

    assert!(iters < 50);
}

#[test]
fn both_ready() {
    let mut iters = 0;
    let (tx1, rx1) = bounded(0);
    let (tx2, rx2) = bounded(0);

    crossbeam::scope(|s| {
        s.spawn(|| {
            thread::sleep(ms(50));
            tx1.send(1).unwrap();
            assert_eq!(rx2.recv().unwrap(), 2);
        });

        for _ in 0..2 {
            loop {
                iters += 1;
                if let Ok(x) = rx1.select() {
                    assert_eq!(x, 1);
                    break;
                }
                if let Ok(()) = tx2.select(2) {
                    break;
                }
            }
        }
    });

    assert!(iters < 50);
}

#[test]
fn no_starvation() {
    const N: usize = 10;

    let done_rx = &(0..N).map(|_| AtomicBool::new(false)).collect::<Vec<_>>();
    let done_tx = &(0..N).map(|_| AtomicBool::new(false)).collect::<Vec<_>>();

    while !done_rx.iter().all(|x| x.load(SeqCst)) || !done_tx.iter().all(|x| x.load(SeqCst)) {
        crossbeam::scope(|s| {
            let rxs = (0..N).map(|i| {
                let (tx, rx) = unbounded();
                tx.send(i).unwrap();
                rx
            }).collect::<Vec<_>>();

            let txs = (0..N).map(|i| {
                let (tx, rx) = bounded(0);
                s.spawn(move || {
                    if let Ok(x) = rx.recv() {
                        assert_eq!(x, i);
                        done_tx[i].store(true, SeqCst);
                    }
                });
                tx
            }).collect::<Vec<_>>();

            let mut iters = 0;

            'select: loop {
                iters += 1;

                for rx in &rxs {
                    if let Ok(x) = rx.select() {
                        done_rx[x].store(true, SeqCst);
                        break 'select;
                    }
                }

                for (i, tx) in txs.iter().enumerate() {
                    if let Ok(()) = tx.select(i) {
                        break 'select;
                    }
                }
            }

            assert!(iters < 50);
        });
    }
}

#[test]
fn loop_try() {
    for _ in 0..20 {
        let (tx1, rx1) = bounded::<i32>(0);
        let (tx2, rx2) = bounded::<i32>(0);

        crossbeam::scope(|s| {
            s.spawn(|| {
                loop {
                    match tx1.try_send(1) {
                        Ok(()) => break,
                        Err(TrySendError::Disconnected(_)) => break,
                        Err(TrySendError::Full(_)) => continue,
                    }
                }
            });

            s.spawn(|| {
                loop {
                    match rx2.try_recv() {
                        Ok(x) => {
                            assert_eq!(x, 2);
                            break;
                        }
                        Err(TryRecvError::Disconnected) => break,
                        Err(TryRecvError::Empty) => continue,
                    }
                }
            });

            s.spawn(|| {
                let mut iters = 0;
                thread::sleep(ms(50));

                loop {
                    iters += 1;
                    if let Ok(x) = rx1.select() {
                        assert_eq!(x, 1);
                        break;
                    }
                    if let Ok(x) = tx2.select(2) {
                        break;
                    }
                    if select::disconnected() {
                        panic!();
                    }
                    if select::timeout(ms(50)) {
                        panic!();
                    }
                }

                drop(rx1);
                drop(tx2);
                assert!(iters < 50);
            });
        });
    }
}

#[test]
fn cloning1() {
    crossbeam::scope(|s| {
        let mut iters = 0;
        let (tx1, rx1) = unbounded::<i32>();
        let (_tx2, rx2) = unbounded::<i32>();
        let (tx3, rx3) = unbounded::<()>();

        s.spawn(move || {
            rx3.recv().unwrap();
            tx1.clone();
            assert_eq!(rx3.try_recv(), Err(TryRecvError::Empty));
            tx1.send(1).unwrap();
            rx3.recv().unwrap();
        });

        tx3.send(()).unwrap();
        loop {
            iters += 1;
            if let Ok(_) = rx1.select() {
                break;
            }
            if let Ok(_) = rx2.select() {
                panic!();
            }
        }

        tx3.send(()).unwrap();
        assert!(iters < 50);
    });
}

#[test]
fn cloning2() {
    crossbeam::scope(|s| {
        let mut iters = 0;
        let (tx1, rx1) = unbounded::<()>();
        let (tx2, rx2) = unbounded::<()>();
        let (tx3, rx3) = unbounded::<()>();

        s.spawn(move || {
            loop {
                iters += 1;
                if let Ok(_) = rx1.select() {
                    panic!();
                }
                if let Ok(_) = rx2.select() {
                    break;
                }
            }
        });

        thread::sleep(ms(50));
        drop(tx1.clone());
        tx2.send(()).unwrap();

        assert!(iters < 50);
    })
}

#[test]
fn preflight1() {
    let (tx, rx) = unbounded();
    tx.send(()).unwrap();

    let mut iters = 0;
    loop {
        iters += 1;
        if let Ok(_) = rx.select() {
            break;
        }
    }
    assert!(iters < 10);
}

#[test]
fn preflight2() {
    let (tx, rx) = unbounded();
    drop(tx.clone());
    tx.send(()).unwrap();
    drop(tx);

    let mut iters = 0;
    loop {
        iters += 1;
        if let Ok(_) = rx.select() {
            break;
        }
    }
    assert_eq!(rx.try_recv(), Err(TryRecvError::Disconnected));
    assert!(iters < 10);
}

#[test]
fn preflight3() {
    let (tx, rx) = unbounded();
    drop(tx.clone());
    tx.send(()).unwrap();
    drop(tx);
    rx.recv().unwrap();

    let mut iters = 0;
    loop {
        iters += 1;
        if let Ok(_) = rx.select() {
            panic!();
        }
        if select::disconnected() {
            break;
        }
    }
    assert!(iters < 10);
}

#[test]
fn stress_recv() {
    let (tx1, rx1) = unbounded();
    let (tx2, rx2) = bounded(5);
    let (tx3, rx3) = bounded(100);

    crossbeam::scope(|s| {
        s.spawn(|| {
            for i in 0..10_000 {
                tx1.send(i);
                rx3.recv().unwrap();

                tx2.send(i);
                rx3.recv().unwrap();
            }
        });

        for i in 0..10_000 {
            let mut iters = 0;

            for _ in 0..2 {
                loop {
                    iters += 1;
                    if let Ok(x) = rx1.select() {
                        assert_eq!(x, i);
                        break;
                    }
                    if let Ok(x) = rx2.select() {
                        assert_eq!(x, i);
                        break;
                    }
                }

                tx3.send(()).unwrap();
            }

            assert!(iters < 50);
        }
    });
}

#[test]
fn stress_send() {
    let (tx1, rx1) = bounded(0);
    let (tx2, rx2) = bounded(0);
    let (tx3, rx3) = bounded(100);

    crossbeam::scope(|s| {
        s.spawn(|| {
            for i in 0..10_000 {
                assert_eq!(rx1.recv().unwrap(), i);
                assert_eq!(rx2.recv().unwrap(), i);
                rx3.recv().unwrap();
            }
        });

        for i in 0..10_000 {
            let mut iters = 0;

            for _ in 0..2 {
                loop {
                    iters += 1;
                    if let Ok(()) = tx1.select(i) {
                        break;
                    }
                    if let Ok(()) = tx2.select(i) {
                        break;
                    }
                }
            }
            tx3.send(()).unwrap();

            assert!(iters < 50);
        }
    });
}

#[test]
fn stress_mixed() {
    let (tx1, rx1) = bounded(0);
    let (tx2, rx2) = bounded(0);
    let (tx3, rx3) = bounded(100);

    crossbeam::scope(|s| {
        s.spawn(|| {
            for i in 0..10_000 {
                tx1.send(i).unwrap();
                assert_eq!(rx2.recv().unwrap(), i);
                rx3.recv().unwrap();
            }
        });

        for i in 0..10_000 {
            let mut iters = 0;

            for _ in 0..2 {
                loop {
                    iters += 1;
                    if let Ok(x) = rx1.select() {
                        assert_eq!(x, i);
                        break;
                    }
                    if let Ok(()) = tx2.select(i) {
                        break;
                    }
                }
            }
            tx3.send(()).unwrap();

            assert!(iters < 50);
        }
    });
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate hyper;

use futures::future;
use hyper::rt::{Future, Stream};
use hyper::service::service_fn;
use hyper::{Body, Method, Request, Response, Server, StatusCode};

/// We need to return different futures depending on the route matched,
/// and we can do that with an enum, such as `futures::Either`, or with
/// trait objects.
///
/// A boxed Future (trait object) is used as it is easier to understand
/// and extend with more types. Advanced users could switch to `Either`.
type BoxFut = Box<Future<Item = Response<Body>, Error = hyper::Error> + Send>;

/// This is our service handler. It receives a Request, routes on its
/// path, and returns a Future of a Response.
fn echo(req: Request<Body>) -> BoxFut {
    let mut response = Response::new(Body::empty());

    match (req.method(), req.uri().path()) {
        // Serve some instructions at /
        (Method::GET, "/") => {
            *response.body_mut() = Body::from("Try POSTing data to /echo");
        }

        // Simply echo the body back to the client.
        (Method::POST, "/echo") => {
            *response.body_mut() = req.into_body();
        }

        // Convert to uppercase before sending back to client.
        (Method::POST, "/echo/uppercase") => {
            let mapping = req.into_body().map(|chunk| {
                chunk
                    .iter()
                    .map(|byte| byte.to_ascii_uppercase())
                    .collect::<Vec<u8>>()
            });

            *response.body_mut() = Body::wrap_stream(mapping);
        }

        // Reverse the entire body before sending back to the client.
        //
        // Since we don't know the end yet, we can't simply stream
        // the chunks as they arrive. So, this returns a different
        // future, waiting on concatenating the full body, so that
        // it can be reversed. Only then can we return a `Response`.
        (Method::POST, "/echo/reversed") => {
            let reversed = req.into_body().concat2().map(move |chunk| {
                let body = chunk.iter().rev().cloned().collect::<Vec<u8>>();
                *response.body_mut() = Body::from(body);
                response
            });

            return Box::new(reversed);
        }

        // The 404 Not Found route...
        _ => {
            *response.status_mut() = StatusCode::NOT_FOUND;
        }
    };

    Box::new(future::ok(response))
}

fn main() {
    let addr = ([127, 0, 0, 1], 3000).into();

    let server = Server::bind(&addr)
        .serve(|| service_fn(echo))
        .map_err(|e| eprintln!("server error: {}", e));

    println!("Listening on http://{}", addr);
    hyper::rt::run(server);
}
<commit_msg>chore(examples): fix echo compilation without NLL<commit_after>extern crate futures;
extern crate hyper;

use futures::future;
use hyper::rt::{Future, Stream};
use hyper::service::service_fn;
use hyper::{Body, Method, Request, Response, Server, StatusCode};

/// We need to return different futures depending on the route matched,
/// and we can do that with an enum, such as `futures::Either`, or with
/// trait objects.
///
/// A boxed Future (trait object) is used as it is easier to understand
/// and extend with more types. Advanced users could switch to `Either`.
type BoxFut = Box<Future<Item = Response<Body>, Error = hyper::Error> + Send>;

/// This is our service handler. It receives a Request, routes on its
/// path, and returns a Future of a Response.
fn echo(req: Request<Body>) -> BoxFut {
    let mut response = Response::new(Body::empty());

    match (req.method(), req.uri().path()) {
        // Serve some instructions at /
        (&Method::GET, "/") => {
            *response.body_mut() = Body::from("Try POSTing data to /echo");
        }

        // Simply echo the body back to the client.
        (&Method::POST, "/echo") => {
            *response.body_mut() = req.into_body();
        }

        // Convert to uppercase before sending back to client.
        (&Method::POST, "/echo/uppercase") => {
            let mapping = req.into_body().map(|chunk| {
                chunk
                    .iter()
                    .map(|byte| byte.to_ascii_uppercase())
                    .collect::<Vec<u8>>()
            });

            *response.body_mut() = Body::wrap_stream(mapping);
        }

        // Reverse the entire body before sending back to the client.
        //
        // Since we don't know the end yet, we can't simply stream
        // the chunks as they arrive. So, this returns a different
        // future, waiting on concatenating the full body, so that
        // it can be reversed. Only then can we return a `Response`.
        (&Method::POST, "/echo/reversed") => {
            let reversed = req.into_body().concat2().map(move |chunk| {
                let body = chunk.iter().rev().cloned().collect::<Vec<u8>>();
                *response.body_mut() = Body::from(body);
                response
            });

            return Box::new(reversed);
        }

        // The 404 Not Found route...
        _ => {
            *response.status_mut() = StatusCode::NOT_FOUND;
        }
    };

    Box::new(future::ok(response))
}

fn main() {
    let addr = ([127, 0, 0, 1], 3000).into();

    let server = Server::bind(&addr)
        .serve(|| service_fn(echo))
        .map_err(|e| eprintln!("server error: {}", e));

    println!("Listening on http://{}", addr);
    hyper::rt::run(server);
}
<|endoftext|>


<commit_before>extern crate image;
extern crate bspline;

use std::ops::{Mul, Add, Index, IndexMut};
use std::iter;

#[derive(Copy, Clone, Debug)]
struct Point {
    x: f32,
    y: f32,
}
impl Point {
    fn new(x: f32, y: f32) -> Point {
        Point { x: x, y: y }
    }
}
impl Mul<f32> for Point {
    type Output = Point;
    fn mul(self, rhs: f32) -> Point {
        Point { x: self.x * rhs, y: self.y * rhs }
    }
}
impl Add for Point {
    type Output = Point;
    fn add(self, rhs: Point) -> Point {
        Point { x: self.x + rhs.x, y: self.y + rhs.y }
    }
}

/// Clamp `x` to be between `min` and `max`
pub fn clamp<T: PartialOrd>(x: T, min: T, max: T) -> T {
    if x < min { min } else if x > max { max } else { x }
}

#[derive(Debug, Copy, Clone)]
pub struct Colorf {
    pub r: f32,
    pub g: f32,
    pub b: f32,
}

impl Colorf {
    /// Create an RGB color
    pub fn new(r: f32, g: f32, b: f32) -> Colorf {
        Colorf { r: r, g: g, b: b }
    }
    pub fn broadcast(x: f32) -> Colorf {
        Colorf { r: x, g: x, b: x }
    }
    /// Clamp the color values between [0, 1]
    pub fn clamp(&self) -> Colorf {
        Colorf { r: clamp(self.r, 0.0, 1.0),
                 g: clamp(self.g, 0.0, 1.0),
                 b: clamp(self.b, 0.0, 1.0) }
    }
    /// Convert the linear RGB color to sRGB
    pub fn to_srgb(&self) -> Colorf {
        let a = 0.055f32;
        let b = 1f32 / 2.4;
        let mut srgb = Colorf::broadcast(0.0);
        for i in 0..3 {
            if self[i] <= 0.0031308 {
                srgb[i] = 12.92 * self[i];
            } else {
                srgb[i] = (1.0 + a) * f32::powf(self[i], b) - a;
            }
        }
        srgb
    }
}
impl Add for Colorf {
    type Output = Colorf;
    /// Add two colors together
    fn add(self, rhs: Colorf) -> Colorf {
        Colorf { r: self.r + rhs.r, g: self.g + rhs.g, b: self.b + rhs.b }
    }
}
impl Mul<f32> for Colorf {
    type Output = Colorf;
    /// Scale the color by the float
    fn mul(self, rhs: f32) -> Colorf {
        Colorf { r: self.r * rhs, g: self.g * rhs, b: self.b * rhs }
    }
}
impl Index<usize> for Colorf {
    type Output = f32;
    /// Access the channels by index
    ///
    /// - 0 = r
    /// - 1 = g
    /// - 2 = b
    fn index(&self, i: usize) -> &f32 {
        match i {
            0 => &self.r,
            1 => &self.g,
            2 => &self.b,
            _ => panic!("Invalid index into color"),
        }
    }
}
impl IndexMut<usize> for Colorf {
    /// Access the channels by index
    ///
    /// - 0 = r
    /// - 1 = g
    /// - 2 = b
    fn index_mut(&mut self, i: usize) -> &mut f32 {
        match i {
            0 => &mut self.r,
            1 => &mut self.g,
            2 => &mut self.b,
            _ => panic!("Invalid index into color"),
        }
    }
}

/// Evaluate the B-spline and plot it to the image buffer passed. The colors and points splines
/// should have the same t range.
fn plot_2d(spline: &bspline::BSpline<Point>, colors: &bspline::BSpline<Colorf>, plot: &mut [u8],
           plot_dim: (usize, usize), scale: (f32, f32), offset: (f32, f32), show_control_pts: bool) {
    let step_size = 0.001;
    let t_range = spline.knot_domain();
    let steps = ((t_range.1 - t_range.0) / step_size) as usize;
    for s in 0..steps {
        let t = step_size * s as f32 + t_range.0;
        let pt = spline.point(t);
        let color = colors.point(t).to_srgb();
        let ix = ((pt.x + offset.0) * scale.0) as isize;
        let iy = ((pt.y + offset.1) * scale.1) as isize;
        for y in iy - 4..iy + 4 {
            for x in ix - 4..ix + 4 {
                if y >= 0 && y < plot_dim.1 as isize && x >= 0 && x < plot_dim.0 as isize {
                    let px = (plot_dim.1 - 1 - y as usize) * plot_dim.0 * 3 + x as usize * 3;
                    for i in 0..3 {
                        plot[px + i] = (color[i] * 255.0) as u8;
                    }
                }
            }
        }
    }
    // Draw the control points
    if show_control_pts {
        for pt in spline.control_points() {
            let ix = ((pt.x + offset.0) * scale.0) as isize;
            let iy = ((pt.y + offset.1) * scale.1) as isize;
            // Plot a black marker for each control point
            for y in iy - 3..iy + 3 {
                for x in ix - 3..ix + 3 {
                    if y >= 0 && y < plot_dim.1 as isize && x >= 0 && x < plot_dim.0 as isize {
                        let px = (plot_dim.1 - 1 - y as usize) * plot_dim.0 * 3 + x as usize * 3;
                        plot[px] = 0;
                        plot[px + 1] = 0;
                        plot[px + 2] = 0;
                    }
                }
            }
        }
    }
}

/// Plot the text 'bspline' to create the logo for the library
fn main() {
    let points = vec![// Draw the b
                      Point::new(-4.0, 4.0), Point::new(-4.0, -1.0), Point::new(-4.0, -1.0),
                      Point::new(-2.0, 0.0), Point::new(-4.0, 1.35), Point::new(-4.0, 1.35),
                      // Draw the s
                      Point::new(-1.0, 1.5), Point::new(-1.0, 1.5), Point::new(-2.8, 1.0),
                      Point::new(-0.5, 0.0), Point::new(-2.5, -0.5), Point::new(-2.5, -0.5),
                      // Draw the p
                      Point::new(0.0, -1.0), Point::new(0.0, 1.8), Point::new(0.0, 1.8),
                      Point::new(0.0, 1.8), Point::new(-0.2, -1.8), Point::new(-0.2, -1.8),
                      Point::new(-0.2, -1.8), Point::new(0.25, 2.5), Point::new(1.5, 1.2),
                      Point::new(0.0, -0.5), Point::new(0.0, -0.5), Point::new(1.0, -0.3),
                      Point::new(1.0, -0.3), Point::new(2.5, 1.5),
                      // Draw the l
                      Point::new(2.0, 3.0), Point::new(2.0, 3.0), Point::new(1.5, 1.5),
                      Point::new(2.5, -0.5), Point::new(2.5, -0.5),
                      // Draw the i
                      Point::new(2.8, 1.3), Point::new(2.8, 1.3), Point::new(2.8, 1.3),
                      // Draw the n
                      Point::new(3.1, -0.5), Point::new(3.1, -0.5), Point::new(3.4, 1.2),
                      Point::new(3.4, 1.2), Point::new(3.4, 1.2), Point::new(3.4, -0.5),
                      Point::new(3.4, -0.5), Point::new(3.4, -0.5), Point::new(4.0, 2.3),
                      Point::new(4.2, -0.5), Point::new(4.2, -0.5),
                      // Draw the e
                      Point::new(5.5, 0.8), Point::new(5.5, 0.8), Point::new(4.5, 1.3), Point::new(4.5, -0.3),
                      Point::new(6.5, -0.3)];
    let knots = vec![0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 4.0, 5.0, 6.0, 7.0, 7.0,
                     8.0, 9.0, 9.0, 9.0, 10.0, 10.0, 10.0, 11.0, 12.0, 13.0, 13.0,
                     14.0, 14.0, 15.0, 16.0, 16.0, 17.0, 18.0, 18.0, 19.0, 19.0, 19.0,
                     20.0, 20.0, 21.0, 21.0, 21.0, 22.0, 22.0, 22.0, 23.0, 24.0, 24.0,
                     25.0, 25.0, 26.0, 27.0, 28.0, 28.0, 28.0, 28.0];

    let colors = vec![Colorf::new(1.0, 0.0, 0.0), Colorf::new(0.0, 0.0, 1.0), Colorf::new(0.0, 1.0, 0.0)];
    let color_knots = vec![0.0, 0.0, 0.0, 28.0, 28.0, 28.0];

    let plot_dim = (720, 540);
    let scale = (plot_dim.0 as f32 / 14.0, plot_dim.1 as f32 / 10.0);
    let offset = (6.0, 4.5);

    let mut plot: Vec<_> = iter::repeat(255u8).take(plot_dim.0 * plot_dim.1 * 3).collect();

    let spline = bspline::BSpline::new(3, points, knots);
    let color_spline = bspline::BSpline::new(2, colors, color_knots);

    plot_2d(&spline, &color_spline, &mut plot[..], plot_dim, scale, offset, false);
    match image::save_buffer("logo.png", &plot[..], plot_dim.0 as u32, plot_dim.1 as u32, image::RGB(8)) {
        Ok(_) => println!("B-spline logo saved to logo.png"),
        Err(e) => println!("Error saving logo.png,  {}", e),
    }
}

<commit_msg>Clean up trailing space<commit_after>extern crate image;
extern crate bspline;

use std::ops::{Mul, Add, Index, IndexMut};
use std::iter;

#[derive(Copy, Clone, Debug)]
struct Point {
    x: f32,
    y: f32,
}
impl Point {
    fn new(x: f32, y: f32) -> Point {
        Point { x: x, y: y }
    }
}
impl Mul<f32> for Point {
    type Output = Point;
    fn mul(self, rhs: f32) -> Point {
        Point { x: self.x * rhs, y: self.y * rhs }
    }
}
impl Add for Point {
    type Output = Point;
    fn add(self, rhs: Point) -> Point {
        Point { x: self.x + rhs.x, y: self.y + rhs.y }
    }
}

/// Clamp `x` to be between `min` and `max`
pub fn clamp<T: PartialOrd>(x: T, min: T, max: T) -> T {
    if x < min { min } else if x > max { max } else { x }
}

#[derive(Debug, Copy, Clone)]
pub struct Colorf {
    pub r: f32,
    pub g: f32,
    pub b: f32,
}

impl Colorf {
    /// Create an RGB color
    pub fn new(r: f32, g: f32, b: f32) -> Colorf {
        Colorf { r: r, g: g, b: b }
    }
    pub fn broadcast(x: f32) -> Colorf {
        Colorf { r: x, g: x, b: x }
    }
    /// Clamp the color values between [0, 1]
    pub fn clamp(&self) -> Colorf {
        Colorf { r: clamp(self.r, 0.0, 1.0),
                 g: clamp(self.g, 0.0, 1.0),
                 b: clamp(self.b, 0.0, 1.0) }
    }
    /// Convert the linear RGB color to sRGB
    pub fn to_srgb(&self) -> Colorf {
        let a = 0.055f32;
        let b = 1f32 / 2.4;
        let mut srgb = Colorf::broadcast(0.0);
        for i in 0..3 {
            if self[i] <= 0.0031308 {
                srgb[i] = 12.92 * self[i];
            } else {
                srgb[i] = (1.0 + a) * f32::powf(self[i], b) - a;
            }
        }
        srgb
    }
}
impl Add for Colorf {
    type Output = Colorf;
    /// Add two colors together
    fn add(self, rhs: Colorf) -> Colorf {
        Colorf { r: self.r + rhs.r, g: self.g + rhs.g, b: self.b + rhs.b }
    }
}
impl Mul<f32> for Colorf {
    type Output = Colorf;
    /// Scale the color by the float
    fn mul(self, rhs: f32) -> Colorf {
        Colorf { r: self.r * rhs, g: self.g * rhs, b: self.b * rhs }
    }
}
impl Index<usize> for Colorf {
    type Output = f32;
    /// Access the channels by index
    /// - 0 = r
    /// - 1 = g
    /// - 2 = b
    fn index(&self, i: usize) -> &f32 {
        match i {
            0 => &self.r,
            1 => &self.g,
            2 => &self.b,
            _ => panic!("Invalid index into color"),
        }
    }
}
impl IndexMut<usize> for Colorf {
    /// Access the channels by index
    /// - 0 = r
    /// - 1 = g
    /// - 2 = b
    fn index_mut(&mut self, i: usize) -> &mut f32 {
        match i {
            0 => &mut self.r,
            1 => &mut self.g,
            2 => &mut self.b,
            _ => panic!("Invalid index into color"),
        }
    }
}

/// Evaluate the B-spline and plot it to the image buffer passed. The colors and points splines
/// should have the same t range.
fn plot_2d(spline: &bspline::BSpline<Point>, colors: &bspline::BSpline<Colorf>, plot: &mut [u8],
           plot_dim: (usize, usize), scale: (f32, f32), offset: (f32, f32), show_control_pts: bool) {
    let step_size = 0.001;
    let t_range = spline.knot_domain();
    let steps = ((t_range.1 - t_range.0) / step_size) as usize;
    for s in 0..steps {
        let t = step_size * s as f32 + t_range.0;
        let pt = spline.point(t);
        let color = colors.point(t).to_srgb();
        let ix = ((pt.x + offset.0) * scale.0) as isize;
        let iy = ((pt.y + offset.1) * scale.1) as isize;
        for y in iy - 4..iy + 4 {
            for x in ix - 4..ix + 4 {
                if y >= 0 && y < plot_dim.1 as isize && x >= 0 && x < plot_dim.0 as isize {
                    let px = (plot_dim.1 - 1 - y as usize) * plot_dim.0 * 3 + x as usize * 3;
                    for i in 0..3 {
                        plot[px + i] = (color[i] * 255.0) as u8;
                    }
                }
            }
        }
    }
    // Draw the control points
    if show_control_pts {
        for pt in spline.control_points() {
            let ix = ((pt.x + offset.0) * scale.0) as isize;
            let iy = ((pt.y + offset.1) * scale.1) as isize;
            // Plot a black marker for each control point
            for y in iy - 3..iy + 3 {
                for x in ix - 3..ix + 3 {
                    if y >= 0 && y < plot_dim.1 as isize && x >= 0 && x < plot_dim.0 as isize {
                        let px = (plot_dim.1 - 1 - y as usize) * plot_dim.0 * 3 + x as usize * 3;
                        plot[px] = 0;
                        plot[px + 1] = 0;
                        plot[px + 2] = 0;
                    }
                }
            }
        }
    }
}

/// Plot the text 'bspline' to create the logo for the library
fn main() {
    let points = vec![// Draw the b
                      Point::new(-4.0, 4.0), Point::new(-4.0, -1.0), Point::new(-4.0, -1.0),
                      Point::new(-2.0, 0.0), Point::new(-4.0, 1.35), Point::new(-4.0, 1.35),
                      // Draw the s
                      Point::new(-1.0, 1.5), Point::new(-1.0, 1.5), Point::new(-2.8, 1.0),
                      Point::new(-0.5, 0.0), Point::new(-2.5, -0.5), Point::new(-2.5, -0.5),
                      // Draw the p
                      Point::new(0.0, -1.0), Point::new(0.0, 1.8), Point::new(0.0, 1.8),
                      Point::new(0.0, 1.8), Point::new(-0.2, -1.8), Point::new(-0.2, -1.8),
                      Point::new(-0.2, -1.8), Point::new(0.25, 2.5), Point::new(1.5, 1.2),
                      Point::new(0.0, -0.5), Point::new(0.0, -0.5), Point::new(1.0, -0.3),
                      Point::new(1.0, -0.3), Point::new(2.5, 1.5),
                      // Draw the l
                      Point::new(2.0, 3.0), Point::new(2.0, 3.0), Point::new(1.5, 1.5),
                      Point::new(2.5, -0.5), Point::new(2.5, -0.5),
                      // Draw the i
                      Point::new(2.8, 1.3), Point::new(2.8, 1.3), Point::new(2.8, 1.3),
                      // Draw the n
                      Point::new(3.1, -0.5), Point::new(3.1, -0.5), Point::new(3.4, 1.2),
                      Point::new(3.4, 1.2), Point::new(3.4, 1.2), Point::new(3.4, -0.5),
                      Point::new(3.4, -0.5), Point::new(3.4, -0.5), Point::new(4.0, 2.3),
                      Point::new(4.2, -0.5), Point::new(4.2, -0.5),
                      // Draw the e
                      Point::new(5.5, 0.8), Point::new(5.5, 0.8), Point::new(4.5, 1.3), Point::new(4.5, -0.3),
                      Point::new(6.5, -0.3)];
    let knots = vec![0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 4.0, 5.0, 6.0, 7.0, 7.0,
                     8.0, 9.0, 9.0, 9.0, 10.0, 10.0, 10.0, 11.0, 12.0, 13.0, 13.0,
                     14.0, 14.0, 15.0, 16.0, 16.0, 17.0, 18.0, 18.0, 19.0, 19.0, 19.0,
                     20.0, 20.0, 21.0, 21.0, 21.0, 22.0, 22.0, 22.0, 23.0, 24.0, 24.0,
                     25.0, 25.0, 26.0, 27.0, 28.0, 28.0, 28.0, 28.0];

    let colors = vec![Colorf::new(1.0, 0.0, 0.0), Colorf::new(0.0, 0.0, 1.0), Colorf::new(0.0, 1.0, 0.0)];
    let color_knots = vec![0.0, 0.0, 0.0, 28.0, 28.0, 28.0];

    let plot_dim = (720, 540);
    let scale = (plot_dim.0 as f32 / 14.0, plot_dim.1 as f32 / 10.0);
    let offset = (6.0, 4.5);

    let mut plot: Vec<_> = iter::repeat(255u8).take(plot_dim.0 * plot_dim.1 * 3).collect();

    let spline = bspline::BSpline::new(3, points, knots);
    let color_spline = bspline::BSpline::new(2, colors, color_knots);

    plot_2d(&spline, &color_spline, &mut plot[..], plot_dim, scale, offset, false);
    match image::save_buffer("logo.png", &plot[..], plot_dim.0 as u32, plot_dim.1 as u32, image::RGB(8)) {
        Ok(_) => println!("B-spline logo saved to logo.png"),
        Err(e) => println!("Error saving logo.png,  {}", e),
    }
}

<|endoftext|>


<commit_before>#[macro_use]
extern crate enum_map;

use enum_map::{Enum, EnumMap, IntoIter};

use std::cell::RefCell;
use std::collections::HashSet;
use std::convert::Infallible;
use std::marker::PhantomData;

trait From<T>: Sized {
    fn from(_: T) -> Self {
        unreachable!();
    }
}

impl<T, U> From<T> for U {}

#[derive(Copy, Clone, Debug, Enum, PartialEq)]
enum Example {
    A,
    B,
    C,
}

#[test]
fn test_bool() {
    let mut map = enum_map! { false => 24, true => 42 };
    assert_eq!(map[false], 24);
    assert_eq!(map[true], 42);
    map[false] += 1;
    assert_eq!(map[false], 25);
    for (key, item) in &mut map {
        if !key {
            *item += 1;
        }
    }
    assert_eq!(map[false], 26);
    assert_eq!(map[true], 42);
}

#[test]
fn test_clone() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(map.clone(), map);
}

#[test]
fn test_debug() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(format!("{:?}", map), "{false: 3, true: 5}");
}

#[test]
fn test_hash() {
    let map = enum_map! { false => 3, true => 5 };
    let mut set = HashSet::new();
    set.insert(map);
    assert!(set.contains(&map));
}

#[test]
fn test_clear() {
    let mut map = enum_map! { false => 1, true => 2 };
    map.clear();
    assert_eq!(map[true], 0);
    assert_eq!(map[false], 0);
}

#[test]
fn discriminants() {
    #[derive(Debug, Enum, PartialEq)]
    enum Discriminants {
        A = 2000,
        B = 3000,
        C = 1000,
    }
    let mut map = EnumMap::new();
    map[Discriminants::A] = 3;
    map[Discriminants::B] = 2;
    map[Discriminants::C] = 1;
    let mut pairs = map.iter();
    assert_eq!(pairs.next(), Some((Discriminants::A, &3)));
    assert_eq!(pairs.next(), Some((Discriminants::B, &2)));
    assert_eq!(pairs.next(), Some((Discriminants::C, &1)));
    assert_eq!(pairs.next(), None);
}

#[test]
fn extend() {
    let mut map = enum_map! { _ => 0 };
    map.extend(vec![(Example::A, 3)]);
    map.extend(vec![(&Example::B, &4)]);
    assert_eq!(
        map,
        enum_map! { Example::A => 3, Example::B => 4, Example::C => 0 }
    );
}

#[test]
fn huge_enum() {
    #[derive(Enum)]
    enum Example {
        A,
        B,
        C,
        D,
        E,
        F,
        G,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R,
        S,
        T,
        U,
        V,
        W,
        X,
        Y,
        Z,
        Aa,
        Bb,
        Cc,
        Dd,
        Ee,
        Ff,
        Gg,
        Hh,
        Ii,
        Jj,
        Kk,
        Ll,
        Mm,
        Nn,
        Oo,
        Pp,
        Qq,
        Rr,
        Ss,
        Tt,
        Uu,
        Vv,
        Ww,
        Xx,
        Yy,
        Zz,
    }

    let map = enum_map! { _ => 2 };
    assert_eq!(map[Example::Xx], 2);
}

#[test]
fn iterator_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter()
            .len(),
        3
    );
}

#[test]
fn iter_mut_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter_mut()
            .len(),
        3
    );
}

#[test]
fn into_iter_len() {
    assert_eq!(enum_map! { Example::A | _ => 0 }.into_iter().len(), 3);
}

#[test]
fn iterator_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &3))
    );
}

#[test]
fn iter_mut_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter_mut()
            .next_back(),
        Some((Example::C, &mut 3))
    );
}

#[test]
fn into_iter() {
    let mut iter = enum_map! { true => 5, false => 7 }.into_iter();
    assert_eq!(iter.next(), Some((false, 7)));
    assert_eq!(iter.next(), Some((true, 5)));
    assert_eq!(iter.next(), None);
    assert_eq!(iter.next(), None);
}

#[test]
fn into_iter_u8() {
    assert_eq!(
        <EnumMap<_, _> as core::convert::From<_>>::from(|i: u8| i)
            .into_iter()
            .collect::<Vec<_>>(),
        (0..256).map(|x| (x as u8, x as u8)).collect::<Vec<_>>()
    );
}

struct DropReporter<'a> {
    into: &'a RefCell<Vec<usize>>,
    value: usize,
}

impl<'a> Drop for DropReporter<'a> {
    fn drop(&mut self) {
        self.into.borrow_mut().push(self.value);
    }
}

#[test]
fn into_iter_drop() {
    let dropped = RefCell::new(Vec::new());
    let mut a: IntoIter<Example, _> = enum_map! {
        k => DropReporter {
            into: &dropped,
            value: k as usize,
        },
    }
    .into_iter();
    assert_eq!(a.next().unwrap().0, Example::A);
    assert_eq!(*dropped.borrow(), &[0]);
    drop(a);
    assert_eq!(*dropped.borrow(), &[0, 1, 2]);
}

#[test]
fn values_rev_collect() {
    assert_eq!(
        vec![3, 2, 1],
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .values()
            .rev()
            .cloned()
            .collect::<Vec<_>>()
    );
}

#[test]
fn values_len() {
    assert_eq!(enum_map! { false => 0, true => 1 }.values().len(), 2);
}

#[test]
fn values_mut_next_back() {
    let mut map = enum_map! { false => 0, true => 1 };
    assert_eq!(map.values_mut().next_back(), Some(&mut 1));
}
#[test]
fn test_u8() {
    let mut map = enum_map! { b'a' => 4, _ => 0 };
    map[b'c'] = 3;
    assert_eq!(map[b'a'], 4);
    assert_eq!(map[b'b'], 0);
    assert_eq!(map[b'c'], 3);
    assert_eq!(map.iter().next(), Some((0, &0)));
}

#[derive(Enum)]
enum Void {}

#[test]
fn empty_map() {
    let void: EnumMap<Void, Void> = enum_map! {};
    assert!(void.is_empty());
}

#[test]
#[should_panic]
fn empty_value() {
    let _void: EnumMap<bool, Void> = enum_map! { _ => unreachable!() };
}

#[test]
fn empty_infallible_map() {
    let void: EnumMap<Infallible, Infallible> = enum_map! {};
    assert!(void.is_empty());
}

#[derive(Clone, Copy)]
enum X {
    A(PhantomData<*const ()>),
}

impl<V> Enum<V> for X {
    type Array = [V; 1];
    const POSSIBLE_VALUES: usize = 1;

    fn slice(array: &[V; 1]) -> &[V] {
        array
    }

    fn slice_mut(array: &mut [V; 1]) -> &mut [V] {
        array
    }

    fn from_usize(arg: usize) -> X {
        assert_eq!(arg, 0);
        X::A(PhantomData)
    }

    fn to_usize(self) -> usize {
        0
    }

    fn from_function<F: FnMut(Self) -> V>(mut f: F) -> [V; 1] {
        [f(X::A(PhantomData))]
    }
}

fn assert_sync_send<T: Sync + Send>(_: T) {}

#[test]
fn assert_enum_map_does_not_copy_sync_send_dependency_of_keys() {
    let mut map = enum_map! { X::A(PhantomData) => true };
    assert_sync_send(map);
    assert_sync_send(&map);
    assert_sync_send(&mut map);
    assert_sync_send(map.iter());
    assert_sync_send(map.iter_mut());
    assert_sync_send(map.into_iter());
    assert_eq!(map[X::A(PhantomData)], true);
}

#[test]
fn test_sum() {
    assert_eq!(
        enum_map! { i => u8::into(i) }
            .iter()
            .map(|(_, v)| v)
            .sum::<u32>(),
        32_640
    );
}

#[test]
fn test_sum_mut() {
    assert_eq!(
        enum_map! { i => u8::into(i) }
            .iter_mut()
            .map(|(_, &mut v)| -> u32 { v })
            .sum::<u32>(),
        32_640
    );
}

#[test]
fn test_iter_clone() {
    // Mutex doesn't implement Clone, but iterators should still be Clone.
    use std::sync::Mutex;
    let map = enum_map! {
        Example::A => Mutex::new(3),
        Example::B => Mutex::new(4),
        Example::C => Mutex::new(1),
    };
    let iter = map.iter();
    assert_eq!(
        iter.clone().map(|(_, v)| *v.lock().unwrap()).sum::<u32>(),
        8
    );
    assert_eq!(iter.map(|(_, v)| *v.lock().unwrap()).sum::<u32>(), 8);
    let values = map.values();
    assert_eq!(values.clone().map(|v| *v.lock().unwrap()).sum::<u32>(), 8);
    assert_eq!(values.map(|v| *v.lock().unwrap()).sum::<u32>(), 8);
}
<commit_msg>Avoid using mutexes in test_iter_clone<commit_after>#[macro_use]
extern crate enum_map;

use enum_map::{Enum, EnumMap, IntoIter};

use std::cell::RefCell;
use std::collections::HashSet;
use std::convert::Infallible;
use std::marker::PhantomData;

trait From<T>: Sized {
    fn from(_: T) -> Self {
        unreachable!();
    }
}

impl<T, U> From<T> for U {}

#[derive(Copy, Clone, Debug, Enum, PartialEq)]
enum Example {
    A,
    B,
    C,
}

#[test]
fn test_bool() {
    let mut map = enum_map! { false => 24, true => 42 };
    assert_eq!(map[false], 24);
    assert_eq!(map[true], 42);
    map[false] += 1;
    assert_eq!(map[false], 25);
    for (key, item) in &mut map {
        if !key {
            *item += 1;
        }
    }
    assert_eq!(map[false], 26);
    assert_eq!(map[true], 42);
}

#[test]
fn test_clone() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(map.clone(), map);
}

#[test]
fn test_debug() {
    let map = enum_map! { false => 3, true => 5 };
    assert_eq!(format!("{:?}", map), "{false: 3, true: 5}");
}

#[test]
fn test_hash() {
    let map = enum_map! { false => 3, true => 5 };
    let mut set = HashSet::new();
    set.insert(map);
    assert!(set.contains(&map));
}

#[test]
fn test_clear() {
    let mut map = enum_map! { false => 1, true => 2 };
    map.clear();
    assert_eq!(map[true], 0);
    assert_eq!(map[false], 0);
}

#[test]
fn discriminants() {
    #[derive(Debug, Enum, PartialEq)]
    enum Discriminants {
        A = 2000,
        B = 3000,
        C = 1000,
    }
    let mut map = EnumMap::new();
    map[Discriminants::A] = 3;
    map[Discriminants::B] = 2;
    map[Discriminants::C] = 1;
    let mut pairs = map.iter();
    assert_eq!(pairs.next(), Some((Discriminants::A, &3)));
    assert_eq!(pairs.next(), Some((Discriminants::B, &2)));
    assert_eq!(pairs.next(), Some((Discriminants::C, &1)));
    assert_eq!(pairs.next(), None);
}

#[test]
fn extend() {
    let mut map = enum_map! { _ => 0 };
    map.extend(vec![(Example::A, 3)]);
    map.extend(vec![(&Example::B, &4)]);
    assert_eq!(
        map,
        enum_map! { Example::A => 3, Example::B => 4, Example::C => 0 }
    );
}

#[test]
fn huge_enum() {
    #[derive(Enum)]
    enum Example {
        A,
        B,
        C,
        D,
        E,
        F,
        G,
        H,
        I,
        J,
        K,
        L,
        M,
        N,
        O,
        P,
        Q,
        R,
        S,
        T,
        U,
        V,
        W,
        X,
        Y,
        Z,
        Aa,
        Bb,
        Cc,
        Dd,
        Ee,
        Ff,
        Gg,
        Hh,
        Ii,
        Jj,
        Kk,
        Ll,
        Mm,
        Nn,
        Oo,
        Pp,
        Qq,
        Rr,
        Ss,
        Tt,
        Uu,
        Vv,
        Ww,
        Xx,
        Yy,
        Zz,
    }

    let map = enum_map! { _ => 2 };
    assert_eq!(map[Example::Xx], 2);
}

#[test]
fn iterator_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter()
            .len(),
        3
    );
}

#[test]
fn iter_mut_len() {
    assert_eq!(
        enum_map! { Example::A | Example::B | Example::C => 0 }
            .iter_mut()
            .len(),
        3
    );
}

#[test]
fn into_iter_len() {
    assert_eq!(enum_map! { Example::A | _ => 0 }.into_iter().len(), 3);
}

#[test]
fn iterator_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter()
            .next_back(),
        Some((Example::C, &3))
    );
}

#[test]
fn iter_mut_next_back() {
    assert_eq!(
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .iter_mut()
            .next_back(),
        Some((Example::C, &mut 3))
    );
}

#[test]
fn into_iter() {
    let mut iter = enum_map! { true => 5, false => 7 }.into_iter();
    assert_eq!(iter.next(), Some((false, 7)));
    assert_eq!(iter.next(), Some((true, 5)));
    assert_eq!(iter.next(), None);
    assert_eq!(iter.next(), None);
}

#[test]
fn into_iter_u8() {
    assert_eq!(
        <EnumMap<_, _> as core::convert::From<_>>::from(|i: u8| i)
            .into_iter()
            .collect::<Vec<_>>(),
        (0..256).map(|x| (x as u8, x as u8)).collect::<Vec<_>>()
    );
}

struct DropReporter<'a> {
    into: &'a RefCell<Vec<usize>>,
    value: usize,
}

impl<'a> Drop for DropReporter<'a> {
    fn drop(&mut self) {
        self.into.borrow_mut().push(self.value);
    }
}

#[test]
fn into_iter_drop() {
    let dropped = RefCell::new(Vec::new());
    let mut a: IntoIter<Example, _> = enum_map! {
        k => DropReporter {
            into: &dropped,
            value: k as usize,
        },
    }
    .into_iter();
    assert_eq!(a.next().unwrap().0, Example::A);
    assert_eq!(*dropped.borrow(), &[0]);
    drop(a);
    assert_eq!(*dropped.borrow(), &[0, 1, 2]);
}

#[test]
fn values_rev_collect() {
    assert_eq!(
        vec![3, 2, 1],
        enum_map! { Example::A => 1, Example::B => 2, Example::C => 3 }
            .values()
            .rev()
            .cloned()
            .collect::<Vec<_>>()
    );
}

#[test]
fn values_len() {
    assert_eq!(enum_map! { false => 0, true => 1 }.values().len(), 2);
}

#[test]
fn values_mut_next_back() {
    let mut map = enum_map! { false => 0, true => 1 };
    assert_eq!(map.values_mut().next_back(), Some(&mut 1));
}
#[test]
fn test_u8() {
    let mut map = enum_map! { b'a' => 4, _ => 0 };
    map[b'c'] = 3;
    assert_eq!(map[b'a'], 4);
    assert_eq!(map[b'b'], 0);
    assert_eq!(map[b'c'], 3);
    assert_eq!(map.iter().next(), Some((0, &0)));
}

#[derive(Enum)]
enum Void {}

#[test]
fn empty_map() {
    let void: EnumMap<Void, Void> = enum_map! {};
    assert!(void.is_empty());
}

#[test]
#[should_panic]
fn empty_value() {
    let _void: EnumMap<bool, Void> = enum_map! { _ => unreachable!() };
}

#[test]
fn empty_infallible_map() {
    let void: EnumMap<Infallible, Infallible> = enum_map! {};
    assert!(void.is_empty());
}

#[derive(Clone, Copy)]
enum X {
    A(PhantomData<*const ()>),
}

impl<V> Enum<V> for X {
    type Array = [V; 1];
    const POSSIBLE_VALUES: usize = 1;

    fn slice(array: &[V; 1]) -> &[V] {
        array
    }

    fn slice_mut(array: &mut [V; 1]) -> &mut [V] {
        array
    }

    fn from_usize(arg: usize) -> X {
        assert_eq!(arg, 0);
        X::A(PhantomData)
    }

    fn to_usize(self) -> usize {
        0
    }

    fn from_function<F: FnMut(Self) -> V>(mut f: F) -> [V; 1] {
        [f(X::A(PhantomData))]
    }
}

fn assert_sync_send<T: Sync + Send>(_: T) {}

#[test]
fn assert_enum_map_does_not_copy_sync_send_dependency_of_keys() {
    let mut map = enum_map! { X::A(PhantomData) => true };
    assert_sync_send(map);
    assert_sync_send(&map);
    assert_sync_send(&mut map);
    assert_sync_send(map.iter());
    assert_sync_send(map.iter_mut());
    assert_sync_send(map.into_iter());
    assert_eq!(map[X::A(PhantomData)], true);
}

#[test]
fn test_sum() {
    assert_eq!(
        enum_map! { i => u8::into(i) }
            .iter()
            .map(|(_, v)| v)
            .sum::<u32>(),
        32_640
    );
}

#[test]
fn test_sum_mut() {
    assert_eq!(
        enum_map! { i => u8::into(i) }
            .iter_mut()
            .map(|(_, &mut v)| -> u32 { v })
            .sum::<u32>(),
        32_640
    );
}

#[test]
fn test_iter_clone() {
    struct S(u8);
    let map = enum_map! {
        Example::A => S(3),
        Example::B => S(4),
        Example::C => S(1),
    };
    let iter = map.iter();
    assert_eq!(iter.clone().map(|(_, S(v))| v).sum::<u8>(), 8);
    assert_eq!(iter.map(|(_, S(v))| v).sum::<u8>(), 8);
    let values = map.values();
    assert_eq!(values.clone().map(|S(v)| v).sum::<u8>(), 8);
    assert_eq!(values.map(|S(v)| v).sum::<u8>(), 8);
}
<|endoftext|>


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

use eutil::fptr_is_null;
use libc::{size_t, c_int, c_ushort,c_void};
use libc::types::os::arch::c95::wchar_t;
use mem::{new0,newarray0,delete,deletearray};
use std::mem;
use std::ptr;
use std::slice;
use std::string;
use std::str;
use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t};
use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t};

//cef_string

#[no_mangle]
extern "C" fn string_wide_dtor(str: *mut wchar_t) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf8_dtor(str: *mut u8) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf16_dtor(str: *mut c_ushort) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_free(cs: *mut cef_string_userfree_wide_t) {
   cef_string_wide_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_free(cs: *mut cef_string_userfree_utf8_t) {
   cef_string_utf8_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_free(cs: *mut cef_string_userfree_utf16_t) {
   cef_string_utf16_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_clear(cs: *mut cef_string_utf8_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut u8;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_alloc() -> *mut cef_string_utf8_t {
    #![inline(never)]
    new0::<cef_string_utf8_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: *mut cef_string_utf8_t, copy: c_int) -> c_int {
    cef_string_utf8_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<u8>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf8_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_cmp(a: *const cef_string_utf8_t, b: *const cef_string_utf8_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(mem::transmute((*a).str), (*a).length as uint, |astr:&[u8]| {
            slice::raw::buf_as_slice(mem::transmute((*b).str), (*b).length as uint, |bstr:&[u8]| {
                  match astr.cmp(&bstr) {
                       Less => -1,
                       Equal => 0,
                       Greater => 1
                  }
            })
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(src, src_len as uint, |result| {
            match str::from_utf8(result) {
                 Some(enc) => {
                      let conv = enc.utf16_units().collect::<Vec<u16>>();
                      cef_string_utf16_set(conv.as_ptr(), conv.len() as size_t, output, 1);
                      1
                 },
                 None => 0
            }
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_to_utf8(src: *const u16, src_len: size_t, output: *mut cef_string_utf8_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(src, src_len as uint, |ustr| {
            match string::String::from_utf16(ustr) {
                Some(str) => {
                    cef_string_utf8_set(str.as_bytes().as_ptr(), str.len() as size_t, output, 1);
                    1 as c_int
                },
                None =>  0 as c_int
            }
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_clear(cs: *mut cef_string_utf16_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut c_ushort;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_alloc() -> *mut cef_string_utf16_t {
    #![inline(never)]
    new0::<cef_string_utf16_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, output: *mut cef_string_utf16_t, copy: c_int) -> c_int {
    cef_string_utf16_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<c_ushort>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf16_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_cmp(a: *const cef_string_utf16_t, b: *const cef_string_utf16_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(mem::transmute((*a).str), (*a).length as uint, |astr:&[u16]| {
            slice::raw::buf_as_slice(mem::transmute((*b).str), (*b).length as uint, |bstr:&[u16]| {
                  match astr.cmp(&bstr) {
                       Less => -1,
                       Equal => 0,
                       Greater => 1
                  }
            })
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_wide_clear(cs: *mut cef_string_wide_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut wchar_t;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_alloc() -> *mut cef_string_wide_t {
    #![inline(never)]
    new0::<cef_string_wide_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, output: *mut cef_string_wide_t, copy: c_int) -> c_int {
    cef_string_wide_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<wchar_t>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_wide_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}
<commit_msg>embedding: replace transmutes with manual casts in cef_string_utf8_cmp()<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use eutil::fptr_is_null;
use libc::{size_t, c_int, c_ushort,c_void};
use libc::types::os::arch::c95::wchar_t;
use mem::{new0,newarray0,delete,deletearray};
use std::mem;
use std::ptr;
use std::slice;
use std::string;
use std::str;
use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t};
use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t};

//cef_string

#[no_mangle]
extern "C" fn string_wide_dtor(str: *mut wchar_t) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf8_dtor(str: *mut u8) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf16_dtor(str: *mut c_ushort) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_free(cs: *mut cef_string_userfree_wide_t) {
   cef_string_wide_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_free(cs: *mut cef_string_userfree_utf8_t) {
   cef_string_utf8_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_free(cs: *mut cef_string_userfree_utf16_t) {
   cef_string_utf16_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_clear(cs: *mut cef_string_utf8_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut u8;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_alloc() -> *mut cef_string_utf8_t {
    #![inline(never)]
    new0::<cef_string_utf8_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: *mut cef_string_utf8_t, copy: c_int) -> c_int {
    cef_string_utf8_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<u8>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf8_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_cmp(a: *const cef_string_utf8_t, b: *const cef_string_utf8_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice((*a).str as *const u8, (*a).length as uint, |astr:&[u8]| {
            slice::raw::buf_as_slice((*b).str as *const u8, (*b).length as uint, |bstr:&[u8]| {
                  match astr.cmp(&bstr) {
                       Less => -1,
                       Equal => 0,
                       Greater => 1
                  }
            })
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(src, src_len as uint, |result| {
            match str::from_utf8(result) {
                 Some(enc) => {
                      let conv = enc.utf16_units().collect::<Vec<u16>>();
                      cef_string_utf16_set(conv.as_ptr(), conv.len() as size_t, output, 1);
                      1
                 },
                 None => 0
            }
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_to_utf8(src: *const u16, src_len: size_t, output: *mut cef_string_utf8_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(src, src_len as uint, |ustr| {
            match string::String::from_utf16(ustr) {
                Some(str) => {
                    cef_string_utf8_set(str.as_bytes().as_ptr(), str.len() as size_t, output, 1);
                    1 as c_int
                },
                None =>  0 as c_int
            }
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_clear(cs: *mut cef_string_utf16_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut c_ushort;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_alloc() -> *mut cef_string_utf16_t {
    #![inline(never)]
    new0::<cef_string_utf16_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, output: *mut cef_string_utf16_t, copy: c_int) -> c_int {
    cef_string_utf16_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<c_ushort>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_utf16_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_cmp(a: *const cef_string_utf16_t, b: *const cef_string_utf16_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(mem::transmute((*a).str), (*a).length as uint, |astr:&[u16]| {
            slice::raw::buf_as_slice(mem::transmute((*b).str), (*b).length as uint, |bstr:&[u16]| {
                  match astr.cmp(&bstr) {
                       Less => -1,
                       Equal => 0,
                       Greater => 1
                  }
            })
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_wide_clear(cs: *mut cef_string_wide_t) {
    unsafe {
        if !fptr_is_null(mem::transmute((*cs).dtor)) {
            let dtor = (*cs).dtor;
            dtor((*cs).str);
        }
        (*cs).length = 0;
        (*cs).str = 0 as *mut wchar_t;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_alloc() -> *mut cef_string_wide_t {
    #![inline(never)]
    new0::<cef_string_wide_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, output: *mut cef_string_wide_t, copy: c_int) -> c_int {
    cef_string_wide_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<wchar_t>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = string_wide_dtor;
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}
<|endoftext|>


<commit_before>//! A synchronous client for the PostgreSQL database.
//!
//! # Example
//!
//! ```no_run
//! use postgres::{Client, NoTls};
//!
//! # fn main() -> Result<(), postgres::Error> {
//! let mut client = Client::connect("host=localhost user=postgres", NoTls)?;
//!
//! client.simple_query("
//!     CREATE TABLE person (
//!         id      SERIAL PRIMARY KEY,
//!         name    TEXT NOT NULL,
//!         data    BYTEA
//!     )
//! ")?;
//!
//! let name = "Ferris";
//! let data = None::<&[u8]>;
//! client.execute(
//!     "INSERT INTO person (name, data) VALUES ($1, $2)",
//!     &[&name, &data],
//! )?;
//!
//! for row in client.query("SELECT id, name, data FROM person", &[])? {
//!     let id: i32 = row.get(0);
//!     let name: &str = row.get(1);
//!     let data: Option<&[u8]> = row.get(2);
//!
//!     println!("found person: {} {} {:?}", id, name, data);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! # Implementation
//!
//! This crate is a lightweight wrapper over tokio-postgres. The `tokio_postgres::Connection` is spawned onto an
//! executor, and the `tokio_postgres::Client` is wrapped in the `postgres::Client`, which simply waits on the futures
//! the nonblocking client creates.
//!
//! # Runtime
//!
//! A client can be constructed directly from a `tokio-postgres` client via a `From` implementation, but the `runtime`
//! Cargo feature (enabled by default) provides a more convenient interface. By default, connections will be spawned
//! onto a static tokio `Runtime`, but a custom `Executor` can also be used instead.
//!
//! # SSL/TLS support
//!
//! TLS support is implemented via external libraries. `Client::connect` and `Config::connect` take a TLS implementation
//! as an argument. The `NoTls` type in this crate can be used when TLS is not required. Otherwise, the
//! `postgres-openssl` and `postgres-native-tls` crates provide implementations backed by the `openssl` and `native-tls`
//! crates, respectively.
#![doc(html_root_url = "https://docs.rs/postgres/0.17")]
#![warn(clippy::all, rust_2018_idioms, missing_docs)]

pub use tokio_postgres::{
    error, row, tls, types, Column, Portal, SimpleQueryMessage, Socket, Statement, ToStatement,
};

pub use crate::client::*;
pub use crate::config::Config;
pub use crate::copy_in_writer::CopyInWriter;
pub use crate::copy_out_reader::CopyOutReader;
#[doc(no_inline)]
pub use crate::error::Error;
#[doc(no_inline)]
pub use crate::row::{Row, SimpleQueryRow};
pub use crate::row_iter::RowIter;
#[doc(no_inline)]
pub use crate::tls::NoTls;
pub use crate::transaction::*;

mod client;
pub mod config;
mod copy_in_writer;
mod copy_out_reader;
mod lazy_pin;
pub mod binary_copy;
mod row_iter;
mod transaction;

#[cfg(test)]
mod test;
<commit_msg>rustfmt<commit_after>//! A synchronous client for the PostgreSQL database.
//!
//! # Example
//!
//! ```no_run
//! use postgres::{Client, NoTls};
//!
//! # fn main() -> Result<(), postgres::Error> {
//! let mut client = Client::connect("host=localhost user=postgres", NoTls)?;
//!
//! client.simple_query("
//!     CREATE TABLE person (
//!         id      SERIAL PRIMARY KEY,
//!         name    TEXT NOT NULL,
//!         data    BYTEA
//!     )
//! ")?;
//!
//! let name = "Ferris";
//! let data = None::<&[u8]>;
//! client.execute(
//!     "INSERT INTO person (name, data) VALUES ($1, $2)",
//!     &[&name, &data],
//! )?;
//!
//! for row in client.query("SELECT id, name, data FROM person", &[])? {
//!     let id: i32 = row.get(0);
//!     let name: &str = row.get(1);
//!     let data: Option<&[u8]> = row.get(2);
//!
//!     println!("found person: {} {} {:?}", id, name, data);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! # Implementation
//!
//! This crate is a lightweight wrapper over tokio-postgres. The `tokio_postgres::Connection` is spawned onto an
//! executor, and the `tokio_postgres::Client` is wrapped in the `postgres::Client`, which simply waits on the futures
//! the nonblocking client creates.
//!
//! # Runtime
//!
//! A client can be constructed directly from a `tokio-postgres` client via a `From` implementation, but the `runtime`
//! Cargo feature (enabled by default) provides a more convenient interface. By default, connections will be spawned
//! onto a static tokio `Runtime`, but a custom `Executor` can also be used instead.
//!
//! # SSL/TLS support
//!
//! TLS support is implemented via external libraries. `Client::connect` and `Config::connect` take a TLS implementation
//! as an argument. The `NoTls` type in this crate can be used when TLS is not required. Otherwise, the
//! `postgres-openssl` and `postgres-native-tls` crates provide implementations backed by the `openssl` and `native-tls`
//! crates, respectively.
#![doc(html_root_url = "https://docs.rs/postgres/0.17")]
#![warn(clippy::all, rust_2018_idioms, missing_docs)]

pub use tokio_postgres::{
    error, row, tls, types, Column, Portal, SimpleQueryMessage, Socket, Statement, ToStatement,
};

pub use crate::client::*;
pub use crate::config::Config;
pub use crate::copy_in_writer::CopyInWriter;
pub use crate::copy_out_reader::CopyOutReader;
#[doc(no_inline)]
pub use crate::error::Error;
#[doc(no_inline)]
pub use crate::row::{Row, SimpleQueryRow};
pub use crate::row_iter::RowIter;
#[doc(no_inline)]
pub use crate::tls::NoTls;
pub use crate::transaction::*;

pub mod binary_copy;
mod client;
pub mod config;
mod copy_in_writer;
mod copy_out_reader;
mod lazy_pin;
mod row_iter;
mod transaction;

#[cfg(test)]
mod test;
<|endoftext|>


<commit_before>extern crate slog_term;
#[macro_use] extern crate slog;
extern crate tokio_core;
extern crate futures;

#[macro_use] extern crate reql;

use slog::DrainExt;
use tokio_core::reactor::Core;
use futures::stream::Stream;

use reql::{Client, Run, ResponseValue};
use reql::structs::ServerStatus;

fn main() {
    // Build an output drain
    let drain = slog_term::streamer().async().compact().build();

    // Setup a logger
    let logger = slog::Logger::root(drain.fuse(), o!());

    // Create a new ReQL client with the logger
    let r = Client::new().with_logger(logger);

    // Create an even loop
    let core = Core::new().unwrap();

    // Create a connection pool
    let conn = r.connect(args!(core.handle(), {servers: ["localhost"]})).unwrap();

    // Run the query
    let stati = r.db("rethinkdb").table("server_status").run::<ServerStatus>(conn).unwrap();

    // Process results
    for res in stati.wait() {
        match res {
            Ok(Ok(Some(ResponseValue::Expected(server)))) => {
                println!("{} => {:?}", server.name, server.network.canonical_addresses);
            }
            Ok(Ok(res)) => {
                println!("unexpected response from DB: {:?}", res);
            }
            Ok(Err(error)) => {
                println!("{}", error);
            }
            Err(_) => {
                println!("an error occured while processing the stream");
            }
        }
    }
}
<commit_msg>Spin a thread maintaining servers<commit_after>extern crate slog_term;
#[macro_use] extern crate slog;
extern crate tokio_core;
extern crate futures;

#[macro_use] extern crate reql;

use slog::DrainExt;
use tokio_core::reactor::Core;
use futures::stream::Stream;

use reql::{Client, Run, ResponseValue};
use reql::structs::ServerStatus;

fn main() {
    args!(|| "hello world!");
    // Build an output drain
    let drain = slog_term::streamer().async().compact().build();

    // Setup a logger
    let logger = slog::Logger::root(drain.fuse(), o!());

    // Create a new ReQL client with the logger
    let r = Client::new().with_logger(logger);

    // Create an even loop
    let core = Core::new().unwrap();

    // Create a connection pool
    let conn = r.connect(args!(core.handle(), {servers: ["localhost"]})).unwrap();

    // Run the query
    let query = r.db("rethinkdb").table("server_status");
    let stati = query.changes().map(args!(query)).run::<ServerStatus>(conn).unwrap();

    // Process results
    for res in stati.wait() {
        match res {
            Ok(Ok(Some(ResponseValue::Expected(server)))) => {
                println!("{} => {:?}", server.name, server.network.canonical_addresses);
            }
            Ok(Ok(res)) => {
                println!("unexpected response from DB: {:?}", res);
            }
            Ok(Err(error)) => {
                println!("{:?}", error);
            }
            Err(_) => {
                println!("an error occured while processing the stream");
            }
        }
    }
}
<|endoftext|>


<commit_before>// This example demonstrates use of the callback-based `Resolver`.  It uses
// a third-party DNS parser to handle the response, rather than `c-ares`'s own
// parser.
extern crate c_ares;
extern crate c_ares_resolver;
extern crate dns_parser;

use std::error::Error;
use std::sync::mpsc;

use c_ares_resolver::Resolver;
use dns_parser::Packet;

fn handle_result(result: &Result<&[u8], c_ares::Error>) {
    match *result {
        Err(ref e) => {
            println!("Query failed with error '{}'", e.description());
        },
        Ok(ref bytes) => {
            match Packet::parse(bytes) {
                Err(e) => {
                    println!(
                        "Parser failed with error '{}'",
                        e.description()
                    );
                },
                Ok(packet) => {
                    for answer in &packet.answers {
                        println!("{:?}", answer.data);
                    }
                },
            }
        },
    }
}

fn main() {
    // Create Resolver.
    let resolver = Resolver::new().expect("Failed to create resolver");

    // Make an A-query, but use a third-party DNS parser to handle the result.
    let (tx, rx) = mpsc::channel();
    resolver.query(
        "apple.com",
        1,  // internet
        1,  // Host address
        move |result| {
            handle_result(&result);
            tx.send(()).expect("failed to send on channel!");
        }
    );

    // If we allowed the resolver to be dropped, we'd shut down c-ares and the
    // query would fail.  Wait for the handler to signal that it is done.
    rx.recv().expect("query did not complete!");
}
<commit_msg>clippy says I have a reference to a reference<commit_after>// This example demonstrates use of the callback-based `Resolver`.  It uses
// a third-party DNS parser to handle the response, rather than `c-ares`'s own
// parser.
extern crate c_ares;
extern crate c_ares_resolver;
extern crate dns_parser;

use std::error::Error;
use std::sync::mpsc;

use c_ares_resolver::Resolver;
use dns_parser::Packet;

fn handle_result(result: &Result<&[u8], c_ares::Error>) {
    match *result {
        Err(ref e) => {
            println!("Query failed with error '{}'", e.description());
        },
        Ok(bytes) => {
            match Packet::parse(bytes) {
                Err(e) => {
                    println!(
                        "Parser failed with error '{}'",
                        e.description()
                    );
                },
                Ok(packet) => {
                    for answer in &packet.answers {
                        println!("{:?}", answer.data);
                    }
                },
            }
        },
    }
}

fn main() {
    // Create Resolver.
    let resolver = Resolver::new().expect("Failed to create resolver");

    // Make an A-query, but use a third-party DNS parser to handle the result.
    let (tx, rx) = mpsc::channel();
    resolver.query(
        "apple.com",
        1,  // internet
        1,  // Host address
        move |result| {
            handle_result(&result);
            tx.send(()).expect("failed to send on channel!");
        }
    );

    // If we allowed the resolver to be dropped, we'd shut down c-ares and the
    // query would fail.  Wait for the handler to signal that it is done.
    rx.recv().expect("query did not complete!");
}
<|endoftext|>