<commit_before>#![feature(generators, generator_trait, conservative_impl_trait, proc_macro)]

extern crate futures_await as futures;
extern crate crossbeam;

use std::ops::Generator;
use std::ops::GeneratorState;
use futures::prelude::*;
use crossbeam::sync::chase_lev;

struct AsyncGenerator<T>
where T: Generator
{
    generator: T,
    producer: chase_lev::Worker<GeneratorState<T::Yield, T::Return>>,
    consumer: chase_lev::Stealer<GeneratorState<T::Yield, T::Return>>
}

impl<T> AsyncGenerator<T>
where T: Generator
{
    fn new(generator: T) -> Self {
        let (mut producer, consumer) = chase_lev::deque();
        let mut async_gen = AsyncGenerator {
            generator: generator,
            producer: producer,
            consumer: consumer
        };
        async_gen.populate();
        async_gen
    }

    #[async]
    fn resume(&mut self) -> Result<Option<T::Yield>, ()> {
        loop {
            match self.consumer.steal() {
                chase_lev::Steal::Data(data) => match data {
                    GeneratorState::Yielded(value) => return Ok(Some(value)),
                    GeneratorState::Complete(_) => return Ok(None)
                }
            }
        }
    }

    #[async]
    fn populate(&mut self) -> Result<(), ()> {
        loop {
            let next_item = self.generator.resume();
            self.producer.push(next_item);
            match next_item {
                GeneratorState::Complete(_) => break
            }
        }
        Ok(())
    }
}

trait IntoAsync<T>
where T: Generator
{
    fn into_async(self) -> AsyncGenerator<T>;
}

impl<T> IntoAsync<T> for T
where T: Generator
{
    fn into_async(self) -> AsyncGenerator<T> {
        AsyncGenerator::new(self)
    }
}

impl<T> Iterator for AsyncGenerator<T>
where T: Generator
{
    type Item = T::Yield;

    fn next(&mut self) -> Option<Self::Item> {
        let future = async_block! {
            await!(self.resume())
        };
        match future.wait() {
            Ok(Some(next_value)) => Some(next_value),
            Ok(None) => None,
            Err(_) => None
        }
    }
}

#[cfg(test)]
mod tests {
    use std::ops::Generator;
    use IntoAsync;

    fn dummy_generator() -> impl Generator<Yield=u32, Return=()> {
        || {
            yield 1;
            yield 2;
            yield 3;
            return;
        }
    }

    #[test]
    fn it_works() {
        let test : Vec<_> = dummy_generator().into_async().collect();

        assert_eq!(vec![1u32, 2, 3], test);
    }
}
<commit_msg>Final non-functional implem.<commit_after>#![feature(generators, generator_trait, conservative_impl_trait, proc_macro)]

extern crate futures_await as futures;
extern crate crossbeam;

use std::ops::Generator;
use std::ops::GeneratorState;
use futures::prelude::*;
use crossbeam::sync::chase_lev;

struct AsyncGenerator<T>
where T: Generator
{
    generator: T,
    producer: chase_lev::Worker<GeneratorState<T::Yield, T::Return>>,
    consumer: chase_lev::Stealer<GeneratorState<T::Yield, T::Return>>
}

impl<T> AsyncGenerator<T>
where T: Generator
{
    fn new(generator: T) -> Self {
        let (mut producer, consumer) = chase_lev::deque();
        let mut async_gen = AsyncGenerator {
            generator: generator,
            producer: producer,
            consumer: consumer
        };
        async_gen.populate();
        async_gen
    }

    fn resume(&mut self) -> Option<T::Yield> {
        loop {
            match self.consumer.steal() {
                chase_lev::Steal::Data(data) => match data {
                    GeneratorState::Yielded(value) => return Some(value),
                    GeneratorState::Complete(_) => return None
                }
            }
        }
    }

    #[async]
    fn populate(&mut self) -> Result<(), ()> {
        loop {
            let next_item = self.generator.resume();
            self.producer.push(next_item);
            match next_item {
                GeneratorState::Complete(_) => break
            }
        }
        Ok(())
    }
}

trait IntoAsync<T>
where T: Generator
{
    fn into_async(self) -> AsyncGenerator<T>;
}

impl<T> IntoAsync<T> for T
where T: Generator
{
    fn into_async(self) -> AsyncGenerator<T> {
        AsyncGenerator::new(self)
    }
}

impl<T> Iterator for AsyncGenerator<T>
where T: Generator
{
    type Item = T::Yield;

    fn next(&mut self) -> Option<Self::Item> {
        return self.resume();
    }
}

#[cfg(test)]
mod tests {
    use std::ops::Generator;
    use IntoAsync;

    fn dummy_generator() -> impl Generator<Yield=u32, Return=()> {
        || {
            yield 1;
            yield 2;
            yield 3;
            return;
        }
    }

    #[test]
    fn it_works() {
        let test : Vec<_> = dummy_generator().into_async().collect();

        assert_eq!(vec![1u32, 2, 3], test);
    }
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate unix_socket;

mod platform;
pub mod fs;

use std::{io, process, mem};
use std::collections::BTreeMap;
use std::path::Path;
use unix_socket::UnixStream;

pub struct RunningSandbox {
    pid: libc::c_int,
    pub socket: UnixStream,
}

impl RunningSandbox {
    pub fn wait(self) -> io::Result<RunningSandbox> {
        let mut status = 0;
        unsafe { libc::waitpid(self.pid, &mut status, 0) };
        if status == 0 {
            Ok(self)
        } else {
            Err(io::Error::new(io::ErrorKind::Other, "Sandboxed child process exited with non-zero status"))
        }
    }
}

pub struct SandboxContext {
    dirs: BTreeMap<String, fs::Directory>,
}

impl SandboxContext {
    pub fn directory(&self, key: &str) -> Option<&fs::Directory> {
        self.dirs.get(key)
    }
}

pub struct Sandbox {
    dirs: BTreeMap<String, fs::Directory>,
}

impl Sandbox {
    pub fn new() -> Sandbox {
        Sandbox {
            dirs: BTreeMap::new()
        }
    }

    pub fn add_directory<P: AsRef<Path>>(&mut self, key: &str, path: P) -> &mut Sandbox {
        if let Some(dir) = fs::Directory::new(path) {
            self.dirs.insert(key.to_owned(), dir);
        }
        self
    }

    pub fn sandbox_this_process(&self) -> SandboxContext {
        platform::enter_sandbox(Box::new(self.dirs.values()));
        self.context()
    }

    pub fn sandboxed_fork<F>(&self, fun: F) -> io::Result<RunningSandbox>
    where F: Fn(&mut SandboxContext, &mut UnixStream) -> () {
        let (parent_socket, child_socket) = try!(UnixStream::pair());

        let pid = unsafe { libc::fork() };
        if pid < 0 {
            Err(io::Error::new(io::ErrorKind::Other, "fork() failed"))
        } else if pid > 0 { // parent
            // child_socket is dropped by going out of scope
            Ok(RunningSandbox {
                pid: pid,
                socket: parent_socket,
            })
        } else { // child
            mem::drop(parent_socket);
            platform::enter_sandbox(Box::new(self.dirs.values()));
            let mut socket = child_socket;
            fun(&mut self.context(), &mut socket);
            process::exit(0);
        }
    }

    fn context(&self) -> SandboxContext {
        SandboxContext {
            dirs: self.dirs.to_owned(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::net;
    use std::fs::File;
    use std::io::{Read, Write, BufRead, BufReader};

    #[test]
    fn test_socket() {
        let mut process = Sandbox::new()
            .sandboxed_fork(|_, socket| {
                let msg = BufReader::new(socket.try_clone().unwrap()).lines().next().unwrap().unwrap() + " > from sandbox\n";
                socket.write_all(msg.as_bytes()).unwrap();
                socket.flush().unwrap();
            })
            .unwrap();
        process.socket.write_all(b"from parent\n").unwrap();
        process.socket.flush().unwrap();
        let msg = BufReader::new(process.socket.try_clone().unwrap()).lines().next().unwrap().unwrap();
        assert_eq!(msg, "from parent > from sandbox");
        process.wait().unwrap();
    }

    #[test]
    fn test_preopened_file() {
        let mut f = File::open("UNLICENSE").unwrap();
        let mut process = Sandbox::new()
            .sandboxed_fork(|_, socket| {
                let mut buf = String::new();
                BufReader::new(&f).read_line(&mut buf).unwrap();
                let msg = buf.replace("\n", "") + " from sandbox\n";
                socket.write_all(msg.as_bytes()).unwrap();
                socket.flush().unwrap();
            })
            .unwrap();
        let msg = BufReader::new(process.socket.try_clone().unwrap()).lines().next().unwrap().unwrap();
        assert_eq!(msg, "This is free and unencumbered software released into the public domain. from sandbox");
        process.wait().unwrap();
    }

    #[cfg(not(target_os = "openbsd"))]
    #[test]
    fn test_directory() {
        Sandbox::new()
            .add_directory("temp", "/tmp")
            .sandboxed_fork(|ctx, _| {
                let mut file = ctx.directory("temp").unwrap()
                    .open_options().write(true).create(true)
                    .open("hello_rusty_sandbox").unwrap();
                file.write_all(b"Hello World").unwrap();
            }).unwrap().wait().unwrap();
        let mut buf = Vec::new();
        let mut f = File::open("/tmp/hello_rusty_sandbox").unwrap();
        f.read_to_end(&mut buf).unwrap();
        assert_eq!(&buf[..], b"Hello World");
    }

    #[cfg(not(target_os = "openbsd"))]
    #[test]
    fn test_forbidden_file() {
        let process = Sandbox::new()
            .sandboxed_fork(|_, socket| {
                socket.write_all(match File::open("README.md") {
                    Ok(_) => b"ok",
                    Err(_) => b"err",
                }).unwrap();
                socket.flush().unwrap();
            })
            .unwrap();
        let msg = BufReader::new(process.socket.try_clone().unwrap()).lines().next().unwrap().unwrap();
        assert_eq!(msg, "err");
        process.wait().unwrap();
    }

    #[cfg(not(target_os = "openbsd"))]
    #[test]
    fn test_forbidden_socket() {
        let process = Sandbox::new()
            .sandboxed_fork(|_, socket| {
                socket.write_all(match net::TcpStream::connect("8.8.8.8:53") { // yes it's available on tcp too
                    Ok(_) => b"ok",
                    Err(_) => b"err",
                }).unwrap();
                socket.flush().unwrap();
            })
            .unwrap();
        let msg = BufReader::new(process.socket.try_clone().unwrap()).lines().next().unwrap().unwrap();
        assert_eq!(msg, "err");
        process.wait().unwrap();
    }

}
<commit_msg>Return a Result from sandbox_this_process()<commit_after>extern crate libc;
extern crate unix_socket;

mod platform;
pub mod fs;

use std::{io, process, mem};
use std::collections::BTreeMap;
use std::path::Path;
use unix_socket::UnixStream;

pub struct RunningSandbox {
    pid: libc::c_int,
    pub socket: UnixStream,
}

impl RunningSandbox {
    pub fn wait(self) -> io::Result<RunningSandbox> {
        let mut status = 0;
        unsafe { libc::waitpid(self.pid, &mut status, 0) };
        if status == 0 {
            Ok(self)
        } else {
            Err(io::Error::new(io::ErrorKind::Other, "Sandboxed child process exited with non-zero status"))
        }
    }
}

pub struct SandboxContext {
    dirs: BTreeMap<String, fs::Directory>,
}

impl SandboxContext {
    pub fn directory(&self, key: &str) -> Option<&fs::Directory> {
        self.dirs.get(key)
    }
}

pub struct Sandbox {
    dirs: BTreeMap<String, fs::Directory>,
}

impl Sandbox {
    pub fn new() -> Sandbox {
        Sandbox {
            dirs: BTreeMap::new()
        }
    }

    pub fn add_directory<P: AsRef<Path>>(&mut self, key: &str, path: P) -> &mut Sandbox {
        if let Some(dir) = fs::Directory::new(path) {
            self.dirs.insert(key.to_owned(), dir);
        }
        self
    }

    pub fn sandbox_this_process(&self) -> Result<SandboxContext, ()> {
        if platform::enter_sandbox(Box::new(self.dirs.values())) {
            Ok(self.context())
        } else {
            Err(())
        }
    }

    pub fn sandboxed_fork<F>(&self, fun: F) -> io::Result<RunningSandbox>
    where F: Fn(&mut SandboxContext, &mut UnixStream) -> () {
        let (parent_socket, child_socket) = try!(UnixStream::pair());

        let pid = unsafe { libc::fork() };
        if pid < 0 {
            Err(io::Error::new(io::ErrorKind::Other, "fork() failed"))
        } else if pid > 0 { // parent
            // child_socket is dropped by going out of scope
            Ok(RunningSandbox {
                pid: pid,
                socket: parent_socket,
            })
        } else { // child
            mem::drop(parent_socket);
            platform::enter_sandbox(Box::new(self.dirs.values()));
            let mut socket = child_socket;
            fun(&mut self.context(), &mut socket);
            process::exit(0);
        }
    }

    fn context(&self) -> SandboxContext {
        SandboxContext {
            dirs: self.dirs.to_owned(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::net;
    use std::fs::File;
    use std::io::{Read, Write, BufRead, BufReader};

    #[test]
    fn test_socket() {
        let mut process = Sandbox::new()
            .sandboxed_fork(|_, socket| {
                let msg = BufReader::new(socket.try_clone().unwrap()).lines().next().unwrap().unwrap() + " > from sandbox\n";
                socket.write_all(msg.as_bytes()).unwrap();
                socket.flush().unwrap();
            })
            .unwrap();
        process.socket.write_all(b"from parent\n").unwrap();
        process.socket.flush().unwrap();
        let msg = BufReader::new(process.socket.try_clone().unwrap()).lines().next().unwrap().unwrap();
        assert_eq!(msg, "from parent > from sandbox");
        process.wait().unwrap();
    }

    #[test]
    fn test_preopened_file() {
        let mut f = File::open("UNLICENSE").unwrap();
        let mut process = Sandbox::new()
            .sandboxed_fork(|_, socket| {
                let mut buf = String::new();
                BufReader::new(&f).read_line(&mut buf).unwrap();
                let msg = buf.replace("\n", "") + " from sandbox\n";
                socket.write_all(msg.as_bytes()).unwrap();
                socket.flush().unwrap();
            })
            .unwrap();
        let msg = BufReader::new(process.socket.try_clone().unwrap()).lines().next().unwrap().unwrap();
        assert_eq!(msg, "This is free and unencumbered software released into the public domain. from sandbox");
        process.wait().unwrap();
    }

    #[cfg(not(target_os = "openbsd"))]
    #[test]
    fn test_directory() {
        Sandbox::new()
            .add_directory("temp", "/tmp")
            .sandboxed_fork(|ctx, _| {
                let mut file = ctx.directory("temp").unwrap()
                    .open_options().write(true).create(true)
                    .open("hello_rusty_sandbox").unwrap();
                file.write_all(b"Hello World").unwrap();
            }).unwrap().wait().unwrap();
        let mut buf = Vec::new();
        let mut f = File::open("/tmp/hello_rusty_sandbox").unwrap();
        f.read_to_end(&mut buf).unwrap();
        assert_eq!(&buf[..], b"Hello World");
    }

    #[cfg(not(target_os = "openbsd"))]
    #[test]
    fn test_forbidden_file() {
        let process = Sandbox::new()
            .sandboxed_fork(|_, socket| {
                socket.write_all(match File::open("README.md") {
                    Ok(_) => b"ok",
                    Err(_) => b"err",
                }).unwrap();
                socket.flush().unwrap();
            })
            .unwrap();
        let msg = BufReader::new(process.socket.try_clone().unwrap()).lines().next().unwrap().unwrap();
        assert_eq!(msg, "err");
        process.wait().unwrap();
    }

    #[cfg(not(target_os = "openbsd"))]
    #[test]
    fn test_forbidden_socket() {
        let process = Sandbox::new()
            .sandboxed_fork(|_, socket| {
                socket.write_all(match net::TcpStream::connect("8.8.8.8:53") { // yes it's available on tcp too
                    Ok(_) => b"ok",
                    Err(_) => b"err",
                }).unwrap();
                socket.flush().unwrap();
            })
            .unwrap();
        let msg = BufReader::new(process.socket.try_clone().unwrap()).lines().next().unwrap().unwrap();
        assert_eq!(msg, "err");
        process.wait().unwrap();
    }

}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! Bincode is a crate for encoding and decoding using a tiny binary
//! serialization strategy.  Using it, you can easily go from having
//! an object in memory, quickly serialize it to bytes, and then
//! deserialize it back just as fast!
//!
//! ### Using Basic Functions
//!
//! ```rust
//! extern crate bincode;
//! use bincode::{serialize, deserialize};
//! fn main() {
//!     // The object that we will serialize.
//!     let target: Option<String>  = Some("hello world".to_string());
//!
//!     let encoded: Vec<u8>        = serialize(&target).unwrap();
//!     let decoded: Option<String> = deserialize(&encoded[..]).unwrap();
//!     assert_eq!(target, decoded);
//! }
//! ```

#![crate_name = "bincode"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]

extern crate byteorder;
extern crate serde;

mod config;
mod ser;
mod error;
mod de;
mod internal;

pub use error::{Error, ErrorKind, Result};
pub use config::Config;
pub use de::read::{BincodeRead, IoReader, SliceReader};

/// An object that implements this trait can be passed a
/// serde::Deserializer without knowing its concrete type.
///
/// This trait should be used only for `with_deserializer` functions.
#[doc(hidden)]
pub trait DeserializerAcceptor<'a> {
    /// The return type for the accept method
    type Output;
    /// Accept a serde::Deserializer and do whatever you want with it.
    fn accept<T: serde::Deserializer<'a>>(self, T) -> Self::Output;
}

/// An object that implements this trait can be passed a
/// serde::Serializer without knowing its concrete type.
///
/// This trait should be used only for `with_serializer` functions.
#[doc(hidden)]
pub trait SerializerAcceptor {
    /// The return type for the accept method
    type Output;
    /// Accept a serde::Serializer and do whatever you want with it.
    fn accept<T: serde::Serializer>(self, T) -> Self::Output;
}

/// Get a default configuration object.
///
/// ### Default Configuration:
/// Byte limit: Unlimited
/// Endianness: Little
pub fn config() -> Config {
    Config::new()
}

/// Serializes an object directly into a `Writer` using the default configuration.
///
/// If the serialization would take more bytes than allowed by the size limit, an error
/// is returned and *no bytes* will be written into the `Writer`.
pub fn serialize_into<W, T: ?Sized>(writer: W, value: &T) -> Result<()>
where
    W: std::io::Write,
    T: serde::Serialize,
{
    config().serialize_into(writer, value)
}

/// Serializes a serializable object into a `Vec` of bytes using the default configuration.
pub fn serialize<T: ?Sized>(value: &T) -> Result<Vec<u8>>
where
    T: serde::Serialize,
{
    config().serialize(value)
}

/// Deserializes an object directly from a `Read`er using the default configuration.
///
/// If this returns an `Error`, `reader` may be in an invalid state.
pub fn deserialize_from<R, T>(reader: R) -> Result<T>
where
    R: std::io::Read,
    T: serde::de::DeserializeOwned,
{
    config().deserialize_from(reader)
}

/// Deserializes an object from a custom `BincodeRead`er using the default configuration.
/// It is highly recommended to use `deserialize_from` unless you need to implement
/// `BincodeRead` for performance reasons.
///
/// If this returns an `Error`, `reader` may be in an invalid state.
pub fn deserialize_from_custom<'a, R, T>(reader: R) -> Result<T>
where
    R: de::read::BincodeRead<'a>,
    T: serde::de::DeserializeOwned,
{
    config().deserialize_from_custom(reader)
}

/// TODO: document
#[doc(hidden)]
pub fn deserialize_in_place<'a, R, T>(reader: R, place: &mut T) -> Result<()>
where
    T: serde::de::Deserialize<'a>,
    R: BincodeRead<'a>
{
    config().deserialize_in_place(reader, place)
}

/// Deserializes a slice of bytes into an instance of `T` using the default configuration.
pub fn deserialize<'a, T>(bytes: &'a [u8]) -> Result<T>
where
    T: serde::de::Deserialize<'a>,
{
    config().deserialize(bytes)
}

/// Returns the size that an object would be if serialized using Bincode with the default configuration.
pub fn serialized_size<T: ?Sized>(value: &T) -> Result<u64>
where
    T: serde::Serialize,
{
    config().serialized_size(value)
}

/// Executes the acceptor with a serde::Deserializer instance.
/// NOT A PART OF THE STABLE PUBLIC API
#[doc(hidden)]
pub fn with_deserializer<'a, A,  R>(reader: R, acceptor: A) -> A::Output
where A: DeserializerAcceptor<'a>,
        R: BincodeRead<'a>
{
    config().with_deserializer(reader, acceptor)
}

/// Executes the acceptor with a serde::Serializer instance.
/// NOT A PART OF THE STABLE PUBLIC API
#[doc(hidden)]
pub fn with_serializer<A, W>(writer: W, acceptor: A) -> A::Output
where A: SerializerAcceptor,
    W: std::io::Write
{
    config().with_serializer(writer, acceptor)
}
<commit_msg>some comment fixes<commit_after>#![deny(missing_docs)]

//! Bincode is a crate for encoding and decoding using a tiny binary
//! serialization strategy.  Using it, you can easily go from having
//! an object in memory, quickly serialize it to bytes, and then
//! deserialize it back just as fast!
//!
//! ### Using Basic Functions
//!
//! ```rust
//! extern crate bincode;
//! use bincode::{serialize, deserialize};
//! fn main() {
//!     // The object that we will serialize.
//!     let target: Option<String>  = Some("hello world".to_string());
//!
//!     let encoded: Vec<u8>        = serialize(&target).unwrap();
//!     let decoded: Option<String> = deserialize(&encoded[..]).unwrap();
//!     assert_eq!(target, decoded);
//! }
//! ```

#![crate_name = "bincode"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]

extern crate byteorder;
extern crate serde;

mod config;
mod ser;
mod error;
mod de;
mod internal;

pub use error::{Error, ErrorKind, Result};
pub use config::Config;
pub use de::read::{BincodeRead, IoReader, SliceReader};

/// An object that implements this trait can be passed a
/// serde::Deserializer without knowing its concrete type.
///
/// This trait should be used only for `with_deserializer` functions.
#[doc(hidden)]
pub trait DeserializerAcceptor<'a> {
    /// The return type for the accept method
    type Output;
    /// Accept a serde::Deserializer and do whatever you want with it.
    fn accept<T: serde::Deserializer<'a>>(self, T) -> Self::Output;
}

/// An object that implements this trait can be passed a
/// serde::Serializer without knowing its concrete type.
///
/// This trait should be used only for `with_serializer` functions.
#[doc(hidden)]
pub trait SerializerAcceptor {
    /// The return type for the accept method
    type Output;
    /// Accept a serde::Serializer and do whatever you want with it.
    fn accept<T: serde::Serializer>(self, T) -> Self::Output;
}

/// Get a default configuration object.
///
/// ### Default Configuration:
///
/// | Byte limit | Endianness |
/// |------------|------------|
/// | Unlimited  | Little     |
pub fn config() -> Config {
    Config::new()
}

/// Serializes an object directly into a `Writer` using the default configuration.
///
/// If the serialization would take more bytes than allowed by the size limit, an error
/// is returned and *no bytes* will be written into the `Writer`.
pub fn serialize_into<W, T: ?Sized>(writer: W, value: &T) -> Result<()>
where
    W: std::io::Write,
    T: serde::Serialize,
{
    config().serialize_into(writer, value)
}

/// Serializes a serializable object into a `Vec` of bytes using the default configuration.
pub fn serialize<T: ?Sized>(value: &T) -> Result<Vec<u8>>
where
    T: serde::Serialize,
{
    config().serialize(value)
}

/// Deserializes an object directly from a `Read`er using the default configuration.
///
/// If this returns an `Error`, `reader` may be in an invalid state.
pub fn deserialize_from<R, T>(reader: R) -> Result<T>
where
    R: std::io::Read,
    T: serde::de::DeserializeOwned,
{
    config().deserialize_from(reader)
}

/// Deserializes an object from a custom `BincodeRead`er using the default configuration.
/// It is highly recommended to use `deserialize_from` unless you need to implement
/// `BincodeRead` for performance reasons.
///
/// If this returns an `Error`, `reader` may be in an invalid state.
pub fn deserialize_from_custom<'a, R, T>(reader: R) -> Result<T>
where
    R: de::read::BincodeRead<'a>,
    T: serde::de::DeserializeOwned,
{
    config().deserialize_from_custom(reader)
}

/// Only use this if you know what you're doing.
///
/// This is part of the public API.
#[doc(hidden)]
pub fn deserialize_in_place<'a, R, T>(reader: R, place: &mut T) -> Result<()>
where
    T: serde::de::Deserialize<'a>,
    R: BincodeRead<'a>
{
    config().deserialize_in_place(reader, place)
}

/// Deserializes a slice of bytes into an instance of `T` using the default configuration.
pub fn deserialize<'a, T>(bytes: &'a [u8]) -> Result<T>
where
    T: serde::de::Deserialize<'a>,
{
    config().deserialize(bytes)
}

/// Returns the size that an object would be if serialized using Bincode with the default configuration.
pub fn serialized_size<T: ?Sized>(value: &T) -> Result<u64>
where
    T: serde::Serialize,
{
    config().serialized_size(value)
}

/// Executes the acceptor with a serde::Deserializer instance.
/// NOT A PART OF THE STABLE PUBLIC API
#[doc(hidden)]
pub fn with_deserializer<'a, A,  R>(reader: R, acceptor: A) -> A::Output
where A: DeserializerAcceptor<'a>,
        R: BincodeRead<'a>
{
    config().with_deserializer(reader, acceptor)
}

/// Executes the acceptor with a serde::Serializer instance.
/// NOT A PART OF THE STABLE PUBLIC API
#[doc(hidden)]
pub fn with_serializer<A, W>(writer: W, acceptor: A) -> A::Output
where A: SerializerAcceptor,
    W: std::io::Write
{
    config().with_serializer(writer, acceptor)
}
<|endoftext|>


<commit_before>//! Highly modular & configurable hash & crypto library written in Rust
//!
//! # About
//!
//! Octavo is Rust implementation of cryptographic primitives and [Transport Layer Security][tls].
//! Our goal is to provide safe, fast, full-featured and configurable cryptographic library
//! for modern world.
//!
//! Except of Rust API we want expose also C API for usage with other languages and tools. Probably
//! there will also land thin [OpenSSL][openssl] compatibility cascade for use with existing code.
//!
//! [tls]: https://en.wikipedia.org/wiki/Transport_Layer_Security "Transport Layer Security"
//!
//! ## Legalities
//!
//! Please remember that export/import and/or use of strong cryptography software, providing
//! cryptography hooks, or even just communicating technical details about cryptography software is
//! illegal in some parts of the world. So when you import this package to your country,
//! re-distribute it from there or even just email technical suggestions or even source patches to
//! the authors or other people you are strongly advised to pay close attention to any laws or
//! regulations which apply to you. The authors of Octavo are not liable for any violations you
//! make here. So be careful, it is your responsibility.[^authors]
//!
//! [^authors]: Text of this paragraph is copied from [OpenSSL website][openssl].
//! [openssl]: http://www.openssl.org/ "OpenSSL - Cryptography and SSL/TLS Toolkit"

#![doc(html_logo_url = "https://raw.githubusercontent.com/libOctavo/octavo/master/docs/logo.png",
       html_root_url = "http://libOctavo.github.io/")]

pub extern crate octavo_crypto as crypto;
pub extern crate octavo_digest as digest;
pub extern crate octavo_kdf as kdf;
pub extern crate octavo_mac as mac;
<commit_msg>fix(octavo): compatibility with stable<commit_after>//! Highly modular & configurable hash & crypto library written in Rust
//!
//! # About
//!
//! Octavo is Rust implementation of cryptographic primitives and [Transport Layer Security][tls].
//! Our goal is to provide safe, fast, full-featured and configurable cryptographic library
//! for modern world.
//!
//! Except of Rust API we want expose also C API for usage with other languages and tools. Probably
//! there will also land thin [OpenSSL][openssl] compatibility cascade for use with existing code.
//!
//! [tls]: https://en.wikipedia.org/wiki/Transport_Layer_Security "Transport Layer Security"
//!
//! ## Legalities
//!
//! Please remember that export/import and/or use of strong cryptography software, providing
//! cryptography hooks, or even just communicating technical details about cryptography software is
//! illegal in some parts of the world. So when you import this package to your country,
//! re-distribute it from there or even just email technical suggestions or even source patches to
//! the authors or other people you are strongly advised to pay close attention to any laws or
//! regulations which apply to you. The authors of Octavo are not liable for any violations you
//! make here. So be careful, it is your responsibility.[^authors]
//!
//! [^authors]: Text of this paragraph is copied from [OpenSSL website][openssl].
//! [openssl]: http://www.openssl.org/ "OpenSSL - Cryptography and SSL/TLS Toolkit"

#![doc(html_logo_url = "https://raw.githubusercontent.com/libOctavo/octavo/master/docs/logo.png",
       html_root_url = "http://libOctavo.github.io/")]

pub extern crate octavo_crypto;
pub extern crate octavo_digest;
pub extern crate octavo_kdf;
pub extern crate octavo_mac;

pub use octavo_crypto as crypto;
pub use octavo_digest as digest;
pub use octavo_kdf as kdf;
pub use octavo_mac as mac;
<|endoftext|>


<commit_before>#![deny(missing_docs)]
#![warn(dead_code)]

//! A user friendly game engine written in Rust.

#[cfg(feature = "include_gfx")]
extern crate libc;
#[cfg(feature = "include_gfx")]
extern crate gfx;
#[cfg(feature = "include_gfx")]
extern crate gfx_device_gl;
#[cfg(feature = "include_gfx")]
extern crate gfx_graphics;
#[cfg(feature = "include_opengl")]
extern crate opengl_graphics;
#[cfg(feature = "include_sdl2")]
extern crate sdl2;
#[cfg(feature = "include_sdl2")]
extern crate sdl2_window;
#[cfg(feature = "include_glfw")]
extern crate glfw;
#[cfg(feature = "include_glfw")]
extern crate glfw_window;
#[cfg(feature = "include_glutin")]
extern crate glutin;
#[cfg(feature = "include_glutin")]
extern crate glutin_window;
extern crate graphics;
extern crate fps_counter;
extern crate current;
extern crate shader_version;

extern crate piston;

#[cfg(feature = "include_sdl2")]
pub use sdl2_window::Sdl2Window as WindowBackEnd;
#[cfg(feature = "include_glfw")]
pub use glfw_window::GlfwWindow as WindowBackEnd;
#[cfg(feature = "include_glutin")]
pub use glutin_window::GlutinWindow as WindowBackEnd;

#[cfg(feature = "include_gfx")]
use gfx_graphics::Gfx2d;
#[cfg(feature = "include_gfx")]
use gfx::{ DeviceExt };
#[cfg(feature = "include_gfx")]
use gfx_device_gl::{ GlDevice, GlResources };
#[cfg(feature = "include_gfx")]
use gfx_device_gl::CommandBuffer;

#[cfg(feature = "include_opengl")]
use opengl_graphics::GlGraphics;
use fps_counter::FPSCounter;

use std::rc::Rc;
use std::cell::RefCell;

use piston::window::WindowSettings;
use piston::quack::{ Get, Set };
use current::{ Current, CurrentGuard };

fn start_window<F>(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    mut f: F
)
    where
        F: FnMut()
{
    let mut window = Rc::new(RefCell::new(WindowBackEnd::new(
        opengl,
        window_settings,
    )));
    let mut fps_counter = Rc::new(RefCell::new(FPSCounter::new()));

    #[cfg(feature = "include_sdl2")]
    fn disable_vsync() { sdl2::video::gl_set_swap_interval(0); }

    #[cfg(not(feature = "include_sdl2"))]
    fn disable_vsync() {}

    disable_vsync();

    let window_guard = CurrentGuard::new(&mut window);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(fps_counter_guard);
}

#[cfg(feature = "include_opengl")]
fn start_opengl<F>(mut f: F)
    where
        F: FnMut()
{
    let mut gl = Rc::new(RefCell::new(GlGraphics::new(opengl)));

    let gl_guard = CurrentGuard::new(&mut gl);

    f();

    drop(gl_guard);
}

#[cfg(not(feature = "include_opengl"))]
fn start_opengl<F>(mut f: F)
    where
        F: FnMut()
{
    f();
}

#[cfg(feature = "include_gfx")]
fn start_gfx<F>(mut f: F)
    where
        F: FnMut()
{
    let window = current_window();

    let mut device = Rc::new(RefCell::new(GlDevice::new(|s| {
        #[cfg(feature = "include_sdl2")]
        fn get_proc_address(_: &WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            unsafe { std::mem::transmute(sdl2::video::gl_get_proc_address(s)) }
        }

        #[cfg(feature = "include_glfw")]
        fn get_proc_address(window: &mut WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            window.window.get_proc_address(s)
        }

        #[cfg(feature = "include_glutin")]
        fn get_proc_address(window: &WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            window.window.get_proc_address(s)
        }

        get_proc_address(&mut *window.borrow_mut(), s)
    })));
    let mut g2d = Rc::new(RefCell::new(Gfx2d::new(&mut *device.borrow_mut())));
    let mut renderer = Rc::new(RefCell::new(device.borrow_mut().create_renderer()));
    let piston::window::Size([w, h]) = window.get();
    let mut frame = Rc::new(RefCell::new(gfx::Frame::<GlResources>::new(w as u16, h as u16)));

    let device_guard = CurrentGuard::new(&mut device);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let frame_guard = CurrentGuard::new(&mut frame);

    f();

    drop(g2d_guard);
    drop(renderer_guard);
    drop(frame_guard);
    drop(device_guard);
}

#[cfg(not(feature = "include_gfx"))]
fn start_gfx<F>(mut f: F)
    where
        F: FnMut()
{
    f();
}

/// Initializes window and sets up current objects.
pub fn start<F>(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    mut f: F
)
    where
        F: FnMut()
{
    start_window(opengl, window_settings, || {
        start_opengl(|| {
            if cfg!(feature = "include_gfx") {
                start_gfx(|| f());
            } else {
                f();
            }
        })
    });
}

/// The current window
pub fn current_window() -> Rc<RefCell<WindowBackEnd>> {
    unsafe {
        Current::<Rc<RefCell<WindowBackEnd>>>::new().clone()
    }
}
/// The current Gfx device
#[cfg(feature = "include_gfx")]
pub fn current_gfx_device() -> Rc<RefCell<GlDevice>> {
    unsafe {
        Current::<Rc<RefCell<GlDevice>>>::new().clone()
    }
}
/// The current opengl_graphics back-end
#[cfg(feature = "include_opengl")]
pub fn current_gl() -> Rc<RefCell<GlGraphics>> {
    unsafe {
        Current::<Rc<RefCell<GlGraphics>>>::new().clone()
    }
}
/// The current gfx_graphics back-end
#[cfg(feature = "include_gfx")]
pub fn current_g2d() -> Rc<RefCell<Gfx2d<GlDevice>>> {
    unsafe {
        Current::<Rc<RefCell<Gfx2d<GlDevice>>>>::new().clone()
    }
}
/// The current Gfx renderer
#[cfg(feature = "include_gfx")]
pub fn current_renderer() -> Rc<RefCell<gfx::Renderer<CommandBuffer>>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Renderer<CommandBuffer>>>>::new().clone()
    }
}
/// The current Gfx frame
#[cfg(feature = "include_gfx")]
pub fn current_frame() -> Rc<RefCell<gfx::Frame<GlResources>>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Frame<GlResources>>>>::new().clone()
    }
}
/// The current FPS counter
pub fn current_fps_counter() -> Rc<RefCell<FPSCounter>> {
    unsafe {
        Current::<Rc<RefCell<FPSCounter>>>::new().clone()
    }
}

/// Returns an event iterator for the event loop
pub fn events() -> piston::event::Events<
    Rc<RefCell<WindowBackEnd>>, piston::event::Event
> {
    piston::event::events(current_window())
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> usize {
    let fps_counter = current_fps_counter();
    let mut fps_counter = fps_counter.borrow_mut();
    fps_counter.tick()
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    current_window().set_mut(piston::window::Title(text));
}

/// Returns true if the current window should be closed.
pub fn should_close() -> bool {
    use piston::window::ShouldClose;
    let ShouldClose(val) = current_window().get();
    val
}

/// Renders 2D graphics using Gfx.
#[cfg(feature = "include_gfx")]
pub fn render_2d_gfx<F>(
    bg_color: Option<[f32; 4]>,
    mut f: F
)
    where
        F: FnMut(graphics::Context,
            &mut gfx_graphics::GraphicsBackEnd<gfx_device_gl::GlDevice>)
{
    use gfx::Device;

    let renderer = current_renderer();
    let mut renderer = renderer.borrow_mut();
    let renderer = &mut *renderer;
    let gfx = current_g2d();
    let mut gfx = gfx.borrow_mut();
    let frame = current_frame();
    let frame = frame.borrow();
    gfx.draw(
        renderer,
        &*frame,
        |c, g| {
            if let Some(bg_color) = bg_color {
                graphics::clear(bg_color, g);
            }
            f(c, g);
        });
    let gfx_device = current_gfx_device();
    let mut gfx_device = gfx_device.borrow_mut();
    gfx_device.submit(renderer.as_buffer());
    renderer.reset();
}

/// Renders 2D graphics using OpenGL.
///
/// Panics if called nested within the closure
/// to prevent mutable aliases to the graphics back-end.
#[cfg(feature = "include_opengl")]
pub fn render_2d_opengl<F>(
    bg_color: Option<[f32; 4]>,
    mut f: F
)
    where
        F: FnMut(graphics::Context, &mut opengl_graphics::Gl)
{
    let window = current_window();
    let window = window.borrow();
    let piston::window::Size([w, h]) = window.get();
    let gl = current_gl();
    let mut gl = gl.borrow_mut();
    gl.draw([0, 0, w as i32, h as i32], |c, g| {
        use graphics::*;
        if let Some(bg_color) = bg_color {
            graphics::clear(bg_color, g);
        }
        f(c, g);
    });
}

<commit_msg>Fixed OpenGL argument<commit_after>#![deny(missing_docs)]
#![warn(dead_code)]

//! A user friendly game engine written in Rust.

#[cfg(feature = "include_gfx")]
extern crate libc;
#[cfg(feature = "include_gfx")]
extern crate gfx;
#[cfg(feature = "include_gfx")]
extern crate gfx_device_gl;
#[cfg(feature = "include_gfx")]
extern crate gfx_graphics;
#[cfg(feature = "include_opengl")]
extern crate opengl_graphics;
#[cfg(feature = "include_sdl2")]
extern crate sdl2;
#[cfg(feature = "include_sdl2")]
extern crate sdl2_window;
#[cfg(feature = "include_glfw")]
extern crate glfw;
#[cfg(feature = "include_glfw")]
extern crate glfw_window;
#[cfg(feature = "include_glutin")]
extern crate glutin;
#[cfg(feature = "include_glutin")]
extern crate glutin_window;
extern crate graphics;
extern crate fps_counter;
extern crate current;
extern crate shader_version;

extern crate piston;

#[cfg(feature = "include_sdl2")]
pub use sdl2_window::Sdl2Window as WindowBackEnd;
#[cfg(feature = "include_glfw")]
pub use glfw_window::GlfwWindow as WindowBackEnd;
#[cfg(feature = "include_glutin")]
pub use glutin_window::GlutinWindow as WindowBackEnd;

#[cfg(feature = "include_gfx")]
use gfx_graphics::Gfx2d;
#[cfg(feature = "include_gfx")]
use gfx::{ DeviceExt };
#[cfg(feature = "include_gfx")]
use gfx_device_gl::{ GlDevice, GlResources };
#[cfg(feature = "include_gfx")]
use gfx_device_gl::CommandBuffer;

#[cfg(feature = "include_opengl")]
use opengl_graphics::GlGraphics;
use fps_counter::FPSCounter;

use std::rc::Rc;
use std::cell::RefCell;

use piston::window::WindowSettings;
use piston::quack::{ Get, Set };
use current::{ Current, CurrentGuard };

fn start_window<F>(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    mut f: F
)
    where
        F: FnMut()
{
    let mut window = Rc::new(RefCell::new(WindowBackEnd::new(
        opengl,
        window_settings,
    )));
    let mut fps_counter = Rc::new(RefCell::new(FPSCounter::new()));

    #[cfg(feature = "include_sdl2")]
    fn disable_vsync() { sdl2::video::gl_set_swap_interval(0); }

    #[cfg(not(feature = "include_sdl2"))]
    fn disable_vsync() {}

    disable_vsync();

    let window_guard = CurrentGuard::new(&mut window);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(fps_counter_guard);
}

#[cfg(feature = "include_opengl")]
fn start_opengl<F>(opengl: shader_version::OpenGL, mut f: F)
    where
        F: FnMut()
{
    let mut gl = Rc::new(RefCell::new(GlGraphics::new(opengl)));

    let gl_guard = CurrentGuard::new(&mut gl);

    f();

    drop(gl_guard);
}

#[cfg(not(feature = "include_opengl"))]
fn start_opengl<F>(mut f: F)
    where
        F: FnMut()
{
    f();
}

#[cfg(feature = "include_gfx")]
fn start_gfx<F>(mut f: F)
    where
        F: FnMut()
{
    let window = current_window();

    let mut device = Rc::new(RefCell::new(GlDevice::new(|s| {
        #[cfg(feature = "include_sdl2")]
        fn get_proc_address(_: &WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            unsafe { std::mem::transmute(sdl2::video::gl_get_proc_address(s)) }
        }

        #[cfg(feature = "include_glfw")]
        fn get_proc_address(window: &mut WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            window.window.get_proc_address(s)
        }

        #[cfg(feature = "include_glutin")]
        fn get_proc_address(window: &WindowBackEnd, s: &str) ->
            *const libc::types::common::c95::c_void {
            window.window.get_proc_address(s)
        }

        get_proc_address(&mut *window.borrow_mut(), s)
    })));
    let mut g2d = Rc::new(RefCell::new(Gfx2d::new(&mut *device.borrow_mut())));
    let mut renderer = Rc::new(RefCell::new(device.borrow_mut().create_renderer()));
    let piston::window::Size([w, h]) = window.get();
    let mut frame = Rc::new(RefCell::new(gfx::Frame::<GlResources>::new(w as u16, h as u16)));

    let device_guard = CurrentGuard::new(&mut device);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let frame_guard = CurrentGuard::new(&mut frame);

    f();

    drop(g2d_guard);
    drop(renderer_guard);
    drop(frame_guard);
    drop(device_guard);
}

#[cfg(not(feature = "include_gfx"))]
fn start_gfx<F>(mut f: F)
    where
        F: FnMut()
{
    f();
}

/// Initializes window and sets up current objects.
pub fn start<F>(
    opengl: shader_version::OpenGL,
    window_settings: WindowSettings,
    mut f: F
)
    where
        F: FnMut()
{
    start_window(opengl, window_settings, || {
        start_opengl(opengl, || {
            if cfg!(feature = "include_gfx") {
                start_gfx(|| f());
            } else {
                f();
            }
        })
    });
}

/// The current window
pub fn current_window() -> Rc<RefCell<WindowBackEnd>> {
    unsafe {
        Current::<Rc<RefCell<WindowBackEnd>>>::new().clone()
    }
}
/// The current Gfx device
#[cfg(feature = "include_gfx")]
pub fn current_gfx_device() -> Rc<RefCell<GlDevice>> {
    unsafe {
        Current::<Rc<RefCell<GlDevice>>>::new().clone()
    }
}
/// The current opengl_graphics back-end
#[cfg(feature = "include_opengl")]
pub fn current_gl() -> Rc<RefCell<GlGraphics>> {
    unsafe {
        Current::<Rc<RefCell<GlGraphics>>>::new().clone()
    }
}
/// The current gfx_graphics back-end
#[cfg(feature = "include_gfx")]
pub fn current_g2d() -> Rc<RefCell<Gfx2d<GlDevice>>> {
    unsafe {
        Current::<Rc<RefCell<Gfx2d<GlDevice>>>>::new().clone()
    }
}
/// The current Gfx renderer
#[cfg(feature = "include_gfx")]
pub fn current_renderer() -> Rc<RefCell<gfx::Renderer<CommandBuffer>>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Renderer<CommandBuffer>>>>::new().clone()
    }
}
/// The current Gfx frame
#[cfg(feature = "include_gfx")]
pub fn current_frame() -> Rc<RefCell<gfx::Frame<GlResources>>> {
    unsafe {
        Current::<Rc<RefCell<gfx::Frame<GlResources>>>>::new().clone()
    }
}
/// The current FPS counter
pub fn current_fps_counter() -> Rc<RefCell<FPSCounter>> {
    unsafe {
        Current::<Rc<RefCell<FPSCounter>>>::new().clone()
    }
}

/// Returns an event iterator for the event loop
pub fn events() -> piston::event::Events<
    Rc<RefCell<WindowBackEnd>>, piston::event::Event
> {
    piston::event::events(current_window())
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> usize {
    let fps_counter = current_fps_counter();
    let mut fps_counter = fps_counter.borrow_mut();
    fps_counter.tick()
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    current_window().set_mut(piston::window::Title(text));
}

/// Returns true if the current window should be closed.
pub fn should_close() -> bool {
    use piston::window::ShouldClose;
    let ShouldClose(val) = current_window().get();
    val
}

/// Renders 2D graphics using Gfx.
#[cfg(feature = "include_gfx")]
pub fn render_2d_gfx<F>(
    bg_color: Option<[f32; 4]>,
    mut f: F
)
    where
        F: FnMut(graphics::Context,
            &mut gfx_graphics::GraphicsBackEnd<gfx_device_gl::GlDevice>)
{
    use gfx::Device;

    let renderer = current_renderer();
    let mut renderer = renderer.borrow_mut();
    let renderer = &mut *renderer;
    let gfx = current_g2d();
    let mut gfx = gfx.borrow_mut();
    let frame = current_frame();
    let frame = frame.borrow();
    gfx.draw(
        renderer,
        &*frame,
        |c, g| {
            if let Some(bg_color) = bg_color {
                graphics::clear(bg_color, g);
            }
            f(c, g);
        });
    let gfx_device = current_gfx_device();
    let mut gfx_device = gfx_device.borrow_mut();
    gfx_device.submit(renderer.as_buffer());
    renderer.reset();
}

/// Renders 2D graphics using OpenGL.
///
/// Panics if called nested within the closure
/// to prevent mutable aliases to the graphics back-end.
#[cfg(feature = "include_opengl")]
pub fn render_2d_opengl<F>(
    bg_color: Option<[f32; 4]>,
    mut f: F
)
    where
        F: FnMut(graphics::Context, &mut opengl_graphics::Gl)
{
    let window = current_window();
    let window = window.borrow();
    let piston::window::Size([w, h]) = window.get();
    let gl = current_gl();
    let mut gl = gl.borrow_mut();
    gl.draw([0, 0, w as i32, h as i32], |c, g| {
        use graphics::*;
        if let Some(bg_color) = bg_color {
            graphics::clear(bg_color, g);
        }
        f(c, g);
    });
}

<|endoftext|>


<commit_before>#![warn(rust_2018_idioms)]
extern crate conduit;
extern crate route_recognizer as router;

use std::collections::hash_map::{Entry, HashMap};
use std::error::Error;
use std::fmt;

use conduit::{box_error, Handler, HandlerResult, Method, RequestExt};
use router::{Match, Router};

#[derive(Default)]
pub struct RouteBuilder {
    routers: HashMap<Method, Router<WrappedHandler>>,
}

#[derive(Clone, Copy)]
pub struct RoutePattern(&'static str);

pub struct WrappedHandler {
    pattern: RoutePattern,
    handler: Box<dyn Handler>,
}

impl conduit::Handler for WrappedHandler {
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        self.handler.call(request)
    }
}

#[derive(Debug)]
pub struct RouterError(String);

impl RouteBuilder {
    pub fn new() -> RouteBuilder {
        RouteBuilder {
            routers: HashMap::new(),
        }
    }

    #[allow(clippy::borrowed_box)]
    pub fn recognize<'a>(
        &'a self,
        method: &Method,
        path: &str,
    ) -> Result<Match<&WrappedHandler>, RouterError> {
        match self.routers.get(method) {
            Some(router) => router.recognize(path),
            None => Err(format!("No router found for {:?}", method)),
        }
        .map_err(RouterError)
    }

    pub fn map<'a, H: Handler>(
        &'a mut self,
        method: Method,
        pattern: &'static str,
        handler: H,
    ) -> &'a mut RouteBuilder {
        {
            let router = match self.routers.entry(method) {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(Router::new()),
            };
            let wrapped_handler = WrappedHandler {
                pattern: RoutePattern(pattern),
                handler: Box::new(handler),
            };
            router.add(pattern, wrapped_handler);
        }
        self
    }

    pub fn get<'a, H: Handler>(
        &'a mut self,
        pattern: &'static str,
        handler: H,
    ) -> &'a mut RouteBuilder {
        self.map(Method::GET, pattern, handler)
    }

    pub fn post<'a, H: Handler>(
        &'a mut self,
        pattern: &'static str,
        handler: H,
    ) -> &'a mut RouteBuilder {
        self.map(Method::POST, pattern, handler)
    }

    pub fn put<'a, H: Handler>(
        &'a mut self,
        pattern: &'static str,
        handler: H,
    ) -> &'a mut RouteBuilder {
        self.map(Method::PUT, pattern, handler)
    }

    pub fn delete<'a, H: Handler>(
        &'a mut self,
        pattern: &'static str,
        handler: H,
    ) -> &'a mut RouteBuilder {
        self.map(Method::DELETE, pattern, handler)
    }

    pub fn head<'a, H: Handler>(
        &'a mut self,
        pattern: &'static str,
        handler: H,
    ) -> &'a mut RouteBuilder {
        self.map(Method::HEAD, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        let m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => return Err(box_error(e)),
            }
        };

        {
            let extensions = request.mut_extensions();
            extensions.insert(m.handler.pattern);
            extensions.insert(m.params.clone());
        }

        (*m.handler).call(request)
    }
}

impl Error for RouterError {
    fn description(&self) -> &str {
        &self.0
    }
}

impl fmt::Display for RouterError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a router::Params;
}

pub fn params(req: &dyn RequestExt) -> &router::Params {
    req.extensions()
        .find::<router::Params>()
        .expect("Missing params")
}

impl<'a> RequestParams<'a> for &'a (dyn RequestExt + 'a) {
    fn params(self) -> &'a router::Params {
        params(self)
    }
}

#[cfg(test)]
mod tests {
    extern crate conduit_test;

    use std::io;
    use std::net::SocketAddr;

    use {RequestParams, RouteBuilder, RoutePattern};

    use self::conduit_test::ResponseExt;
    use conduit::{
        Body, Extensions, Handler, HeaderMap, Host, Method, Response, Scheme, StatusCode, TypeMap,
        Version,
    };

    struct RequestSentinel {
        method: Method,
        path: String,
        extensions: conduit::Extensions,
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: TypeMap::new(),
                method,
            }
        }
    }

    impl conduit::RequestExt for RequestSentinel {
        fn http_version(&self) -> Version {
            unimplemented!()
        }
        fn method(&self) -> &Method {
            &self.method
        }
        fn scheme(&self) -> Scheme {
            unimplemented!()
        }
        fn host(&self) -> Host<'_> {
            unimplemented!()
        }
        fn virtual_root(&self) -> Option<&str> {
            unimplemented!()
        }
        fn path(&self) -> &str {
            &self.path
        }
        fn path_mut(&mut self) -> &mut String {
            &mut self.path
        }
        fn query_string(&self) -> Option<&str> {
            unimplemented!()
        }
        fn remote_addr(&self) -> SocketAddr {
            unimplemented!()
        }
        fn content_length(&self) -> Option<u64> {
            unimplemented!()
        }
        fn headers(&self) -> &HeaderMap {
            unimplemented!()
        }
        fn body(&mut self) -> &mut dyn io::Read {
            unimplemented!()
        }
        fn extensions(&self) -> &Extensions {
            &self.extensions
        }
        fn mut_extensions(&mut self) -> &mut Extensions {
            &mut self.extensions
        }
    }

    #[test]
    fn basic_get() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::GET, "/posts/1");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"1, GET, /posts/:id"[..]);
    }

    #[test]
    fn basic_post() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/posts/10");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"10, POST, /posts/:id"[..]);
    }

    #[test]
    fn nonexistent_route() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/nonexistent");
        router.call(&mut req).err().expect("No response");
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut dyn conduit::RequestExt) -> conduit::HttpResult {
        let mut res = vec![];
        res.push(req.params()["id"].clone());
        res.push(format!("{:?}", req.method()));
        res.push(
            req.extensions()
                .find::<RoutePattern>()
                .unwrap()
                .0
                .to_string(),
        );

        let bytes = res.join(", ").into_bytes();
        Response::builder().body(Body::from_vec(bytes))
    }
}
<commit_msg>Remove unnecessary lifetime specifiers<commit_after>#![warn(rust_2018_idioms)]
extern crate conduit;
extern crate route_recognizer as router;

use std::collections::hash_map::{Entry, HashMap};
use std::error::Error;
use std::fmt;

use conduit::{box_error, Handler, HandlerResult, Method, RequestExt};
use router::{Match, Router};

#[derive(Default)]
pub struct RouteBuilder {
    routers: HashMap<Method, Router<WrappedHandler>>,
}

#[derive(Clone, Copy)]
pub struct RoutePattern(&'static str);

pub struct WrappedHandler {
    pattern: RoutePattern,
    handler: Box<dyn Handler>,
}

impl conduit::Handler for WrappedHandler {
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        self.handler.call(request)
    }
}

#[derive(Debug)]
pub struct RouterError(String);

impl RouteBuilder {
    pub fn new() -> RouteBuilder {
        RouteBuilder {
            routers: HashMap::new(),
        }
    }

    #[allow(clippy::borrowed_box)]
    pub fn recognize<'a>(
        &'a self,
        method: &Method,
        path: &str,
    ) -> Result<Match<&WrappedHandler>, RouterError> {
        match self.routers.get(method) {
            Some(router) => router.recognize(path),
            None => Err(format!("No router found for {:?}", method)),
        }
        .map_err(RouterError)
    }

    pub fn map<H: Handler>(
        &mut self,
        method: Method,
        pattern: &'static str,
        handler: H,
    ) -> &mut RouteBuilder {
        {
            let router = match self.routers.entry(method) {
                Entry::Occupied(e) => e.into_mut(),
                Entry::Vacant(e) => e.insert(Router::new()),
            };
            let wrapped_handler = WrappedHandler {
                pattern: RoutePattern(pattern),
                handler: Box::new(handler),
            };
            router.add(pattern, wrapped_handler);
        }
        self
    }

    pub fn get<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut RouteBuilder {
        self.map(Method::GET, pattern, handler)
    }

    pub fn post<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut RouteBuilder {
        self.map(Method::POST, pattern, handler)
    }

    pub fn put<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut RouteBuilder {
        self.map(Method::PUT, pattern, handler)
    }

    pub fn delete<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut RouteBuilder {
        self.map(Method::DELETE, pattern, handler)
    }

    pub fn head<H: Handler>(&mut self, pattern: &'static str, handler: H) -> &mut RouteBuilder {
        self.map(Method::HEAD, pattern, handler)
    }
}

impl conduit::Handler for RouteBuilder {
    fn call(&self, request: &mut dyn RequestExt) -> HandlerResult {
        let m = {
            let method = request.method();
            let path = request.path();

            match self.recognize(&method, path) {
                Ok(m) => m,
                Err(e) => return Err(box_error(e)),
            }
        };

        {
            let extensions = request.mut_extensions();
            extensions.insert(m.handler.pattern);
            extensions.insert(m.params.clone());
        }

        (*m.handler).call(request)
    }
}

impl Error for RouterError {
    fn description(&self) -> &str {
        &self.0
    }
}

impl fmt::Display for RouterError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(&self.0, f)
    }
}

pub trait RequestParams<'a> {
    fn params(self) -> &'a router::Params;
}

pub fn params(req: &dyn RequestExt) -> &router::Params {
    req.extensions()
        .find::<router::Params>()
        .expect("Missing params")
}

impl<'a> RequestParams<'a> for &'a (dyn RequestExt + 'a) {
    fn params(self) -> &'a router::Params {
        params(self)
    }
}

#[cfg(test)]
mod tests {
    extern crate conduit_test;

    use std::io;
    use std::net::SocketAddr;

    use {RequestParams, RouteBuilder, RoutePattern};

    use self::conduit_test::ResponseExt;
    use conduit::{
        Body, Extensions, Handler, HeaderMap, Host, Method, Response, Scheme, StatusCode, TypeMap,
        Version,
    };

    struct RequestSentinel {
        method: Method,
        path: String,
        extensions: conduit::Extensions,
    }

    impl RequestSentinel {
        fn new(method: Method, path: &'static str) -> RequestSentinel {
            RequestSentinel {
                path: path.to_string(),
                extensions: TypeMap::new(),
                method,
            }
        }
    }

    impl conduit::RequestExt for RequestSentinel {
        fn http_version(&self) -> Version {
            unimplemented!()
        }
        fn method(&self) -> &Method {
            &self.method
        }
        fn scheme(&self) -> Scheme {
            unimplemented!()
        }
        fn host(&self) -> Host<'_> {
            unimplemented!()
        }
        fn virtual_root(&self) -> Option<&str> {
            unimplemented!()
        }
        fn path(&self) -> &str {
            &self.path
        }
        fn path_mut(&mut self) -> &mut String {
            &mut self.path
        }
        fn query_string(&self) -> Option<&str> {
            unimplemented!()
        }
        fn remote_addr(&self) -> SocketAddr {
            unimplemented!()
        }
        fn content_length(&self) -> Option<u64> {
            unimplemented!()
        }
        fn headers(&self) -> &HeaderMap {
            unimplemented!()
        }
        fn body(&mut self) -> &mut dyn io::Read {
            unimplemented!()
        }
        fn extensions(&self) -> &Extensions {
            &self.extensions
        }
        fn mut_extensions(&mut self) -> &mut Extensions {
            &mut self.extensions
        }
    }

    #[test]
    fn basic_get() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::GET, "/posts/1");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"1, GET, /posts/:id"[..]);
    }

    #[test]
    fn basic_post() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/posts/10");
        let res = router.call(&mut req).expect("No response");

        assert_eq!(res.status(), StatusCode::OK);
        assert_eq!(*res.into_cow(), b"10, POST, /posts/:id"[..]);
    }

    #[test]
    fn nonexistent_route() {
        let router = test_router();
        let mut req = RequestSentinel::new(Method::POST, "/nonexistent");
        router.call(&mut req).err().expect("No response");
    }

    fn test_router() -> RouteBuilder {
        let mut router = RouteBuilder::new();
        router.post("/posts/:id", test_handler);
        router.get("/posts/:id", test_handler);
        router
    }

    fn test_handler(req: &mut dyn conduit::RequestExt) -> conduit::HttpResult {
        let mut res = vec![];
        res.push(req.params()["id"].clone());
        res.push(format!("{:?}", req.method()));
        res.push(
            req.extensions()
                .find::<RoutePattern>()
                .unwrap()
                .0
                .to_string(),
        );

        let bytes = res.join(", ").into_bytes();
        Response::builder().body(Body::from_vec(bytes))
    }
}
<|endoftext|>


<commit_before>#[derive(PartialEq, Debug)]
pub enum Direction {
    North,
    East,
    South,
    West,
}

pub struct Point {
    x: i32,
    y: i32,
}

pub fn distance(input: &str) -> u32 {
    let mut location = Point { x: 0, y: 0 };
    let mut direction = Direction::North;

    for instruction in input.split_whitespace() {
        let mut chars = instruction.chars();
        if let (Some(turn_dir), Some(num_blocks)) = (chars.next(), chars.next()) {
            direction = turn(direction, turn_dir);
            let num_blocks: i32 = num_blocks.to_string()
                                            .parse()
                                            .expect("Cannot parse");
            match direction {
                Direction::North => location.y += num_blocks,
                Direction::East  => location.x += num_blocks,
                Direction::South => location.y -= num_blocks,
                Direction::West  => location.x -= num_blocks,
            }
        } else {
            panic!("Could not get instructions out of {}", instruction);
        }

    }
    (location.x.abs() + location.y.abs()) as u32
}

pub fn turn(initial_direction: Direction, turn_command: char) -> Direction {
    match (turn_command, initial_direction) {
        ('L', Direction::North) => Direction::West,
        ('L', Direction::West) => Direction::South,
        ('L', Direction::South) => Direction::East,
        ('L', Direction::East) => Direction::North,

        ('R', Direction::North) => Direction::East,
        ('R', Direction::East) => Direction::South,
        ('R', Direction::South) => Direction::West,
        ('R', Direction::West) => Direction::North,

        (unknown_turn_command, dir) => panic!("\
            I don't know how to turn {} from {:?}!",
            unknown_turn_command,
            dir
        ),
    }
}

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

    #[test]
    fn r1_is_one() {
        assert_eq!(distance("R1"), 1);
    }

    #[test]
    fn r1_r1_is_two() {
        assert_eq!(distance("R1, R1"), 2);
    }

    #[test]
    fn something_more() {
        assert_eq!(distance("R2, L5, L4, L5, R4"), 6);
    }

    #[test]
    fn turn_left() {
        let mut dir = Direction::North;
        dir = turn(dir, 'L');
        assert_eq!(dir, Direction::West);
        dir = turn(dir, 'L');
        assert_eq!(dir, Direction::South);
        dir = turn(dir, 'L');
        assert_eq!(dir, Direction::East);
        dir = turn(dir, 'L');
        assert_eq!(dir, Direction::North);
    }

    #[test]
    fn turn_right() {
        let mut dir = Direction::North;
        dir = turn(dir, 'R');
        assert_eq!(dir, Direction::East);
        dir = turn(dir, 'R');
        assert_eq!(dir, Direction::South);
        dir = turn(dir, 'R');
        assert_eq!(dir, Direction::West);
        dir = turn(dir, 'R');
        assert_eq!(dir, Direction::North);
    }
}<commit_msg>Be able to take numbers > 1 digit :( :( :( oops<commit_after>#[derive(PartialEq, Debug)]
pub enum Direction {
    North,
    East,
    South,
    West,
}

pub struct Point {
    x: i32,
    y: i32,
}

pub fn distance(input: &str) -> u32 {
    let mut location = Point { x: 0, y: 0 };
    let mut direction = Direction::North;

    for instruction in input.split(", ") {
        let (turn_dir, num_blocks) = instruction.split_at(1);

        println!("Now processing ({}) ({})", turn_dir, num_blocks);
        direction = turn(direction, turn_dir);
        let num_blocks: i32 = num_blocks.to_string()
                                        .trim()
                                        .parse()
                                        .expect("Cannot parse");
        println!("Going {:?} {} blocks", direction, num_blocks);
        match direction {
            Direction::North => location.y += num_blocks,
            Direction::East  => location.x += num_blocks,
            Direction::South => location.y -= num_blocks,
            Direction::West  => location.x -= num_blocks,
        }
        println!("Location: ({}, {})", location.x, location.y);
    }
    (location.x.abs() + location.y.abs()) as u32
}

pub fn turn(initial_direction: Direction, turn_command: &str) -> Direction {
    match (turn_command, initial_direction) {
        ("L", Direction::North) => Direction::West,
        ("L", Direction::West) => Direction::South,
        ("L", Direction::South) => Direction::East,
        ("L", Direction::East) => Direction::North,

        ("R", Direction::North) => Direction::East,
        ("R", Direction::East) => Direction::South,
        ("R", Direction::South) => Direction::West,
        ("R", Direction::West) => Direction::North,

        (unknown_turn_command, dir) => panic!("\
            I don't know how to turn {} from {:?}!",
            unknown_turn_command,
            dir
        ),
    }
}

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

    #[test]
    fn r1_is_one() {
        assert_eq!(distance("R1"), 1);
    }

    #[test]
    fn r1_r1_is_two() {
        assert_eq!(distance("R1, R1"), 2);
    }

    #[test]
    fn something_more() {
        assert_eq!(distance("R2, L5, L4, L5, R4"), 6);
    }

    #[test]
    fn r10_is_ten() {
        assert_eq!(distance("R10"), 10);
    }

    #[test]
    fn turn_left() {
        let mut dir = Direction::North;
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::West);
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::South);
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::East);
        dir = turn(dir, "L");
        assert_eq!(dir, Direction::North);
    }

    #[test]
    fn turn_right() {
        let mut dir = Direction::North;
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::East);
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::South);
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::West);
        dir = turn(dir, "R");
        assert_eq!(dir, Direction::North);
    }
}<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(clippy)]

use std::mem;
use std::ptr;
use std::cell::Cell;
use std::ops::Index;
use std::ops::IndexMut;
use std::default::Default;
use std::iter::FromIterator;

unsafe fn as_ref<'a, T>(ptr: *const T) -> Option<&'a T> {
    if ptr.is_null() {
        None
    } else {
        Some(&*ptr)
    }
}

unsafe fn as_mut<'a, T>(ptr: *mut T) -> Option<&'a mut T> {
    if ptr.is_null() {
        None
    } else {
        Some(&mut *ptr)
    }
}

pub struct Iter<'a, T: 'a> {
    next: Option<&'a Node<T>>
}

pub struct IterMut<'a, T: 'a> {
    next: Option<&'a mut Node<T>>
}

struct Node<T> {
    prev:  *mut Node<T>,
    value: T,
    next:  *mut Node<T>
}

pub struct DoublyLinkedList<T> {
    current: Cell<*mut Node<T>>,
    first:   *mut Node<T>,
    last:    *mut Node<T>,
    index:   Cell<isize>,
    length:  usize
}

impl<'a, T> DoublyLinkedList<T> {
    pub fn new() -> DoublyLinkedList<T> {
        DoublyLinkedList {
            current: Cell::new(ptr::null_mut()),
            first:   ptr::null_mut(),
            last:    ptr::null_mut(),
            index:   Cell::new(-1),
            length:  0
        }
    }

    pub fn singleton(v: T) -> DoublyLinkedList<T> {
        unsafe {
            let node = Node::new_on_heap(v);
            DoublyLinkedList {
                current: Cell::new(node),
                first:   node,
                last:    node,
                index:   Cell::new(0),
                length:  1
            }
        }
    }

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

    pub fn is_empty(&self) -> bool {
        self.length == 0
    }

    pub fn front_mut(&mut self) -> Option<&'a mut T> {
        unsafe { as_mut(self.first).map(|n| { &mut n.value }) }
    }

    pub fn front(&self) -> Option<&'a T> {
        unsafe { as_ref(self.first).map(|n| { &n.value }) }
    }

    pub fn back_mut(&mut self) -> Option<&'a mut T> {
        unsafe { as_mut(self.last).map(|n| { &mut n.value }) }
    }

    pub fn back(&self) -> Option<&'a T> {
        unsafe { as_ref(self.last).map(|n| { &n.value }) }
    }

    pub fn iter(&self) -> Iter<'a, T> {
        unsafe {
            Iter {
                next: if self.first.is_null() {
                    None
                } else {
                    Some(&*self.first)
                }
            }
        }
    }

    pub fn iter_mut(&self) -> IterMut<'a, T> {
        unsafe {
            IterMut {
                next: if self.first.is_null() {
                    None
                } else {
                    Some(&mut *self.first)
                }
            }
        }
    }

    pub fn push_back(&mut self, val: T) {
        unsafe {
            if self.length == 0 {
                *self = DoublyLinkedList::singleton(val);
            } else {
                (*(self.last)).next = Node::new_on_heap(val);
                (*(*(self.last)).next).prev = self.last;
                self.last = (*(self.last)).next;
                self.length += 1;
            }
        }
    }

    pub fn push_front(&mut self, val: T) {
        unsafe {
            if self.length == 0 {
                *self = DoublyLinkedList::singleton(val);
            } else {
                (*(self.first)).prev = Node::new_on_heap(val);
                (*(*(self.first)).prev).next = self.first;
                self.first = (*(self.first)).prev;
                self.length += 1;
                self.index.set(self.index.get() + 1);
            }
        }
    }

    fn index(&self, i: usize) -> Option<&'a T> {
        unsafe {
            if i >= self.length {
                None
            } else {
                self.go_to(i);
                Some(&(*self.current.get()).value)
            }
        }
    }

    fn index_mut(&mut self, i: usize) -> Option<&'a mut T> {
        unsafe {
            if i >= self.length {
                None
            } else  {
                self.go_to(i);
                Some(&mut (*self.current.get()).value)
            }
        }
    }

    fn go_to(&self, i: usize) {
        if self.length / 2 > i {
            if (self.index.get() - i as isize).abs() > i as isize {
                self.go_to_from_start(i);
            } else {
                self.go_to_from_current(i);
            }
        } else if (self.index.get() - i as isize).abs() >= (self.length as isize - i as isize).abs() {
            self.go_to_from_end(i);
        } else {
            self.go_to_from_current(i);
        }
    }

    fn go_to_from_current(&self, i: usize) {
        unsafe {
            while (i as isize) > self.index.get() {
                self.current.set((*self.current.get()).next);
                self.index.set(self.index.get() + 1);
            }
            while (i as isize) < self.index.get() {
                self.current.set((*self.current.get()).prev);
                self.index.set(self.index.get() - 1);
            }
        }
    }

    fn go_to_from_start(&self, i: usize) {
        self.current.set(self.first);
        self.index.set(0);
        self.go_to(i);
    }

    fn go_to_from_end(&self, i: usize) {
        self.current.set(self.last);
        self.index.set(self.length as isize - 1);
        self.go_to(i);
    }

    pub fn pop_back(&mut self) -> Option<T> {
        unsafe {
            if self.length == 0 {
                None
            } else {
                let val = ptr::read(&(*self.last).value);
                if self.current.get() == self.last {
                    self.current.set((*self.last).prev);
                    self.index.set(self.index.get() - 1);
                }
                self.length -= 1;
                let old_last = self.last;
                self.last = (*self.last).prev;
                drop(mem::transmute::<_, Box<Node<T>>>(old_last));
                Some(val)
            }
        }
    }

    pub fn pop_front(&mut self) -> Option<T> {
        unsafe {
            if self.length == 0 {
                None
            } else {
                let val = ptr::read(&(*self.first).value);
                if self.current.get() == self.first {
                    self.current.set((*self.first).next);
                }
                self.length -= 1;
                let old_first = self.first;
                self.first = (*self.first).next;
                drop(mem::transmute::<_, Box<Node<T>>>(old_first));
                Some(val)
            }
        }
    }

    pub fn insert(&mut self, i: usize, val: T) {
        if i > self.length {
            panic!("DoublyLinkedList::insert: index out of range");
        } else {
            if self.length == 0 { *self = DoublyLinkedList::singleton(val); return; }
            if i == self.length { self.push_back(val); return; }
            if i == 0           { self.push_front(val); return; }
            unsafe {
                self.go_to(i);
                let new = Node::new_on_heap(val);
                (*new).next = self.current.get();
                (*new).prev = (*self.current.get()).prev;
                (*(*(self.current.get())).prev).next = new;
                (*self.current.get()).prev = new;
                self.current.set(new);
                self.length += 1;
            }
        }
    }

    pub fn remove(&mut self, i: usize) -> T {
        if i >= self.length {
            panic!("DoublyLinkedList::remove: index out of range");
        } else {
            if i == 0 { return self.pop_front().unwrap() }
            if i + 1 == self.length { return self.pop_back().unwrap() }
            unsafe {
                self.go_to(i);

                let val = ptr::read(&(*self.current.get()).value);

                (*(*self.current.get()).next).prev = (*self.current.get()).prev;
                (*(*self.current.get()).prev).next = (*self.current.get()).next;

                let old_node = self.current.get();
                self.current.set((*self.current.get()).next);
                drop(mem::transmute::<_, Box<Node<T>>>(old_node));

                self.length -= 1;

                val
            }
        }
    }

    pub fn append(&mut self, other: &mut DoublyLinkedList<T>) {
        unsafe {
            self.length += other.len();
            (*self.last).next = other.first;
            self.last = other.last;
            *other = Self::new();
        }
    }
}

impl<T> Index<usize> for DoublyLinkedList<T> {
    type Output = T;
    fn index<'a>(&self, i: usize) -> &'a T {
        self.index(i).unwrap()
    }
}

impl<T> IndexMut<usize> for DoublyLinkedList<T> {
    fn index_mut<'a>(&mut self, i: usize) -> &'a mut T {
        self.index_mut(i).unwrap()
    }
}

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

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<Self::Item> {
        unsafe {
            match self.next {
                None => None,
                Some(node) => {
                    let result = node;
                    self.next = if result.next.is_null() {
                        None
                    } else {
                        Some(&*result.next)
                    };

                    return Some(&(*result).value);
                }
            }
        }
    }
}

impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;
    fn next(&mut self) -> Option<Self::Item> {
        unsafe {
            match self.next.take() {
                None => None,
                Some(node) => {
                    let result = node;
                    self.next = if result.next.is_null() {
                        None
                    } else {
                        Some(&mut *result.next)
                    };

                    return Some(&mut (*result).value);
                }
            }
        }
    }
}

impl<T> FromIterator<T> for DoublyLinkedList<T> {
    fn from_iter<A>(iterator: A) -> Self where A: IntoIterator<Item=T> {
        let mut list = Self::new();

        for x in iterator {
            list.push_back(x);
        }

        return list;
    }
}

impl<T> Node<T> {
    fn new(v: T) -> Node<T> {
        Node {
            prev: ptr::null_mut(),
            value: v,
            next: ptr::null_mut()
        }
    }

    unsafe fn new_on_heap(v: T) -> *mut Node<T> {
        let node = Box::new(Node::new(v));
        let node: *mut Node<T> = mem::transmute(node);
        return node;
    }
}

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

    #[test]
    fn test_list() {
        let mut nums = DoublyLinkedList::singleton(5i32);
        assert_eq!(5i32, *nums.back().unwrap());
        assert_eq!(nums.len(), 1);
        nums.push_front(7i32);
        assert_eq!(nums.len(), 2);
        assert_eq!(7i32, *nums.front().unwrap());
        nums.push_front(9i32);
        nums.push_front(6i32);
        assert_eq!(5i32, *nums.index(3).unwrap());
        nums.push_back(10i32);
        assert_eq!(5i32, *nums.index(3).unwrap());
    }

    #[test]
    fn test_len() {
        let mut nums = DoublyLinkedList::singleton(4i32);

        for x in 0..100 { nums.push_front(x); }

        assert_eq!(101, nums.len());

        for x in 0..100 { nums.push_back(x); }

        assert_eq!(201, nums.len());

        nums.insert(40, 8);

        assert_eq!(202, nums.len());

        nums.insert(200, 56);

        assert_eq!(nums.len(), 203);

        for x in 0..24 {
            nums.insert(12, x);
        }

        assert_eq!(nums.len(), 227);
    }

    #[test]
    fn test_iter() {
        let v = vec![16, 29, 42, 1992];

        let list: DoublyLinkedList<i32> = v.iter().cloned().collect();

        assert_eq!(list.iter().cloned().collect::<Vec<i32>>(), v);
    }

    #[test]
    fn test_append() {
        let mut a: DoublyLinkedList<i32> = [12, 14, 18, 29, 40].iter().cloned().collect();
        let mut b: DoublyLinkedList<i32> = [18, 20, 38, 48, 19].iter().cloned().collect();

        let mut v: Vec<i32> = Vec::new();

        for &x in a.iter() {
            v.push(x);
        }

        for &x in b.iter() {
            v.push(x);
        }

        a.append(&mut b);

        assert_eq!(b.len(), 0);

        assert_eq!(a.len(), 10);

        assert_eq!(v, a.iter().cloned().collect::<Vec<i32>>());
    }

    #[test]
    fn test_empty() {
        let mut dl = DoublyLinkedList::new();

        assert!(dl.is_empty());

        dl.push_front("string");

        assert!(!dl.is_empty());
    }
}
<commit_msg>fix lifetime issue related to rust-lang/rust PR 38897<commit_after>#![feature(plugin)]
#![plugin(clippy)]

use std::mem;
use std::ptr;
use std::cell::Cell;
use std::ops::Index;
use std::ops::IndexMut;
use std::default::Default;
use std::iter::FromIterator;

unsafe fn as_ref<'a, T>(ptr: *const T) -> Option<&'a T> {
    if ptr.is_null() {
        None
    } else {
        Some(&*ptr)
    }
}

unsafe fn as_mut<'a, T>(ptr: *mut T) -> Option<&'a mut T> {
    if ptr.is_null() {
        None
    } else {
        Some(&mut *ptr)
    }
}

pub struct Iter<'a, T: 'a> {
    next: Option<&'a Node<T>>
}

pub struct IterMut<'a, T: 'a> {
    next: Option<&'a mut Node<T>>
}

struct Node<T> {
    prev:  *mut Node<T>,
    value: T,
    next:  *mut Node<T>
}

pub struct DoublyLinkedList<T> {
    current: Cell<*mut Node<T>>,
    first:   *mut Node<T>,
    last:    *mut Node<T>,
    index:   Cell<isize>,
    length:  usize
}

impl<'a, T> DoublyLinkedList<T> {
    pub fn new() -> DoublyLinkedList<T> {
        DoublyLinkedList {
            current: Cell::new(ptr::null_mut()),
            first:   ptr::null_mut(),
            last:    ptr::null_mut(),
            index:   Cell::new(-1),
            length:  0
        }
    }

    pub fn singleton(v: T) -> DoublyLinkedList<T> {
        unsafe {
            let node = Node::new_on_heap(v);
            DoublyLinkedList {
                current: Cell::new(node),
                first:   node,
                last:    node,
                index:   Cell::new(0),
                length:  1
            }
        }
    }

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

    pub fn is_empty(&self) -> bool {
        self.length == 0
    }

    pub fn front_mut(&mut self) -> Option<&'a mut T> {
        unsafe { as_mut(self.first).map(|n| { &mut n.value }) }
    }

    pub fn front(&self) -> Option<&'a T> {
        unsafe { as_ref(self.first).map(|n| { &n.value }) }
    }

    pub fn back_mut(&mut self) -> Option<&'a mut T> {
        unsafe { as_mut(self.last).map(|n| { &mut n.value }) }
    }

    pub fn back(&self) -> Option<&'a T> {
        unsafe { as_ref(self.last).map(|n| { &n.value }) }
    }

    pub fn iter(&self) -> Iter<'a, T> {
        unsafe {
            Iter {
                next: if self.first.is_null() {
                    None
                } else {
                    Some(&*self.first)
                }
            }
        }
    }

    pub fn iter_mut(&self) -> IterMut<'a, T> {
        unsafe {
            IterMut {
                next: if self.first.is_null() {
                    None
                } else {
                    Some(&mut *self.first)
                }
            }
        }
    }

    pub fn push_back(&mut self, val: T) {
        unsafe {
            if self.length == 0 {
                *self = DoublyLinkedList::singleton(val);
            } else {
                (*(self.last)).next = Node::new_on_heap(val);
                (*(*(self.last)).next).prev = self.last;
                self.last = (*(self.last)).next;
                self.length += 1;
            }
        }
    }

    pub fn push_front(&mut self, val: T) {
        unsafe {
            if self.length == 0 {
                *self = DoublyLinkedList::singleton(val);
            } else {
                (*(self.first)).prev = Node::new_on_heap(val);
                (*(*(self.first)).prev).next = self.first;
                self.first = (*(self.first)).prev;
                self.length += 1;
                self.index.set(self.index.get() + 1);
            }
        }
    }

    fn index(&self, i: usize) -> Option<&'a T> {
        unsafe {
            if i >= self.length {
                None
            } else {
                self.go_to(i);
                Some(&(*self.current.get()).value)
            }
        }
    }

    fn index_mut(&mut self, i: usize) -> Option<&'a mut T> {
        unsafe {
            if i >= self.length {
                None
            } else  {
                self.go_to(i);
                Some(&mut (*self.current.get()).value)
            }
        }
    }

    fn go_to(&self, i: usize) {
        if self.length / 2 > i {
            if (self.index.get() - i as isize).abs() > i as isize {
                self.go_to_from_start(i);
            } else {
                self.go_to_from_current(i);
            }
        } else if (self.index.get() - i as isize).abs() >= (self.length as isize - i as isize).abs() {
            self.go_to_from_end(i);
        } else {
            self.go_to_from_current(i);
        }
    }

    fn go_to_from_current(&self, i: usize) {
        unsafe {
            while (i as isize) > self.index.get() {
                self.current.set((*self.current.get()).next);
                self.index.set(self.index.get() + 1);
            }
            while (i as isize) < self.index.get() {
                self.current.set((*self.current.get()).prev);
                self.index.set(self.index.get() - 1);
            }
        }
    }

    fn go_to_from_start(&self, i: usize) {
        self.current.set(self.first);
        self.index.set(0);
        self.go_to(i);
    }

    fn go_to_from_end(&self, i: usize) {
        self.current.set(self.last);
        self.index.set(self.length as isize - 1);
        self.go_to(i);
    }

    pub fn pop_back(&mut self) -> Option<T> {
        unsafe {
            if self.length == 0 {
                None
            } else {
                let val = ptr::read(&(*self.last).value);
                if self.current.get() == self.last {
                    self.current.set((*self.last).prev);
                    self.index.set(self.index.get() - 1);
                }
                self.length -= 1;
                let old_last = self.last;
                self.last = (*self.last).prev;
                drop(mem::transmute::<_, Box<Node<T>>>(old_last));
                Some(val)
            }
        }
    }

    pub fn pop_front(&mut self) -> Option<T> {
        unsafe {
            if self.length == 0 {
                None
            } else {
                let val = ptr::read(&(*self.first).value);
                if self.current.get() == self.first {
                    self.current.set((*self.first).next);
                }
                self.length -= 1;
                let old_first = self.first;
                self.first = (*self.first).next;
                drop(mem::transmute::<_, Box<Node<T>>>(old_first));
                Some(val)
            }
        }
    }

    pub fn insert(&mut self, i: usize, val: T) {
        if i > self.length {
            panic!("DoublyLinkedList::insert: index out of range");
        } else {
            if self.length == 0 { *self = DoublyLinkedList::singleton(val); return; }
            if i == self.length { self.push_back(val); return; }
            if i == 0           { self.push_front(val); return; }
            unsafe {
                self.go_to(i);
                let new = Node::new_on_heap(val);
                (*new).next = self.current.get();
                (*new).prev = (*self.current.get()).prev;
                (*(*(self.current.get())).prev).next = new;
                (*self.current.get()).prev = new;
                self.current.set(new);
                self.length += 1;
            }
        }
    }

    pub fn remove(&mut self, i: usize) -> T {
        if i >= self.length {
            panic!("DoublyLinkedList::remove: index out of range");
        } else {
            if i == 0 { return self.pop_front().unwrap() }
            if i + 1 == self.length { return self.pop_back().unwrap() }
            unsafe {
                self.go_to(i);

                let val = ptr::read(&(*self.current.get()).value);

                (*(*self.current.get()).next).prev = (*self.current.get()).prev;
                (*(*self.current.get()).prev).next = (*self.current.get()).next;

                let old_node = self.current.get();
                self.current.set((*self.current.get()).next);
                drop(mem::transmute::<_, Box<Node<T>>>(old_node));

                self.length -= 1;

                val
            }
        }
    }

    pub fn append(&mut self, other: &mut DoublyLinkedList<T>) {
        unsafe {
            self.length += other.len();
            (*self.last).next = other.first;
            self.last = other.last;
            *other = Self::new();
        }
    }
}

impl<T> Index<usize> for DoublyLinkedList<T> {
    type Output = T;
    fn index(&self, i: usize) -> &T {
        self.index(i).unwrap()
    }
}

impl<T> IndexMut<usize> for DoublyLinkedList<T> {
    fn index_mut(&mut self, i: usize) -> &mut T {
        self.index_mut(i).unwrap()
    }
}

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

impl<'a, T> Iterator for Iter<'a, T> {
    type Item = &'a T;
    fn next(&mut self) -> Option<Self::Item> {
        unsafe {
            match self.next {
                None => None,
                Some(node) => {
                    let result = node;
                    self.next = if result.next.is_null() {
                        None
                    } else {
                        Some(&*result.next)
                    };

                    return Some(&(*result).value);
                }
            }
        }
    }
}

impl<'a, T> Iterator for IterMut<'a, T> {
    type Item = &'a mut T;
    fn next(&mut self) -> Option<Self::Item> {
        unsafe {
            match self.next.take() {
                None => None,
                Some(node) => {
                    let result = node;
                    self.next = if result.next.is_null() {
                        None
                    } else {
                        Some(&mut *result.next)
                    };

                    return Some(&mut (*result).value);
                }
            }
        }
    }
}

impl<T> FromIterator<T> for DoublyLinkedList<T> {
    fn from_iter<A>(iterator: A) -> Self where A: IntoIterator<Item=T> {
        let mut list = Self::new();

        for x in iterator {
            list.push_back(x);
        }

        return list;
    }
}

impl<T> Node<T> {
    fn new(v: T) -> Node<T> {
        Node {
            prev: ptr::null_mut(),
            value: v,
            next: ptr::null_mut()
        }
    }

    unsafe fn new_on_heap(v: T) -> *mut Node<T> {
        let node = Box::new(Node::new(v));
        let node: *mut Node<T> = mem::transmute(node);
        return node;
    }
}

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

    #[test]
    fn test_list() {
        let mut nums = DoublyLinkedList::singleton(5i32);
        assert_eq!(5i32, *nums.back().unwrap());
        assert_eq!(nums.len(), 1);
        nums.push_front(7i32);
        assert_eq!(nums.len(), 2);
        assert_eq!(7i32, *nums.front().unwrap());
        nums.push_front(9i32);
        nums.push_front(6i32);
        assert_eq!(5i32, *nums.index(3).unwrap());
        nums.push_back(10i32);
        assert_eq!(5i32, *nums.index(3).unwrap());
    }

    #[test]
    fn test_len() {
        let mut nums = DoublyLinkedList::singleton(4i32);

        for x in 0..100 { nums.push_front(x); }

        assert_eq!(101, nums.len());

        for x in 0..100 { nums.push_back(x); }

        assert_eq!(201, nums.len());

        nums.insert(40, 8);

        assert_eq!(202, nums.len());

        nums.insert(200, 56);

        assert_eq!(nums.len(), 203);

        for x in 0..24 {
            nums.insert(12, x);
        }

        assert_eq!(nums.len(), 227);
    }

    #[test]
    fn test_iter() {
        let v = vec![16, 29, 42, 1992];

        let list: DoublyLinkedList<i32> = v.iter().cloned().collect();

        assert_eq!(list.iter().cloned().collect::<Vec<i32>>(), v);
    }

    #[test]
    fn test_append() {
        let mut a: DoublyLinkedList<i32> = [12, 14, 18, 29, 40].iter().cloned().collect();
        let mut b: DoublyLinkedList<i32> = [18, 20, 38, 48, 19].iter().cloned().collect();

        let mut v: Vec<i32> = Vec::new();

        for &x in a.iter() {
            v.push(x);
        }

        for &x in b.iter() {
            v.push(x);
        }

        a.append(&mut b);

        assert_eq!(b.len(), 0);

        assert_eq!(a.len(), 10);

        assert_eq!(v, a.iter().cloned().collect::<Vec<i32>>());
    }

    #[test]
    fn test_empty() {
        let mut dl = DoublyLinkedList::new();

        assert!(dl.is_empty());

        dl.push_front("string");

        assert!(!dl.is_empty());
    }
}
<|endoftext|>