<commit_before>use std::sync::Arc;
use std::io;

use futures::{Future, Poll};
use futures::task;
use futures::executor::Executor;

use event_loop::{Message, Loop, LoopPin, LoopHandle, LoopFuture};
use self::dropbox::DropBox;

/// A handle to data that is owned by an event loop thread, and is only
/// accessible on that thread itself.
///
/// This structure is created by the `LoopHandle::add_loop_data` method which
/// will return a future resolving to one of these references. A `LoopData<A>`
/// handle is `Send` regardless of what `A` is, but the internal data can only
/// be accessed on the event loop thread itself.
///
/// Internally this reference also stores a handle to the event loop that the
/// data originated on, so it knows how to go back to the event loop to access
/// the data itself.
// TODO: write more once it's implemented
pub struct LoopData {
    data: DropBox,
    handle: LoopHandle,
}

pub struct Opaque {
    _inner: DropBox<dropbox::MyDrop>,
}

/// Future returned from the `LoopHandle::add_loop_data` method.
///
/// This future will resolve to a `LoopData<A>` reference when completed, which
/// represents a handle to data that is "owned" by the event loop thread but can
/// migrate among threads temporarily so travel with a future itself.
pub struct AddLoopData<F, A> {
    inner: LoopFuture<DropBox, F>,
}

fn _assert() {
    fn _assert_send<T: Send>() {}
    _assert_send::<LoopData<()>>();
}

impl Loop {
    /// Creates a new `LoopData<A>` handle by associating data to be directly
    /// stored by this event loop.
    ///
    /// This function is useful for when storing non-`Send` data inside of a
    /// future. The `LoopData<A>` handle is itself `Send + 'static` regardless
    /// of the underlying `A`. That is, for example, you can create a handle to
    /// some data that contains an `Rc`, for example.
    pub fn add_loop_data(&self, a: A) -> LoopData
        where A: 'static,
    {
        self.pin().add_loop_data(a)
    }
}

impl LoopPin {
    /// Adds some data to the event loop this pin is associated with.
    ///
    /// This method will return a handle to the data, `LoopData`, which can be
    /// used to access the underlying data whenever it's on the correct event
    /// loop thread.
    pub fn add_loop_data(&self, a: A) -> LoopData
        where A: 'static,
    {
        LoopData {
            data: DropBox::new_on(a, self),
            handle: self.handle.clone(),
        }
    }
}

impl LoopHandle {

    /// Schedules a closure to add some data to event loop thread itself.
    ///
    /// This function is useful for when storing non-`Send` data inside of a
    /// future. This returns a future which will resolve to a `LoopData<A>`
    /// handle, which is itself `Send + 'static` regardless of the underlying
    /// `A`. That is, for example, you can create a handle to some data that
    /// contains an `Rc`, for example.
    ///
    /// This function takes a closure which may be sent to the event loop to
    /// generate an instance of type `A`. The closure itself is required to be
    /// `Send + 'static`, but the data it produces is only required to adhere to
    /// `'static`.
    ///
    /// If the returned future is polled on the event loop thread itself it will
    /// very cheaply resolve to a handle to the data, but if it's not polled on
    /// the event loop then it will send a message to the event loop to run the
    /// closure `f`, generate a handle, and then the future will yield it back.
    // TODO: more with examples
    pub fn add_loop_data<F, A>(&self, f: F) -> AddLoopData<F, A>
        where F: FnOnce(&LoopPin) -> A + Send + 'static,
              A: 'static,
    {
        AddLoopData {
            inner: LoopFuture {
                loop_handle: self.clone(),
                data: Some(f),
                result: None,
            },
        }
    }
}

impl<F, A> Future for AddLoopData<F, A>
    where F: FnOnce(&LoopPin) -> A + Send + 'static,
          A: 'static,
{
    type Item = LoopData;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<LoopData, io::Error> {
        let ret = self.inner.poll(|lp, f| {
            Ok(DropBox::new(f(&lp.pin())))
        }, |f, slot| {
            Message::Run(Box::new(move || {
                let pin = super::CURRENT_LOOP.with(|lp| lp.pin());
                slot.try_produce(Ok(DropBox::new(f(&pin)))).ok()
                    .expect("add loop data try_produce intereference");
            }))
        });

        ret.map(|data| {
            LoopData {
                data: data,
                handle: self.inner.loop_handle.clone(),
            }
        })
    }
}

impl LoopData {
    /// Gets a shared reference to the underlying data in this handle.
    ///
    /// Returns `None` if it is not called from the event loop thread that this
    /// `LoopData<A>` is associated with, or `Some` with a reference to the data
    /// if we are indeed on the event loop thread.
    pub fn get(&self) -> Option<&A> {
        self.data.get()
    }

    /// Gets a mutable reference to the underlying data in this handle.
    ///
    /// Returns `None` if it is not called from the event loop thread that this
    /// `LoopData<A>` is associated with, or `Some` with a reference to the data
    /// if we are indeed on the event loop thread.
    pub fn get_mut(&mut self) -> Option<&mut A> {
        self.data.get_mut()
    }

    /// Acquire the executor associated with the thread that owns this
    /// `LoopData<A>`'s data.
    ///
    /// If the `get` and `get_mut` functions above return `None`, then this data
    /// is being polled on the wrong thread to access the data, and to make
    /// progress a future may need to migrate to the actual thread which owns
    /// the relevant data.
    ///
    /// This executor can in turn be passed to `Task::poll_on`, which will then
    /// move the entire future to be polled on the right thread.
    pub fn executor(&self) -> Arc<Executor> {
        self.handle.tx.clone()
    }

    /// Returns a reference to the handle that this data is bound to.
    pub fn loop_handle(&self) -> &LoopHandle {
        &self.handle
    }
}

impl Future for LoopData {
    type Item = A::Item;
    type Error = A::Error;

    fn poll(&mut self) -> Poll {
        // If we're on the right thread, then we can proceed. Otherwise we need
        // to go and get polled on the right thread.
        if let Some(inner) = self.get_mut() {
            return inner.poll()
        }
        task::poll_on(self.executor());
        Poll::NotReady
    }
}

impl Drop for LoopData {
    fn drop(&mut self) {
        // The `DropBox` we store internally will cause a memory leak if it's
        // dropped on the wrong thread. While necessary for safety, we don't
        // actually want a memory leak, so for all normal circumstances we take
        // out the `DropBox<A>` as a `DropBox<MyDrop>` and then we send it off
        // to the event loop.
        //
        // TODO: possible optimization is to do none of this if we're on the
        //       event loop thread itself
        if let Some(data) = self.data.take() {
            self.handle.send(Message::Drop(Opaque { _inner: data }));
        }
    }
}

/// A curious inner module with one `unsafe` keyword, yet quite an important
/// one!
///
/// The purpose of this module is to define a type, `DropBox<A>`, which is able
/// to be sent across thread event when the underlying data `A` is itself not
/// sendable across threads. This is then in turn used to build up the
/// `LoopData` abstraction above.
///
/// A `DropBox` currently contains two major components, an identification of
/// the thread that it originated from as well as the data itself. Right now the
/// data is stored in a `Box` as we'll transition between it and `Box<MyDrop>`,
/// but this is perhaps optimizable.
///
/// The `DropBox<A>` itself only provides a few safe methods, all of which are
/// safe to call from any thread. Access to the underlying data is only granted
/// if we're on the right thread, and otherwise the methods don't access the
/// data itself.
///
/// Finally, one crucial piece, if the data is dropped it may run code that
/// assumes it's on the original thread. For this reason we have to be sure that
/// the data is only dropped on the originating thread itself. It's currently
/// the job of the outer `LoopData` to ensure that a `DropBox` is dropped on the
/// right thread, so we don't attempt to perform any communication in this
/// `Drop` implementation. Instead, if a `DropBox` is dropped on the wrong
/// thread, it simply leaks its contents.
///
/// All that's really just a lot of words in an attempt to justify the `unsafe`
/// impl of `Send` below. The idea is that the data is only ever accessed on the
/// originating thread, even during `Drop`.
///
/// Note that this is a private module to have a visibility boundary around the
/// unsafe internals. Although there's not any unsafe blocks here, the code
/// itself is quite unsafe as it has to make sure that the data is dropped in
/// the right place, if ever.
mod dropbox {
    use std::mem;
    use event_loop::{CURRENT_LOOP, LoopPin};

    pub struct DropBox {
        id: usize,
        inner: Option<Box>,
    }

    // We can be sent across threads due to the comment above
    unsafe impl Send for DropBox {}

    // We can also be shared across threads just fine as we'll only ever get a
    // reference on at most one thread, regardless of `A`.
    unsafe impl Sync for DropBox {}

    pub trait MyDrop {}
    impl<T: ?Sized> MyDrop for T {}

    impl DropBox {
        /// Creates a new `DropBox` pinned to the current threads.
        ///
        /// Will panic if `CURRENT_LOOP` isn't set.
        pub fn new(a: A) -> DropBox {
            DropBox {
                id: CURRENT_LOOP.with(|lp| lp.id),
                inner: Some(Box::new(a)),
            }
        }

        /// Creates a new `DropBox` pinned to the thread of `LoopPin`.
        pub fn new_on(a: A, lp: &LoopPin) -> DropBox {
            DropBox {
                id: lp.handle.id,
                inner: Some(Box::new(a)),
            }
        }

        /// Consumes the contents of this `DropBox<A>`, returning a new
        /// `DropBox<MyDrop>`.
        ///
        /// This is just intended to be a simple and cheap conversion, should
        /// almost always return `Some`.
        pub fn take<'a>(&mut self) -> Option<DropBox<MyDrop + 'a>>
            where A: 'a
        {
            self.inner.take().map(|d| {
                DropBox { id: self.id, inner: Some(d as Box<MyDrop + 'a>) }
            })
        }
    }

    impl DropBox {
        /// Returns a shared reference to the data if we're on the right
        /// thread.
        pub fn get(&self) -> Option<&A> {
            if CURRENT_LOOP.is_set() {
                CURRENT_LOOP.with(|lp| {
                    if lp.id == self.id {
                        self.inner.as_ref().map(|b| &**b)
                    } else {
                        None
                    }
                })
            } else {
                None
            }
        }

        /// Returns a mutable reference to the data if we're on the right
        /// thread.
        pub fn get_mut(&mut self) -> Option<&mut A> {
            if CURRENT_LOOP.is_set() {
                CURRENT_LOOP.with(move |lp| {
                    if lp.id == self.id {
                        self.inner.as_mut().map(|b| &mut **b)
                    } else {
                        None
                    }
                })
            } else {
                None
            }
        }
    }

    impl Drop for DropBox {
        fn drop(&mut self) {
            // Try our safe accessor first, and if it works then we know that
            // we're on the right thread. In that case we can simply drop as
            // usual.
            if let Some(a) = self.get_mut().take() {
                return drop(a)
            }

            // If we're on the wrong thread but we actually have some data, then
            // something in theory horrible has gone awry. Prevent memory safety
            // issues by forgetting the data and then also warn about this odd
            // event.
            if let Some(data) = self.inner.take() {
                mem::forget(data);
                warn!("forgetting some data on an event loop");
            }
        }
    }
}

<commit_msg>Fix DropBox's drop<commit_after>use std::sync::Arc;
use std::io;

use futures::{Future, Poll};
use futures::task;
use futures::executor::Executor;

use event_loop::{Message, Loop, LoopPin, LoopHandle, LoopFuture};
use self::dropbox::DropBox;

/// A handle to data that is owned by an event loop thread, and is only
/// accessible on that thread itself.
///
/// This structure is created by the `LoopHandle::add_loop_data` method which
/// will return a future resolving to one of these references. A `LoopData<A>`
/// handle is `Send` regardless of what `A` is, but the internal data can only
/// be accessed on the event loop thread itself.
///
/// Internally this reference also stores a handle to the event loop that the
/// data originated on, so it knows how to go back to the event loop to access
/// the data itself.
// TODO: write more once it's implemented
pub struct LoopData {
    data: DropBox,
    handle: LoopHandle,
}

pub struct Opaque {
    _inner: DropBox<dropbox::MyDrop>,
}

/// Future returned from the `LoopHandle::add_loop_data` method.
///
/// This future will resolve to a `LoopData<A>` reference when completed, which
/// represents a handle to data that is "owned" by the event loop thread but can
/// migrate among threads temporarily so travel with a future itself.
pub struct AddLoopData<F, A> {
    inner: LoopFuture<DropBox, F>,
}

fn _assert() {
    fn _assert_send<T: Send>() {}
    _assert_send::<LoopData<()>>();
}

impl Loop {
    /// Creates a new `LoopData<A>` handle by associating data to be directly
    /// stored by this event loop.
    ///
    /// This function is useful for when storing non-`Send` data inside of a
    /// future. The `LoopData<A>` handle is itself `Send + 'static` regardless
    /// of the underlying `A`. That is, for example, you can create a handle to
    /// some data that contains an `Rc`, for example.
    pub fn add_loop_data(&self, a: A) -> LoopData
        where A: 'static,
    {
        self.pin().add_loop_data(a)
    }
}

impl LoopPin {
    /// Adds some data to the event loop this pin is associated with.
    ///
    /// This method will return a handle to the data, `LoopData`, which can be
    /// used to access the underlying data whenever it's on the correct event
    /// loop thread.
    pub fn add_loop_data(&self, a: A) -> LoopData
        where A: 'static,
    {
        LoopData {
            data: DropBox::new_on(a, self),
            handle: self.handle.clone(),
        }
    }
}

impl LoopHandle {

    /// Schedules a closure to add some data to event loop thread itself.
    ///
    /// This function is useful for when storing non-`Send` data inside of a
    /// future. This returns a future which will resolve to a `LoopData<A>`
    /// handle, which is itself `Send + 'static` regardless of the underlying
    /// `A`. That is, for example, you can create a handle to some data that
    /// contains an `Rc`, for example.
    ///
    /// This function takes a closure which may be sent to the event loop to
    /// generate an instance of type `A`. The closure itself is required to be
    /// `Send + 'static`, but the data it produces is only required to adhere to
    /// `'static`.
    ///
    /// If the returned future is polled on the event loop thread itself it will
    /// very cheaply resolve to a handle to the data, but if it's not polled on
    /// the event loop then it will send a message to the event loop to run the
    /// closure `f`, generate a handle, and then the future will yield it back.
    // TODO: more with examples
    pub fn add_loop_data<F, A>(&self, f: F) -> AddLoopData<F, A>
        where F: FnOnce(&LoopPin) -> A + Send + 'static,
              A: 'static,
    {
        AddLoopData {
            inner: LoopFuture {
                loop_handle: self.clone(),
                data: Some(f),
                result: None,
            },
        }
    }
}

impl<F, A> Future for AddLoopData<F, A>
    where F: FnOnce(&LoopPin) -> A + Send + 'static,
          A: 'static,
{
    type Item = LoopData;
    type Error = io::Error;

    fn poll(&mut self) -> Poll<LoopData, io::Error> {
        let ret = self.inner.poll(|lp, f| {
            Ok(DropBox::new(f(&lp.pin())))
        }, |f, slot| {
            Message::Run(Box::new(move || {
                let pin = super::CURRENT_LOOP.with(|lp| lp.pin());
                slot.try_produce(Ok(DropBox::new(f(&pin)))).ok()
                    .expect("add loop data try_produce intereference");
            }))
        });

        ret.map(|data| {
            LoopData {
                data: data,
                handle: self.inner.loop_handle.clone(),
            }
        })
    }
}

impl LoopData {
    /// Gets a shared reference to the underlying data in this handle.
    ///
    /// Returns `None` if it is not called from the event loop thread that this
    /// `LoopData<A>` is associated with, or `Some` with a reference to the data
    /// if we are indeed on the event loop thread.
    pub fn get(&self) -> Option<&A> {
        self.data.get()
    }

    /// Gets a mutable reference to the underlying data in this handle.
    ///
    /// Returns `None` if it is not called from the event loop thread that this
    /// `LoopData<A>` is associated with, or `Some` with a reference to the data
    /// if we are indeed on the event loop thread.
    pub fn get_mut(&mut self) -> Option<&mut A> {
        self.data.get_mut()
    }

    /// Acquire the executor associated with the thread that owns this
    /// `LoopData<A>`'s data.
    ///
    /// If the `get` and `get_mut` functions above return `None`, then this data
    /// is being polled on the wrong thread to access the data, and to make
    /// progress a future may need to migrate to the actual thread which owns
    /// the relevant data.
    ///
    /// This executor can in turn be passed to `Task::poll_on`, which will then
    /// move the entire future to be polled on the right thread.
    pub fn executor(&self) -> Arc<Executor> {
        self.handle.tx.clone()
    }

    /// Returns a reference to the handle that this data is bound to.
    pub fn loop_handle(&self) -> &LoopHandle {
        &self.handle
    }
}

impl Future for LoopData {
    type Item = A::Item;
    type Error = A::Error;

    fn poll(&mut self) -> Poll {
        // If we're on the right thread, then we can proceed. Otherwise we need
        // to go and get polled on the right thread.
        if let Some(inner) = self.get_mut() {
            return inner.poll()
        }
        task::poll_on(self.executor());
        Poll::NotReady
    }
}

impl Drop for LoopData {
    fn drop(&mut self) {
        // The `DropBox` we store internally will cause a memory leak if it's
        // dropped on the wrong thread. While necessary for safety, we don't
        // actually want a memory leak, so for all normal circumstances we take
        // out the `DropBox<A>` as a `DropBox<MyDrop>` and then we send it off
        // to the event loop.
        //
        // TODO: possible optimization is to do none of this if we're on the
        //       event loop thread itself
        if let Some(data) = self.data.take() {
            self.handle.send(Message::Drop(Opaque { _inner: data }));
        }
    }
}

/// A curious inner module with one `unsafe` keyword, yet quite an important
/// one!
///
/// The purpose of this module is to define a type, `DropBox<A>`, which is able
/// to be sent across thread event when the underlying data `A` is itself not
/// sendable across threads. This is then in turn used to build up the
/// `LoopData` abstraction above.
///
/// A `DropBox` currently contains two major components, an identification of
/// the thread that it originated from as well as the data itself. Right now the
/// data is stored in a `Box` as we'll transition between it and `Box<MyDrop>`,
/// but this is perhaps optimizable.
///
/// The `DropBox<A>` itself only provides a few safe methods, all of which are
/// safe to call from any thread. Access to the underlying data is only granted
/// if we're on the right thread, and otherwise the methods don't access the
/// data itself.
///
/// Finally, one crucial piece, if the data is dropped it may run code that
/// assumes it's on the original thread. For this reason we have to be sure that
/// the data is only dropped on the originating thread itself. It's currently
/// the job of the outer `LoopData` to ensure that a `DropBox` is dropped on the
/// right thread, so we don't attempt to perform any communication in this
/// `Drop` implementation. Instead, if a `DropBox` is dropped on the wrong
/// thread, it simply leaks its contents.
///
/// All that's really just a lot of words in an attempt to justify the `unsafe`
/// impl of `Send` below. The idea is that the data is only ever accessed on the
/// originating thread, even during `Drop`.
///
/// Note that this is a private module to have a visibility boundary around the
/// unsafe internals. Although there's not any unsafe blocks here, the code
/// itself is quite unsafe as it has to make sure that the data is dropped in
/// the right place, if ever.
mod dropbox {
    use std::mem;
    use event_loop::{CURRENT_LOOP, LoopPin};

    pub struct DropBox {
        id: usize,
        inner: Option<Box>,
    }

    // We can be sent across threads due to the comment above
    unsafe impl Send for DropBox {}

    // We can also be shared across threads just fine as we'll only ever get a
    // reference on at most one thread, regardless of `A`.
    unsafe impl Sync for DropBox {}

    pub trait MyDrop {}
    impl<T: ?Sized> MyDrop for T {}

    impl DropBox {
        /// Creates a new `DropBox` pinned to the current threads.
        ///
        /// Will panic if `CURRENT_LOOP` isn't set.
        pub fn new(a: A) -> DropBox {
            DropBox {
                id: CURRENT_LOOP.with(|lp| lp.id),
                inner: Some(Box::new(a)),
            }
        }

        /// Creates a new `DropBox` pinned to the thread of `LoopPin`.
        pub fn new_on(a: A, lp: &LoopPin) -> DropBox {
            DropBox {
                id: lp.handle.id,
                inner: Some(Box::new(a)),
            }
        }

        /// Consumes the contents of this `DropBox<A>`, returning a new
        /// `DropBox<MyDrop>`.
        ///
        /// This is just intended to be a simple and cheap conversion, should
        /// almost always return `Some`.
        pub fn take<'a>(&mut self) -> Option<DropBox<MyDrop + 'a>>
            where A: 'a
        {
            self.inner.take().map(|d| {
                DropBox { id: self.id, inner: Some(d as Box<MyDrop + 'a>) }
            })
        }
    }

    impl DropBox {
        /// Returns a shared reference to the data if we're on the right
        /// thread.
        pub fn get(&self) -> Option<&A> {
            if CURRENT_LOOP.is_set() {
                CURRENT_LOOP.with(|lp| {
                    if lp.id == self.id {
                        self.inner.as_ref().map(|b| &**b)
                    } else {
                        None
                    }
                })
            } else {
                None
            }
        }

        /// Returns a mutable reference to the data if we're on the right
        /// thread.
        pub fn get_mut(&mut self) -> Option<&mut A> {
            if CURRENT_LOOP.is_set() {
                CURRENT_LOOP.with(move |lp| {
                    if lp.id == self.id {
                        self.inner.as_mut().map(|b| &mut **b)
                    } else {
                        None
                    }
                })
            } else {
                None
            }
        }
    }

    impl Drop for DropBox {
        fn drop(&mut self) {
            // Try our safe accessor first, and if it works then we know that
            // we're on the right thread. In that case we can simply drop as
            // usual.
            if self.get().is_some() {
                drop(self.inner.take().unwrap());
                return;
            }

            // If we're on the wrong thread but we actually have some data, then
            // something in theory horrible has gone awry. Prevent memory safety
            // issues by forgetting the data and then also warn about this odd
            // event.
            if let Some(data) = self.inner.take() {
                mem::forget(data);
                warn!("forgetting some data on an event loop");
            }
        }
    }
}
<|endoftext|>


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

use std::collections::HashMap;

use futures::{Future, Async, Poll};

use auth;
use error;
use error::Error::BadUrl;
use links;
use common::*;

use super::*;
use super::PlaceQuery;

///Load the place with the given ID.
///
///## Examples
///
///```rust,no_run
///# let token = egg_mode::Token::Access {
///#     consumer: egg_mode::KeyPair::new("", ""),
///#     access: egg_mode::KeyPair::new("", ""),
///# };
///let result = egg_mode::place::show("18810aa5b43e76c7", &token).unwrap();
///
///assert!(result.full_name == "Dallas, TX");
///```
pub fn show<'a>(id: &str, token: &auth::Token, handle: &'a Handle) -> FutureResponse<'a, Place> {
    let url = format!("{}/{}.json", links::place::SHOW_STEM, id);

    let req = auth::get(&url, token, None);

    make_parsed_future(handle, req)
}

///Begins building a reverse-geocode search with the given coordinate.
///
///## Examples
///
///```rust,no_run
///# let token = egg_mode::Token::Access {
///#     consumer: egg_mode::KeyPair::new("", ""),
///#     access: egg_mode::KeyPair::new("", ""),
///# };
///use egg_mode::place::{self, PlaceType};
///let result = place::reverse_geocode(51.507222, -0.1275)
///                   .granularity(PlaceType::City)
///                   .call(&token)
///                   .unwrap();
///
///assert!(result.results.iter().any(|pl| pl.full_name == "London, England"));
///```
pub fn reverse_geocode(latitude: f64, longitude: f64) -> GeocodeBuilder
{
    GeocodeBuilder::new(latitude, longitude)
}

fn parse_url<'a>(base: &'static str, full: &'a str) -> Result<ParamList<'a>, error::Error> {
    let mut iter = full.split('?');

    if let Some(base_part) = iter.next() {
        if base_part != base {
            return Err(BadUrl);
        }
    }
    else {
        return Err(BadUrl);
    }

    if let Some(list) = iter.next() {
        let mut p = HashMap::new();

        for item in list.split('&') {
            let mut kv_iter = item.split('=');

            let k = try!(kv_iter.next().ok_or(BadUrl));
            let v = try!(kv_iter.next().ok_or(BadUrl));

            add_param(&mut p, k, v);
        }

        Ok(p)
    }
    else {
        Err(BadUrl)
    }
}

///From a URL given with the result of `reverse_geocode`, perform the same reverse-geocode search.
///
///## Errors
///
///In addition to errors that might occur generally, this function will return a `BadUrl` error if
///the given URL is not a valid `reverse_geocode` query URL.
pub fn reverse_geocode_url<'a>(url: &'a str, token: &'a auth::Token, handle: &'a Handle)
    -> CachedSearchFuture<'a>
{
    let params = parse_url(links::place::REVERSE_GEOCODE, url);
    CachedSearchFuture::new(links::place::REVERSE_GEOCODE, token, handle, params)
}

///Begins building a location search via latitude/longitude.
///
///## Example
///
///```rust,no_run
///# let token = egg_mode::Token::Access {
///#     consumer: egg_mode::KeyPair::new("", ""),
///#     access: egg_mode::KeyPair::new("", ""),
///# };
///use egg_mode::place::{self, PlaceType};
///let result = place::search_point(51.507222, -0.1275)
///                   .granularity(PlaceType::City)
///                   .call(&token)
///                   .unwrap();
///
///assert!(result.results.iter().any(|pl| pl.full_name == "London, England"));
///```
pub fn search_point(latitude: f64, longitude: f64) -> SearchBuilder<'static> {
    SearchBuilder::new(PlaceQuery::LatLon(latitude, longitude))
}

///Begins building a location search via a text query.
///
///## Example
///
///```rust,no_run
///# let token = egg_mode::Token::Access {
///#     consumer: egg_mode::KeyPair::new("", ""),
///#     access: egg_mode::KeyPair::new("", ""),
///# };
///use egg_mode::place::{self, PlaceType};
///let result = place::search_query("columbia")
///                   .granularity(PlaceType::Admin)
///                   .call(&token)
///                   .unwrap();
///
///assert!(result.results.iter().any(|pl| pl.full_name == "British Columbia, Canada"));
///```
pub fn search_query<'a>(query: &'a str) -> SearchBuilder<'a> {
    SearchBuilder::new(PlaceQuery::Query(query))
}

///Begins building a location search via an IP address.
pub fn search_ip<'a>(query: &'a str) -> SearchBuilder<'a> {
    SearchBuilder::new(PlaceQuery::IPAddress(query))
}

///From a URL given with the result of any `search_*` function, perform the same location search.
///
///## Errors
///
///In addition to errors that might occur generally, this function will return a `BadUrl` error if
///the given URL is not a valid `search` query URL.
pub fn search_url<'a>(url: &'a str, token: &'a auth::Token, handle: &'a Handle)
    -> CachedSearchFuture<'a>
{
    let params = parse_url(links::place::SEARCH, url);
    CachedSearchFuture::new(links::place::SEARCH, token, handle, params)
}

/// A `TwitterFuture` that needs to parse a provided URL before making a request.
///
/// This is a special case of [`TwitterFuture`] returned by [`reverse_geocode_url`] and
/// [`search_url`] so it can parse the cached search URL and return an error before making a web
/// request. See the docs for `TwitterFuture` for details.
///
/// [`TwitterFuture`]: ../struct.TwitterFuture.html
/// [`reverse_geocode_url`]: fn.reverse_geocode_url.html
/// [`search_url`]: fn search_url.html
pub struct CachedSearchFuture<'a> {
    stem: &'static str,
    params: Option<Result<ParamList<'a>, error::Error>>,
    token: &'a auth::Token,
    handle: &'a Handle,
    future: Option<FutureResponse<'a, SearchResult>>,
}

impl<'a> CachedSearchFuture<'a> {
    fn new(stem: &'static str,
           token: &'a auth::Token,
           handle: &'a Handle,
           params: Result<ParamList<'a>, error::Error>)
        -> CachedSearchFuture<'a>
    {
        CachedSearchFuture {
            stem: stem,
            params: Some(params),
            token: token,
            handle: handle,
            future: None,
        }
    }
}

impl<'a> Future for CachedSearchFuture<'a> {
    type Item = Response<SearchResult>;
    type Error = error::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        match self.params.take() {
            Some(Ok(params)) => {
                let req = auth::get(self.stem, self.token, Some(&params));

                self.future = Some(make_parsed_future(self.handle, req));
            }
            Some(Err(e)) => {
                return Err(e);
            }
            None => { }
        }

        if let Some(mut fut) = self.future.take() {
            match fut.poll() {
                Ok(Async::NotReady) => {
                    self.future = Some(fut);
                    Ok(Async::NotReady)
                }
                Ok(Async::Ready(res)) => Ok(Async::Ready(res)),
                Err(e) => Err(e),
            }
        } else {
            Err(error::Error::FutureAlreadyCompleted)
        }
    }
}
<commit_msg>update place docs<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::collections::HashMap;

use futures::{Future, Async, Poll};

use auth;
use error;
use error::Error::BadUrl;
use links;
use common::*;

use super::*;
use super::PlaceQuery;

/// Load the place with the given ID.
///
/// ## Examples
///
/// ```rust,no_run
/// # extern crate egg_mode; extern crate tokio_core; extern crate futures;
/// # use egg_mode::Token; use tokio_core::reactor::{Core, Handle};
/// # fn main() {
/// # let (token, mut core, handle): (Token, Core, Handle) = unimplemented!();
/// let result = core.run(egg_mode::place::show("18810aa5b43e76c7", &token, &handle)).unwrap();
///
/// assert!(result.full_name == "Dallas, TX");
/// # }
/// ```
pub fn show<'a>(id: &str, token: &auth::Token, handle: &'a Handle) -> FutureResponse<'a, Place> {
    let url = format!("{}/{}.json", links::place::SHOW_STEM, id);

    let req = auth::get(&url, token, None);

    make_parsed_future(handle, req)
}

/// Begins building a reverse-geocode search with the given coordinate.
///
/// ## Examples
///
/// ```rust,no_run
/// # extern crate egg_mode; extern crate tokio_core; extern crate futures;
/// # use egg_mode::Token; use tokio_core::reactor::{Core, Handle};
/// # fn main() {
/// # let (token, mut core, handle): (Token, Core, Handle) = unimplemented!();
/// use egg_mode::place::{self, PlaceType};
/// let result = core.run(place::reverse_geocode(51.507222, -0.1275)
///                             .granularity(PlaceType::City)
///                             .call(&token, &handle))
///                  .unwrap();
///
/// assert!(result.results.iter().any(|pl| pl.full_name == "London, England"));
/// # }
/// ```
pub fn reverse_geocode(latitude: f64, longitude: f64) -> GeocodeBuilder
{
    GeocodeBuilder::new(latitude, longitude)
}

fn parse_url<'a>(base: &'static str, full: &'a str) -> Result<ParamList<'a>, error::Error> {
    let mut iter = full.split('?');

    if let Some(base_part) = iter.next() {
        if base_part != base {
            return Err(BadUrl);
        }
    }
    else {
        return Err(BadUrl);
    }

    if let Some(list) = iter.next() {
        let mut p = HashMap::new();

        for item in list.split('&') {
            let mut kv_iter = item.split('=');

            let k = try!(kv_iter.next().ok_or(BadUrl));
            let v = try!(kv_iter.next().ok_or(BadUrl));

            add_param(&mut p, k, v);
        }

        Ok(p)
    }
    else {
        Err(BadUrl)
    }
}

///From a URL given with the result of `reverse_geocode`, perform the same reverse-geocode search.
///
///## Errors
///
///In addition to errors that might occur generally, this function will return a `BadUrl` error if
///the given URL is not a valid `reverse_geocode` query URL.
pub fn reverse_geocode_url<'a>(url: &'a str, token: &'a auth::Token, handle: &'a Handle)
    -> CachedSearchFuture<'a>
{
    let params = parse_url(links::place::REVERSE_GEOCODE, url);
    CachedSearchFuture::new(links::place::REVERSE_GEOCODE, token, handle, params)
}

/// Begins building a location search via latitude/longitude.
///
/// ## Example
///
/// ```rust,no_run
/// # extern crate egg_mode; extern crate tokio_core; extern crate futures;
/// # use egg_mode::Token; use tokio_core::reactor::{Core, Handle};
/// # fn main() {
/// # let (token, mut core, handle): (Token, Core, Handle) = unimplemented!();
/// use egg_mode::place::{self, PlaceType};
/// let result = core.run(place::search_point(51.507222, -0.1275)
///                             .granularity(PlaceType::City)
///                             .call(&token, &handle))
///                  .unwrap();
///
/// assert!(result.results.iter().any(|pl| pl.full_name == "London, England"));
/// # }
/// ```
pub fn search_point(latitude: f64, longitude: f64) -> SearchBuilder<'static> {
    SearchBuilder::new(PlaceQuery::LatLon(latitude, longitude))
}

/// Begins building a location search via a text query.
///
/// ## Example
///
/// ```rust,no_run
/// # extern crate egg_mode; extern crate tokio_core; extern crate futures;
/// # use egg_mode::Token; use tokio_core::reactor::{Core, Handle};
/// # fn main() {
/// # let (token, mut core, handle): (Token, Core, Handle) = unimplemented!();
/// use egg_mode::place::{self, PlaceType};
/// let result = core.run(place::search_query("columbia")
///                             .granularity(PlaceType::Admin)
///                             .call(&token, &handle))
///                  .unwrap();
///
/// assert!(result.results.iter().any(|pl| pl.full_name == "British Columbia, Canada"));
/// # }
/// ```
pub fn search_query<'a>(query: &'a str) -> SearchBuilder<'a> {
    SearchBuilder::new(PlaceQuery::Query(query))
}

///Begins building a location search via an IP address.
pub fn search_ip<'a>(query: &'a str) -> SearchBuilder<'a> {
    SearchBuilder::new(PlaceQuery::IPAddress(query))
}

///From a URL given with the result of any `search_*` function, perform the same location search.
///
///## Errors
///
///In addition to errors that might occur generally, this function will return a `BadUrl` error if
///the given URL is not a valid `search` query URL.
pub fn search_url<'a>(url: &'a str, token: &'a auth::Token, handle: &'a Handle)
    -> CachedSearchFuture<'a>
{
    let params = parse_url(links::place::SEARCH, url);
    CachedSearchFuture::new(links::place::SEARCH, token, handle, params)
}

/// A `TwitterFuture` that needs to parse a provided URL before making a request.
///
/// This is a special case of [`TwitterFuture`] returned by [`reverse_geocode_url`] and
/// [`search_url`] so it can parse the cached search URL and return an error before making a web
/// request. See the docs for `TwitterFuture` for details.
///
/// [`TwitterFuture`]: ../struct.TwitterFuture.html
/// [`reverse_geocode_url`]: fn.reverse_geocode_url.html
/// [`search_url`]: fn search_url.html
pub struct CachedSearchFuture<'a> {
    stem: &'static str,
    params: Option<Result<ParamList<'a>, error::Error>>,
    token: &'a auth::Token,
    handle: &'a Handle,
    future: Option<FutureResponse<'a, SearchResult>>,
}

impl<'a> CachedSearchFuture<'a> {
    fn new(stem: &'static str,
           token: &'a auth::Token,
           handle: &'a Handle,
           params: Result<ParamList<'a>, error::Error>)
        -> CachedSearchFuture<'a>
    {
        CachedSearchFuture {
            stem: stem,
            params: Some(params),
            token: token,
            handle: handle,
            future: None,
        }
    }
}

impl<'a> Future for CachedSearchFuture<'a> {
    type Item = Response<SearchResult>;
    type Error = error::Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        match self.params.take() {
            Some(Ok(params)) => {
                let req = auth::get(self.stem, self.token, Some(&params));

                self.future = Some(make_parsed_future(self.handle, req));
            }
            Some(Err(e)) => {
                return Err(e);
            }
            None => { }
        }

        if let Some(mut fut) = self.future.take() {
            match fut.poll() {
                Ok(Async::NotReady) => {
                    self.future = Some(fut);
                    Ok(Async::NotReady)
                }
                Ok(Async::Ready(res)) => Ok(Async::Ready(res)),
                Err(e) => Err(e),
            }
        } else {
            Err(error::Error::FutureAlreadyCompleted)
        }
    }
}
<|endoftext|>


<commit_before>extern crate euclid;

use euclid::TypedRect;
use euclid::TypedSize2D;

use types::*;

#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub struct Polyomino {
    pub squares: Vec<UPoint>,
}

#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub enum GridSegmentType {
    Perimeter,
    Internal,
}

pub struct GridSegment(pub UPoint, pub UPoint, pub GridSegmentType);

impl Polyomino {
    pub fn monomino() -> Polyomino {
        Polyomino {
            squares: vec![UPoint::new(0, 0)],
        }
    }

    pub fn has_position(&self, p: UPoint) -> bool {
        self.squares.contains(&p)
    }

    // TODO: This should be doing entire straight lines at once, not
    // just square by square

    // todo: The segment stuff could be more efficient, only building vecs
    // of the ones we want. Probably not a real issue.
    fn vertical_segments(&self) -> Vec<GridSegment> {
        // Vertical segments have a square to the right of them,
        // unless they're at the far-right of the polyominio.

        let mut res = vec![];

        for p in self.squares {
            let sort = if self.has_position(p - UVec::new(-1, 0)) {
                GridSegmentType::Internal
            } else {
                GridSegmentType::Perimeter
            };

            res.push(GridSegment(p, p + UVec::new(0, 1), sort));

            if !self.has_position(p + UVec::new(1, 0)) {
                // In this case we must be at the right-most side of the poly
                res.push(GridSegment(
                    p + UVec::new(1, 0),
                    p + UVec::new(1, 0) + UVec::new(0, 1),
                    GridSegmentType::Perimeter,
                ));
            }
        }

        res
    }

    fn horizontal_segments(&self) -> Vec<GridSegment> {
        // See above
        let mut res = vec![];

        for p in self.squares {
            let sort = if self.has_position(p - UVec::new(0, -1)) {
                GridSegmentType::Internal
            } else {
                GridSegmentType::Perimeter
            };

            res.push(GridSegment(p, p + UVec::new(1, 0), sort));

            if !self.has_position(p + UVec::new(0, 1)) {
                res.push(GridSegment(
                    p + UVec::new(0, 1),
                    p + UVec::new(0, 1) + UVec::new(1, 0),
                    GridSegmentType::Perimeter,
                ));
            }
        }

        res
    }

    pub fn segments(&self) -> Vec<GridSegment> {
        let r = self.vertical_segments();
        r.append(&mut self.horizontal_segments());
        r
    }

    pub fn square_rects(&self) -> Vec<TypedRect<i32, UniverseSpace>> {
        self.squares
            .iter()
            .map(|&s| TypedRect::new(s, TypedSize2D::new(1, 1)))
            .collect()
    }
}
<commit_msg>Fix borrows<commit_after>extern crate euclid;

use euclid::TypedRect;
use euclid::TypedSize2D;

use types::*;

#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub struct Polyomino {
    pub squares: Vec<UPoint>,
}

#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub enum GridSegmentType {
    Perimeter,
    Internal,
}

pub struct GridSegment(pub UPoint, pub UPoint, pub GridSegmentType);

impl Polyomino {
    pub fn monomino() -> Polyomino {
        Polyomino {
            squares: vec![UPoint::new(0, 0)],
        }
    }

    pub fn has_position(&self, p: UPoint) -> bool {
        self.squares.contains(&p)
    }

    // TODO: This should be doing entire straight lines at once, not
    // just square by square

    // todo: The segment stuff could be more efficient, only building vecs
    // of the ones we want. Probably not a real issue.
    fn vertical_segments(&self) -> Vec<GridSegment> {
        // Vertical segments have a square to the right of them,
        // unless they're at the far-right of the polyominio.

        let mut res = vec![];

        for p in self.squares.iter().cloned() {
            let sort = if self.has_position(p - UVec::new(-1, 0)) {
                GridSegmentType::Internal
            } else {
                GridSegmentType::Perimeter
            };

            res.push(GridSegment(p, p + UVec::new(0, 1), sort));

            if !self.has_position(p + UVec::new(1, 0)) {
                // In this case we must be at the right-most side of the poly
                res.push(GridSegment(
                    p + UVec::new(1, 0),
                    p + UVec::new(1, 0) + UVec::new(0, 1),
                    GridSegmentType::Perimeter,
                ));
            }
        }

        res
    }

    fn horizontal_segments(&self) -> Vec<GridSegment> {
        // See above
        let mut res = vec![];

        for p in self.squares.iter().cloned() {
            let sort = if self.has_position(p - UVec::new(0, -1)) {
                GridSegmentType::Internal
            } else {
                GridSegmentType::Perimeter
            };

            res.push(GridSegment(p, p + UVec::new(1, 0), sort));

            if !self.has_position(p + UVec::new(0, 1)) {
                res.push(GridSegment(
                    p + UVec::new(0, 1),
                    p + UVec::new(0, 1) + UVec::new(1, 0),
                    GridSegmentType::Perimeter,
                ));
            }
        }

        res
    }

    pub fn segments(&self) -> Vec<GridSegment> {
        let mut r = self.vertical_segments();
        r.append(&mut self.horizontal_segments());
        r
    }

    pub fn square_rects(&self) -> Vec<TypedRect<i32, UniverseSpace>> {
        self.squares
            .iter()
            .map(|&s| TypedRect::new(s, TypedSize2D::new(1, 1)))
            .collect()
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The tiny-http Contributors
// Copyright 2015 The rust-chunked-transfer Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::error::Error;
use std::fmt;
use std::io::Error as IoError;
use std::io::ErrorKind;
use std::io::Read;
use std::io::Result as IoResult;

/// Reads HTTP chunks and sends back real data.
///
/// # Example
///
/// ```
/// use chunked_transfer::Decoder;
/// use std::io::Read;
///
/// let encoded = b"3\r\nhel\r\nb\r\nlo world!!!\r\n0\r\n\r\n";
/// let mut decoded = String::new();
///
/// let mut decoder = Decoder::new(encoded as &[u8]);
/// decoder.read_to_string(&mut decoded);
///
/// assert_eq!(decoded, "hello world!!!");
/// ```
pub struct Decoder<R> {
    // where the chunks come from
    source: R,

    // remaining size of the chunk being read
    // none if we are not in a chunk
    remaining_chunks_size: Option<usize>,
}

impl<R> Decoder<R>
where
    R: Read,
{
    pub fn new(source: R) -> Decoder<R> {
        Decoder {
            source: source,
            remaining_chunks_size: None,
        }
    }

    fn read_chunk_size(&mut self) -> IoResult<usize> {
        let mut chunk_size = Vec::new();
        let mut has_ext = false;

        loop {
            let byte = match self.source.by_ref().bytes().next() {
                Some(b) => r#try!(b),
                None => return Err(IoError::new(ErrorKind::InvalidInput, DecoderError)),
            };

            if byte == b'\r' {
                break;
            }

            if byte == b';' {
                has_ext = true;
                break;
            }

            chunk_size.push(byte);
        }

        // Ignore extensions for now
        if has_ext {
            loop {
                let byte = match self.source.by_ref().bytes().next() {
                    Some(b) => r#try!(b),
                    None => return Err(IoError::new(ErrorKind::InvalidInput, DecoderError)),
                };
                if byte == b'\r' {
                    break;
                }
            }
        }

        r#try!(self.read_line_feed());

        let chunk_size = match String::from_utf8(chunk_size) {
            Ok(c) => c,
            Err(_) => return Err(IoError::new(ErrorKind::InvalidInput, DecoderError)),
        };

        let chunk_size = match usize::from_str_radix(chunk_size.trim(), 16) {
            Ok(c) => c,
            Err(_) => return Err(IoError::new(ErrorKind::InvalidInput, DecoderError)),
        };

        Ok(chunk_size)
    }

    fn read_carriage_return(&mut self) -> IoResult<()> {
        match self.source.by_ref().bytes().next() {
            Some(Ok(b'\r')) => Ok(()),
            _ => Err(IoError::new(ErrorKind::InvalidInput, DecoderError)),
        }
    }

    fn read_line_feed(&mut self) -> IoResult<()> {
        match self.source.by_ref().bytes().next() {
            Some(Ok(b'\n')) => Ok(()),
            _ => Err(IoError::new(ErrorKind::InvalidInput, DecoderError)),
        }
    }
}

impl<R> Read for Decoder<R>
where
    R: Read,
{
    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
        let remaining_chunks_size = match self.remaining_chunks_size {
            Some(c) => c,
            None => {
                // first possibility: we are not in a chunk, so we'll attempt to determine
                // the chunks size
                let chunk_size = r#try!(self.read_chunk_size());

                // if the chunk size is 0, we are at EOF
                if chunk_size == 0 {
                    r#try!(self.read_carriage_return());
                    r#try!(self.read_line_feed());
                    return Ok(0);
                }

                chunk_size
            }
        };

        // second possibility: we continue reading from a chunk
        if buf.len() < remaining_chunks_size {
            let read = r#try!(self.source.read(buf));
            self.remaining_chunks_size = Some(remaining_chunks_size - read);
            return Ok(read);
        }

        // third possibility: the read request goes further than the current chunk
        // we simply read until the end of the chunk and return
        assert!(buf.len() >= remaining_chunks_size);

        let buf = &mut buf[..remaining_chunks_size];
        let read = r#try!(self.source.read(buf));

        self.remaining_chunks_size = if read == remaining_chunks_size {
            r#try!(self.read_carriage_return());
            r#try!(self.read_line_feed());
            None
        } else {
            Some(remaining_chunks_size - read)
        };

        Ok(read)
    }
}

#[derive(Debug, Copy, Clone)]
struct DecoderError;

impl fmt::Display for DecoderError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(fmt, "Error while decoding chunks")
    }
}

impl Error for DecoderError {
    fn description(&self) -> &str {
        "Error while decoding chunks"
    }
}

#[cfg(test)]
mod test {
    use super::Decoder;
    use std::io;
    use std::io::Read;

    /// This unit test is taken from from Hyper
    /// https://github.com/hyperium/hyper
    /// Copyright (c) 2014 Sean McArthur
    #[test]
    fn test_read_chunk_size() {
        fn read(s: &str, expected: usize) {
            let mut decoded = Decoder::new(s.as_bytes());
            let actual = decoded.read_chunk_size().unwrap();
            assert_eq!(expected, actual);
        }

        fn read_err(s: &str) {
            let mut decoded = Decoder::new(s.as_bytes());
            let err_kind = decoded.read_chunk_size().unwrap_err().kind();
            assert_eq!(err_kind, io::ErrorKind::InvalidInput);
        }

        read("1\r\n", 1);
        read("01\r\n", 1);
        read("0\r\n", 0);
        read("00\r\n", 0);
        read("A\r\n", 10);
        read("a\r\n", 10);
        read("Ff\r\n", 255);
        read("Ff   \r\n", 255);
        // Missing LF or CRLF
        read_err("F\rF");
        read_err("F");
        // Invalid hex digit
        read_err("X\r\n");
        read_err("1X\r\n");
        read_err("-\r\n");
        read_err("-1\r\n");
        // Acceptable (if not fully valid) extensions do not influence the size
        read("1;extension\r\n", 1);
        read("a;ext name=value\r\n", 10);
        read("1;extension;extension2\r\n", 1);
        read("1;;;  ;\r\n", 1);
        read("2; extension...\r\n", 2);
        read("3   ; extension=123\r\n", 3);
        read("3   ;\r\n", 3);
        read("3   ;   \r\n", 3);
        // Invalid extensions cause an error
        read_err("1 invalid extension\r\n");
        read_err("1 A\r\n");
        read_err("1;no CRLF");
    }

    #[test]
    fn test_valid_chunk_decode() {
        let source = io::Cursor::new(
            "3\r\nhel\r\nb\r\nlo world!!!\r\n0\r\n\r\n"
                .to_string()
                .into_bytes(),
        );
        let mut decoded = Decoder::new(source);

        let mut string = String::new();
        decoded.read_to_string(&mut string).unwrap();

        assert_eq!(string, "hello world!!!");
    }

    #[test]
    fn test_decode_zero_length() {
        let mut decoder = Decoder::new(b"0\r\n\r\n" as &[u8]);

        let mut decoded = String::new();
        decoder.read_to_string(&mut decoded).unwrap();

        assert_eq!(decoded, "");
    }

    #[test]
    fn test_decode_invalid_chunk_length() {
        let mut decoder = Decoder::new(b"m\r\n\r\n" as &[u8]);

        let mut decoded = String::new();
        assert!(decoder.read_to_string(&mut decoded).is_err());
    }

    #[test]
    fn invalid_input1() {
        let source = io::Cursor::new(
            "2\r\nhel\r\nb\r\nlo world!!!\r\n0\r\n"
                .to_string()
                .into_bytes(),
        );
        let mut decoded = Decoder::new(source);

        let mut string = String::new();
        decoded.read_to_string(&mut string).is_err();
    }

    #[test]
    fn invalid_input2() {
        let source = io::Cursor::new(
            "3\rhel\r\nb\r\nlo world!!!\r\n0\r\n"
                .to_string()
                .into_bytes(),
        );
        let mut decoded = Decoder::new(source);

        let mut string = String::new();
        decoded.read_to_string(&mut string).is_err();
    }
}
<commit_msg>combinators<commit_after>// Copyright 2015 The tiny-http Contributors
// Copyright 2015 The rust-chunked-transfer Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::error::Error;
use std::fmt;
use std::io::Error as IoError;
use std::io::ErrorKind;
use std::io::Read;
use std::io::Result as IoResult;

/// Reads HTTP chunks and sends back real data.
///
/// # Example
///
/// ```
/// use chunked_transfer::Decoder;
/// use std::io::Read;
///
/// let encoded = b"3\r\nhel\r\nb\r\nlo world!!!\r\n0\r\n\r\n";
/// let mut decoded = String::new();
///
/// let mut decoder = Decoder::new(encoded as &[u8]);
/// decoder.read_to_string(&mut decoded);
///
/// assert_eq!(decoded, "hello world!!!");
/// ```
pub struct Decoder<R> {
    // where the chunks come from
    source: R,

    // remaining size of the chunk being read
    // none if we are not in a chunk
    remaining_chunks_size: Option<usize>,
}

impl<R> Decoder<R>
where
    R: Read,
{
    pub fn new(source: R) -> Decoder<R> {
        Decoder {
            source: source,
            remaining_chunks_size: None,
        }
    }

    fn read_chunk_size(&mut self) -> IoResult<usize> {
        let mut chunk_size_bytes = Vec::new();
        let mut has_ext = false;

        loop {
            let byte = match self.source.by_ref().bytes().next() {
                Some(b) => r#try!(b),
                None => return Err(IoError::new(ErrorKind::InvalidInput, DecoderError)),
            };

            if byte == b'\r' {
                break;
            }

            if byte == b';' {
                has_ext = true;
                break;
            }

            chunk_size_bytes.push(byte);
        }

        // Ignore extensions for now
        if has_ext {
            loop {
                let byte = match self.source.by_ref().bytes().next() {
                    Some(b) => r#try!(b),
                    None => return Err(IoError::new(ErrorKind::InvalidInput, DecoderError)),
                };
                if byte == b'\r' {
                    break;
                }
            }
        }

        r#try!(self.read_line_feed());

        let chunk_size = String::from_utf8(chunk_size_bytes)
            .ok()
            .and_then(|c| usize::from_str_radix(c.trim(), 16).ok())
            .ok_or(IoError::new(ErrorKind::InvalidInput, DecoderError))?;

        Ok(chunk_size)
    }

    fn read_carriage_return(&mut self) -> IoResult<()> {
        match self.source.by_ref().bytes().next() {
            Some(Ok(b'\r')) => Ok(()),
            _ => Err(IoError::new(ErrorKind::InvalidInput, DecoderError)),
        }
    }

    fn read_line_feed(&mut self) -> IoResult<()> {
        match self.source.by_ref().bytes().next() {
            Some(Ok(b'\n')) => Ok(()),
            _ => Err(IoError::new(ErrorKind::InvalidInput, DecoderError)),
        }
    }
}

impl<R> Read for Decoder<R>
where
    R: Read,
{
    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
        let remaining_chunks_size = match self.remaining_chunks_size {
            Some(c) => c,
            None => {
                // first possibility: we are not in a chunk, so we'll attempt to determine
                // the chunks size
                let chunk_size = r#try!(self.read_chunk_size());

                // if the chunk size is 0, we are at EOF
                if chunk_size == 0 {
                    r#try!(self.read_carriage_return());
                    r#try!(self.read_line_feed());
                    return Ok(0);
                }

                chunk_size
            }
        };

        // second possibility: we continue reading from a chunk
        if buf.len() < remaining_chunks_size {
            let read = r#try!(self.source.read(buf));
            self.remaining_chunks_size = Some(remaining_chunks_size - read);
            return Ok(read);
        }

        // third possibility: the read request goes further than the current chunk
        // we simply read until the end of the chunk and return
        assert!(buf.len() >= remaining_chunks_size);

        let buf = &mut buf[..remaining_chunks_size];
        let read = r#try!(self.source.read(buf));

        self.remaining_chunks_size = if read == remaining_chunks_size {
            r#try!(self.read_carriage_return());
            r#try!(self.read_line_feed());
            None
        } else {
            Some(remaining_chunks_size - read)
        };

        Ok(read)
    }
}

#[derive(Debug, Copy, Clone)]
struct DecoderError;

impl fmt::Display for DecoderError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        write!(fmt, "Error while decoding chunks")
    }
}

impl Error for DecoderError {
    fn description(&self) -> &str {
        "Error while decoding chunks"
    }
}

#[cfg(test)]
mod test {
    use super::Decoder;
    use std::io;
    use std::io::Read;

    /// This unit test is taken from from Hyper
    /// https://github.com/hyperium/hyper
    /// Copyright (c) 2014 Sean McArthur
    #[test]
    fn test_read_chunk_size() {
        fn read(s: &str, expected: usize) {
            let mut decoded = Decoder::new(s.as_bytes());
            let actual = decoded.read_chunk_size().unwrap();
            assert_eq!(expected, actual);
        }

        fn read_err(s: &str) {
            let mut decoded = Decoder::new(s.as_bytes());
            let err_kind = decoded.read_chunk_size().unwrap_err().kind();
            assert_eq!(err_kind, io::ErrorKind::InvalidInput);
        }

        read("1\r\n", 1);
        read("01\r\n", 1);
        read("0\r\n", 0);
        read("00\r\n", 0);
        read("A\r\n", 10);
        read("a\r\n", 10);
        read("Ff\r\n", 255);
        read("Ff   \r\n", 255);
        // Missing LF or CRLF
        read_err("F\rF");
        read_err("F");
        // Invalid hex digit
        read_err("X\r\n");
        read_err("1X\r\n");
        read_err("-\r\n");
        read_err("-1\r\n");
        // Acceptable (if not fully valid) extensions do not influence the size
        read("1;extension\r\n", 1);
        read("a;ext name=value\r\n", 10);
        read("1;extension;extension2\r\n", 1);
        read("1;;;  ;\r\n", 1);
        read("2; extension...\r\n", 2);
        read("3   ; extension=123\r\n", 3);
        read("3   ;\r\n", 3);
        read("3   ;   \r\n", 3);
        // Invalid extensions cause an error
        read_err("1 invalid extension\r\n");
        read_err("1 A\r\n");
        read_err("1;no CRLF");
    }

    #[test]
    fn test_valid_chunk_decode() {
        let source = io::Cursor::new(
            "3\r\nhel\r\nb\r\nlo world!!!\r\n0\r\n\r\n"
                .to_string()
                .into_bytes(),
        );
        let mut decoded = Decoder::new(source);

        let mut string = String::new();
        decoded.read_to_string(&mut string).unwrap();

        assert_eq!(string, "hello world!!!");
    }

    #[test]
    fn test_decode_zero_length() {
        let mut decoder = Decoder::new(b"0\r\n\r\n" as &[u8]);

        let mut decoded = String::new();
        decoder.read_to_string(&mut decoded).unwrap();

        assert_eq!(decoded, "");
    }

    #[test]
    fn test_decode_invalid_chunk_length() {
        let mut decoder = Decoder::new(b"m\r\n\r\n" as &[u8]);

        let mut decoded = String::new();
        assert!(decoder.read_to_string(&mut decoded).is_err());
    }

    #[test]
    fn invalid_input1() {
        let source = io::Cursor::new(
            "2\r\nhel\r\nb\r\nlo world!!!\r\n0\r\n"
                .to_string()
                .into_bytes(),
        );
        let mut decoded = Decoder::new(source);

        let mut string = String::new();
        decoded.read_to_string(&mut string).is_err();
    }

    #[test]
    fn invalid_input2() {
        let source = io::Cursor::new(
            "3\rhel\r\nb\r\nlo world!!!\r\n0\r\n"
                .to_string()
                .into_bytes(),
        );
        let mut decoded = Decoder::new(source);

        let mut string = String::new();
        decoded.read_to_string(&mut string).is_err();
    }
}
<|endoftext|>


<commit_before>use coefs::Coefficients;
use consts::SAMPLES;
use descramble::{descramble, Bootstrap};
use enhance::{self, EnhancedSpectrals, FrameEnergy};
use errors::Errors;
use gain::Gains;
use params::BaseParams;
use prev::PrevFrame;
use spectral::Spectrals;
use unvoiced::{UnvoicedDFT, Unvoiced};
use voiced::{Phase, PhaseBase, Voiced};

pub struct CAIFrame {
    chunks: [u32; 8],
    errors: [usize; 7],
}

impl CAIFrame {
    pub fn new(chunks: [u32; 8], errors: [usize; 7]) -> CAIFrame {
        CAIFrame {
            chunks: chunks,
            errors: errors,
        }
    }
}

pub struct IMBEDecoder {
    prev: PrevFrame,
}

impl IMBEDecoder {
    pub fn new() -> IMBEDecoder {
        IMBEDecoder {
            prev: PrevFrame::default(),
        }
    }

    pub fn decode<F: FnMut(f32)>(&mut self, frame: CAIFrame, mut cb: F) {
        let period = match Bootstrap::new(&frame.chunks) {
            Bootstrap::Period(p) => p,
            Bootstrap::Invalid => {
                self.repeat(cb);
                return;
            },
            Bootstrap::Silence => {
                self.silence(cb);
                return;
            },
        };

        let errors = Errors::new(&frame.errors, self.prev.err_rate);

        if enhance::should_repeat(&errors) {
            self.repeat(cb);
            return;
        }

        if enhance::should_mute(&errors) {
            self.silence(cb);
            return;
        }

        let params = BaseParams::new(period);
        let (amps, mut voice, gain_idx) = descramble(&frame.chunks, &params);
        let gains = Gains::new(gain_idx, &amps, &params);
        let coefs = Coefficients::new(&gains, &amps, &params);
        let spectrals = Spectrals::new(&coefs, &params, &self.prev);
        let energy = FrameEnergy::new(&spectrals, &self.prev.energy, &params);

        let mut enhanced = EnhancedSpectrals::new(&spectrals, &energy, &params);
        let amp_thresh = enhance::amp_thresh(&errors, self.prev.amp_thresh);
        enhance::smooth(&mut enhanced, &mut voice, &errors, &energy, amp_thresh);

        let udft = UnvoicedDFT::new(&params, &voice, &enhanced);
        let vbase = PhaseBase::new(&params, &self.prev);
        let vphase = Phase::new(&params, &voice, &vbase);

        {
            let unvoiced = Unvoiced::new(&udft, &self.prev.unvoiced);
            let voiced = Voiced::new(&params, &self.prev, &vphase, &enhanced, &voice);

            for n in 0..SAMPLES {
                cb(unvoiced.get(n) + voiced.get(n));
            }
        }

        self.prev = PrevFrame {
            params: params,
            spectrals: spectrals,
            enhanced: enhanced,
            voice: voice,
            err_rate: errors.rate,
            energy: energy,
            amp_thresh: amp_thresh,
            unvoiced: udft,
            phase_base: vbase,
            phase: vphase,
        };
    }

    fn silence<F: FnMut(f32)>(&self, mut cb: F) {
        for _ in 0..SAMPLES {
            cb(0.0);
        }
    }

    fn repeat<F: FnMut(f32)>(&self, mut cb: F) {
        let params = self.prev.params.clone();
        let voice = self.prev.voice.clone();
        let enhanced = self.prev.enhanced.clone();

        let udft = UnvoicedDFT::new(&params, &voice, &enhanced);
        let vbase = PhaseBase::new(&params, &self.prev);
        let vphase = Phase::new(&params, &voice, &vbase);

        let unvoiced = Unvoiced::new(&udft, &self.prev.unvoiced);
        let voiced = Voiced::new(&params, &self.prev, &vphase, &enhanced, &voice);

        for n in 0..SAMPLES {
            cb(unvoiced.get(n) + voiced.get(n));
        }
    }
}
<commit_msg>Decode samples as an array rather than callback<commit_after>use collect_slice::CollectSlice;

use coefs::Coefficients;
use consts::SAMPLES;
use descramble::{descramble, Bootstrap};
use enhance::{self, EnhancedSpectrals, FrameEnergy};
use errors::Errors;
use gain::Gains;
use params::BaseParams;
use prev::PrevFrame;
use spectral::Spectrals;
use unvoiced::{UnvoicedDFT, Unvoiced};
use voiced::{Phase, PhaseBase, Voiced};

pub struct CAIFrame {
    chunks: [u32; 8],
    errors: [usize; 7],
}

impl CAIFrame {
    pub fn new(chunks: [u32; 8], errors: [usize; 7]) -> CAIFrame {
        CAIFrame {
            chunks: chunks,
            errors: errors,
        }
    }
}

pub struct IMBEDecoder {
    prev: PrevFrame,
}

impl IMBEDecoder {
    pub fn new() -> IMBEDecoder {
        IMBEDecoder {
            prev: PrevFrame::default(),
        }
    }

    pub fn decode(&mut self, frame: CAIFrame, buf: &mut [f32; SAMPLES]) {
        let period = match Bootstrap::new(&frame.chunks) {
            Bootstrap::Period(p) => p,
            Bootstrap::Invalid => {
                self.repeat(buf);
                return;
            },
            Bootstrap::Silence => {
                self.silence(buf);
                return;
            },
        };

        let errors = Errors::new(&frame.errors, self.prev.err_rate);

        if enhance::should_repeat(&errors) {
            self.repeat(buf);
            return;
        }

        if enhance::should_mute(&errors) {
            self.silence(buf);
            return;
        }

        let params = BaseParams::new(period);
        let (amps, mut voice, gain_idx) = descramble(&frame.chunks, &params);
        let gains = Gains::new(gain_idx, &amps, &params);
        let coefs = Coefficients::new(&gains, &amps, &params);
        let spectrals = Spectrals::new(&coefs, &params, &self.prev);
        let energy = FrameEnergy::new(&spectrals, &self.prev.energy, &params);

        let mut enhanced = EnhancedSpectrals::new(&spectrals, &energy, &params);
        let amp_thresh = enhance::amp_thresh(&errors, self.prev.amp_thresh);
        enhance::smooth(&mut enhanced, &mut voice, &errors, &energy, amp_thresh);

        let udft = UnvoicedDFT::new(&params, &voice, &enhanced);
        let vbase = PhaseBase::new(&params, &self.prev);
        let vphase = Phase::new(&params, &voice, &vbase);

        {
            let unvoiced = Unvoiced::new(&udft, &self.prev.unvoiced);
            let voiced = Voiced::new(&params, &self.prev, &vphase, &enhanced, &voice);

            (0..SAMPLES)
                .map(|n| unvoiced.get(n) + voiced.get(n))
                .collect_slice(&mut buf[..]);
        }

        self.prev = PrevFrame {
            params: params,
            spectrals: spectrals,
            enhanced: enhanced,
            voice: voice,
            err_rate: errors.rate,
            energy: energy,
            amp_thresh: amp_thresh,
            unvoiced: udft,
            phase_base: vbase,
            phase: vphase,
        };
    }

    fn silence(&self, buf: &mut [f32; SAMPLES]) {
        (0..SAMPLES).map(|_| 0.0).collect_slice(&mut buf[..]);
    }

    fn repeat(&self, buf: &mut [f32; SAMPLES]) {
        let params = self.prev.params.clone();
        let voice = self.prev.voice.clone();
        let enhanced = self.prev.enhanced.clone();

        let udft = UnvoicedDFT::new(&params, &voice, &enhanced);
        let vbase = PhaseBase::new(&params, &self.prev);
        let vphase = Phase::new(&params, &voice, &vbase);

        let unvoiced = Unvoiced::new(&udft, &self.prev.unvoiced);
        let voiced = Voiced::new(&params, &self.prev, &vphase, &enhanced, &voice);

        (0..SAMPLES)
            .map(|n| unvoiced.get(n) + voiced.get(n))
            .collect_slice(&mut buf[..]);
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use std::collections::BTreeSet;
use std::fmt::{self, Display};
use parse::NextPrev;

#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Range(pub char, pub char);

impl fmt::Display for Range {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.0, self.1)
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Set(BTreeSet<Range>);

impl fmt::Display for Set {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let Set(ref set) = *self;
        let len = BTreeSet::len(set);

        for (count, s) in set.iter().enumerate() {
            if count < len - 1 { try!(write!(f, "{}, ", s)) }
            else { return write!(f, "{}", s) }
        }

        Ok(())
    }
}

impl Set {
    pub fn new() -> Self { Set(BTreeSet::new()) }
    pub fn insert(&mut self, value: Range) {
        let mut ret = BTreeSet::new();
        // value is a complete subset of one of the other ranges.
        let mut subset = false;

        // Borrowing self blocks later operation. Add a new scope.
        {   let Set(ref set) = *self;

            let Range(mut min_val, mut max_val) = value;
            if min_val > max_val { panic!("First value cannot be greater than the second.") }

            // Loop over set adding old disjoint pieces and supersets back.
            // When partially overlapped, expand value to the union. At the
            // end, insert union after it has been fully expanded.
            for &Range(min, max) in &*set {
                // value overlaps at the beginning.
                if min_val < min && max_val >= min && max_val < max { max_val = max }
                // value overlaps at the end.
                else if min_val > min && min_val <= max && max_val > max { min_val = min }
                // value is entirely contained between min and max. Insert original
                // into new array because new is a subset.
                else if min_val >= min && max_val <= max {
                    ret.insert(Range(min, max));
                    subset = true;
                }
                // value is a superset to the current so don't add current.
                else if min_val < min && max_val > max {}
                // value is disjoint with current so add current.
                else { ret.insert(Range(min, max)); }
            }

            // Insert value only when it's not a subset.
            if !subset { ret.insert(Range(min_val, max_val)); }
        }

        *self = Set(ret);
    }
    pub fn remove(&mut self, value: Range) {
        let mut ret = BTreeSet::new();

        // Borrowing self blocks later modification. Make a new scope to contain it.
        {   let Set(ref set) = *self;

            let Range(min_val, max_val) = value;
            if min_val > max_val { panic!("First value cannot be greater than the second.") }

            // Loop over set inserting whatever doesn't intersect.
            for &Range(min, max) in &*set {
                // value overlaps at the beginning.
                if min_val <= min && max_val >= min && max_val < max { ret.insert(Range(max_val.next(), max)); }
                // value overlaps at the end.
                else if min_val > min && min_val <= max && max_val >= max { ret.insert(Range(min, min_val.prev())); }
                // value is entirely contained between min and max. Split set
                // into two pieces.
                else if min_val > min && max_val < max {
                    ret.insert(Range(min, min_val.prev()));
                    ret.insert(Range(max_val.next(), max));

                    // Current piece was a superset so value cannot be anywhere else.
                    break;
                // value is a superset to the current so don't add current.
                } else if min_val <= min && max_val >= max {}
                // value is disjoint with current so add current.
                else { ret.insert(Range(min, max)); }
            }
        }

        *self = Set(ret)
    }
    // 123 + 345 = 12345.
    pub fn union(&self, value: &Self) -> Self {
        let mut ret = self.clone();

        // Loop over the btreeset of Range(char, char).
        for &x in &value.0 { ret.insert(x) }

        ret
    }
    // Intersection of `A` & `B` is `A - (A - B)`: 123 & 345 = 3.
    pub fn intersection(&self, value: &Self) -> Self {
        let diff = self.difference(value);

        self.difference(&diff)
    }
    // 123 - 345 = 12.
    pub fn difference(&self, value: &Self) -> Self {
        let mut ret = self.clone();

        for &x in &value.0 { ret.remove(x) }

        ret
    }
    // `A` ^ `B` is `(A + B) - (A & B)`: 123 ^ 345 = 1245.
    pub fn symmetric_difference(&self, value: &Self) -> Self {
        let union = self.union(value);
        let intersection = self.intersection(value);

        union.difference(&intersection)
    }
}

#[cfg(test)]
mod test {
    use super::{Range, Set};

    fn generate(vec: Vec<(char, char)>) -> Set {
        let mut set = Set::new();

        for (a, b) in vec {
            set.insert(Range(a, b));
        }

        set
    }
    #[test]
    fn insert_partial_overlap() {
        let set1 = generate(vec![('3', '5'), ('4', '6')]);
        let set2 = generate(vec![('3', '5'), ('1', '4')]);

        let other1 = generate(vec![('3', '6')]);
        let other2 = generate(vec![('1', '5')]);

        assert_eq!(other1, set1);
        assert_eq!(other2, set2);
    }
    #[test]
    fn insert_subset() {
        let set1 = generate(vec![('1', '5'), ('2', '3')]); // Complete overlap.
        let set2 = generate(vec![('1', '5'), ('1', '3')]); // Left is exact.
        let set3 = generate(vec![('1', '5'), ('2', '5')]); // Right is exact.
        let set4 = generate(vec![('1', '5'), ('1', '5')]); // Both are exact.

        let other = generate(vec![('1', '5')]);

        assert_eq!(set1, other);
        assert_eq!(set2, other);
        assert_eq!(set3, other);
        assert_eq!(set4, other);
    }
    #[test]
    fn insert_superset() {
        let set   = generate(vec![('3', '5'), ('2', '6')]);
        let other = generate(vec![('2', '6')]);

        assert_eq!(other, set);
    }
    #[test]
    #[should_panic]
    fn panic_on_decreasing_order() {
        generate(vec![('5', '3')]);
    }
    #[test]
    fn set_union() {
        let set1 = generate(vec![('1', '4'), ('5', '6')]);
        let set2 = generate(vec![('0', '5'), ('8', '9')]);

        let union = set1.union(&set2);

        let other = generate(vec![('0', '6'), ('8', '9')]);
        assert_eq!(union, other);
    }
    #[test]
    fn remove_partial_overlap() {
        let mut set1 = generate(vec![('5', '9')]);
        set1.remove(Range('3', '6')); // beginnings different.

        let mut set2 = generate(vec![('5', '9')]);
        set2.remove(Range('5', '6')); // beginnings same.

        let mut set3 = generate(vec![('2', '6')]);
        set3.remove(Range('5', '9')); // end different.

        let mut set4 = generate(vec![('2', '6')]);
        set4.remove(Range('5', '6')); // end same.

        let other12 = generate(vec![('7', '9')]);
        let other34 = generate(vec![('2', '4')]);

        assert_eq!(set1, other12);
        assert_eq!(set2, other12);
        assert_eq!(set3, other34);
        assert_eq!(set4, other34);
    }
    #[test]
    fn remove_subset() {
        let mut set = generate(vec![('1', '9')]);
        set.remove(Range('3', '6'));

        let other = generate(vec![('1', '2'), ('7', '9')]);

        assert_eq!(set, other);
    }
    #[test]
    fn remove_superset() {
        let mut set = generate(vec![('5', '6')]);
        set.remove(Range('3', '8'));

        let other = generate(vec![]);
        assert_eq!(set, other);
    }
    #[test]
    fn remove_disjoint() {
        let mut set = generate(vec![('2', '3')]);
        set.remove(Range('6', '8'));

        let other = generate(vec![('2', '3')]);
        assert_eq!(set, other);
    }
    #[test]
    fn set_difference() {
        let set1 = generate(vec![('2', '7')]);
        let set2 = generate(vec![('0', '1'),   // disjoint left
                                 ('1', '2'),   // partial overlap left
                                 ('4', '5'),   // subset
                                 ('7', '8'),   // partial overlap right
                                 ('9', '9')]); // disjoint right
        let letters1 = generate(vec![('c', 'e')]);
        let letters2 = generate(vec![('a', 'g')]); // superset

        let difference_set     = set1.difference(&set2);
        let difference_letters = letters1.difference(&letters2);

        let other_set     = generate(vec![('3', '3'), ('6', '6')]);
        let other_letters = generate(vec![]);

        assert_eq!(difference_set, other_set);
        assert_eq!(difference_letters, other_letters);
    }
    #[test]
    fn set_intersection_partial_overlap() {
        let set   = generate(vec![('2', '7')]);
        let left  = generate(vec![('0', '3')]);
        let right = generate(vec![('6', '8')]);

        let intersection_left  = set.intersection(&left);
        let intersection_right = set.intersection(&right);

        let other_left  = generate(vec![('2', '3')]);
        let other_right = generate(vec![('6', '7')]);

        assert_eq!(intersection_left, other_left);
        assert_eq!(intersection_right, other_right);
    }
    #[test]
    fn set_intersection_subset() {
        let set = generate(vec![('2', '7')]);

        let subset      = generate(vec![('3', '6')]);
        let exact_left  = generate(vec![('2', '6')]);
        let exact_right = generate(vec![('3', '7')]);

        let intersection_subset = set.intersection(&subset);
        let intersection_left   = set.intersection(&exact_left);
        let intersection_right  = set.intersection(&exact_right);
        let intersection_both   = set.intersection(&set);

        assert_eq!(intersection_subset, subset);
        assert_eq!(intersection_left, exact_left);
        assert_eq!(intersection_right, exact_right);
        assert_eq!(intersection_both, set);
    }
    #[test]
    fn set_intersection_superset() {
        let set      = generate(vec![('2', '7')]);
        let superset = generate(vec![('1', '8')]);

        let intersection = set.intersection(&superset);

        let other = generate(vec![('2', '7')]);
        assert_eq!(intersection, other);
    }
    #[test]
    fn set_intersection_disjoint() {
        let set = generate(vec![('3', '4')]);

        let low  = generate(vec![('1', '2')]);
        let high = generate(vec![('5', '6')]);

        let intersection_low  = set.intersection(&low);
        let intersection_high = set.intersection(&high);

        let other_low  = generate(vec![]);
        let other_high = generate(vec![]);

        assert_eq!(intersection_low, other_low);
        assert_eq!(intersection_high, other_high);
    }
}
<commit_msg>Add tests for symmetric difference<commit_after>#![allow(dead_code)]

use std::collections::BTreeSet;
use std::fmt::{self, Display};
use parse::NextPrev;

#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq)]
pub struct Range(pub char, pub char);

impl fmt::Display for Range {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.0, self.1)
    }
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Set(BTreeSet<Range>);

impl fmt::Display for Set {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let Set(ref set) = *self;
        let len = BTreeSet::len(set);

        for (count, s) in set.iter().enumerate() {
            if count < len - 1 { try!(write!(f, "{}, ", s)) }
            else { return write!(f, "{}", s) }
        }

        Ok(())
    }
}

impl Set {
    pub fn new() -> Self { Set(BTreeSet::new()) }
    pub fn insert(&mut self, value: Range) {
        let mut ret = BTreeSet::new();
        // value is a complete subset of one of the other ranges.
        let mut subset = false;

        // Borrowing self blocks later operation. Add a new scope.
        {   let Set(ref set) = *self;

            let Range(mut min_val, mut max_val) = value;
            if min_val > max_val { panic!("First value cannot be greater than the second.") }

            // Loop over set adding old disjoint pieces and supersets back.
            // When partially overlapped, expand value to the union. At the
            // end, insert union after it has been fully expanded.
            for &Range(min, max) in &*set {
                // value overlaps at the beginning.
                if min_val < min && max_val >= min && max_val < max { max_val = max }
                // value overlaps at the end.
                else if min_val > min && min_val <= max && max_val > max { min_val = min }
                // value is entirely contained between min and max. Insert original
                // into new array because new is a subset.
                else if min_val >= min && max_val <= max {
                    ret.insert(Range(min, max));
                    subset = true;
                }
                // value is a superset to the current so don't add current.
                else if min_val < min && max_val > max {}
                // value is disjoint with current so add current.
                else { ret.insert(Range(min, max)); }
            }

            // Insert value only when it's not a subset.
            if !subset { ret.insert(Range(min_val, max_val)); }
        }

        *self = Set(ret);
    }
    pub fn remove(&mut self, value: Range) {
        let mut ret = BTreeSet::new();

        // Borrowing self blocks later modification. Make a new scope to contain it.
        {   let Set(ref set) = *self;

            let Range(min_val, max_val) = value;
            if min_val > max_val { panic!("First value cannot be greater than the second.") }

            // Loop over set inserting whatever doesn't intersect.
            for &Range(min, max) in &*set {
                // value overlaps at the beginning.
                if min_val <= min && max_val >= min && max_val < max { ret.insert(Range(max_val.next(), max)); }
                // value overlaps at the end.
                else if min_val > min && min_val <= max && max_val >= max { ret.insert(Range(min, min_val.prev())); }
                // value is entirely contained between min and max. Split set
                // into two pieces.
                else if min_val > min && max_val < max {
                    ret.insert(Range(min, min_val.prev()));
                    ret.insert(Range(max_val.next(), max));

                    // Current piece was a superset so value cannot be anywhere else.
                    break;
                // value is a superset to the current so don't add current.
                } else if min_val <= min && max_val >= max {}
                // value is disjoint with current so add current.
                else { ret.insert(Range(min, max)); }
            }
        }

        *self = Set(ret)
    }
    // 123 + 345 = 12345.
    pub fn union(&self, value: &Self) -> Self {
        let mut ret = self.clone();

        // Loop over the btreeset of Range(char, char).
        for &x in &value.0 { ret.insert(x) }

        ret
    }
    // Intersection of `A` & `B` is `A - (A - B)`: 123 & 345 = 3.
    pub fn intersection(&self, value: &Self) -> Self {
        let diff = self.difference(value);

        self.difference(&diff)
    }
    // 123 - 345 = 12.
    pub fn difference(&self, value: &Self) -> Self {
        let mut ret = self.clone();

        for &x in &value.0 { ret.remove(x) }

        ret
    }
    // `A` ^ `B` is `(A + B) - (A & B)`: 123 ^ 345 = 1245.
    pub fn symmetric_difference(&self, value: &Self) -> Self {
        let union = self.union(value);
        let intersection = self.intersection(value);

        union.difference(&intersection)
    }
}

#[cfg(test)]
mod test {
    use super::{Range, Set};

    fn generate(vec: Vec<(char, char)>) -> Set {
        let mut set = Set::new();

        for (a, b) in vec {
            set.insert(Range(a, b));
        }

        set
    }
    #[test]
    fn insert_partial_overlap() {
        let set1 = generate(vec![('3', '5'), ('4', '6')]);
        let set2 = generate(vec![('3', '5'), ('1', '4')]);

        let other1 = generate(vec![('3', '6')]);
        let other2 = generate(vec![('1', '5')]);

        assert_eq!(other1, set1);
        assert_eq!(other2, set2);
    }
    #[test]
    fn insert_subset() {
        let set1 = generate(vec![('1', '5'), ('2', '3')]); // Complete overlap.
        let set2 = generate(vec![('1', '5'), ('1', '3')]); // Left is exact.
        let set3 = generate(vec![('1', '5'), ('2', '5')]); // Right is exact.
        let set4 = generate(vec![('1', '5'), ('1', '5')]); // Both are exact.

        let other = generate(vec![('1', '5')]);

        assert_eq!(set1, other);
        assert_eq!(set2, other);
        assert_eq!(set3, other);
        assert_eq!(set4, other);
    }
    #[test]
    fn insert_superset() {
        let set   = generate(vec![('3', '5'), ('2', '6')]);
        let other = generate(vec![('2', '6')]);

        assert_eq!(other, set);
    }
    #[test]
    #[should_panic]
    fn panic_on_decreasing_order() {
        generate(vec![('5', '3')]);
    }
    #[test]
    fn set_union() {
        let set1 = generate(vec![('1', '4'), ('5', '6')]);
        let set2 = generate(vec![('0', '5'), ('8', '9')]);

        let union = set1.union(&set2);

        let other = generate(vec![('0', '6'), ('8', '9')]);
        assert_eq!(union, other);
    }
    #[test]
    fn remove_partial_overlap() {
        let mut set1 = generate(vec![('5', '9')]);
        set1.remove(Range('3', '6')); // beginnings different.

        let mut set2 = generate(vec![('5', '9')]);
        set2.remove(Range('5', '6')); // beginnings same.

        let mut set3 = generate(vec![('2', '6')]);
        set3.remove(Range('5', '9')); // end different.

        let mut set4 = generate(vec![('2', '6')]);
        set4.remove(Range('5', '6')); // end same.

        let other12 = generate(vec![('7', '9')]);
        let other34 = generate(vec![('2', '4')]);

        assert_eq!(set1, other12);
        assert_eq!(set2, other12);
        assert_eq!(set3, other34);
        assert_eq!(set4, other34);
    }
    #[test]
    fn remove_subset() {
        let mut set = generate(vec![('1', '9')]);
        set.remove(Range('3', '6'));

        let other = generate(vec![('1', '2'), ('7', '9')]);

        assert_eq!(set, other);
    }
    #[test]
    fn remove_superset() {
        let mut set = generate(vec![('5', '6')]);
        set.remove(Range('3', '8'));

        let other = generate(vec![]);
        assert_eq!(set, other);
    }
    #[test]
    fn remove_disjoint() {
        let mut set = generate(vec![('2', '3')]);
        set.remove(Range('6', '8'));

        let other = generate(vec![('2', '3')]);
        assert_eq!(set, other);
    }
    #[test]
    fn set_difference() {
        let set1 = generate(vec![('2', '7')]);
        let set2 = generate(vec![('0', '1'),   // disjoint left
                                 ('1', '2'),   // partial overlap left
                                 ('4', '5'),   // subset
                                 ('7', '8'),   // partial overlap right
                                 ('9', '9')]); // disjoint right
        let letters1 = generate(vec![('c', 'e')]);
        let letters2 = generate(vec![('a', 'g')]); // superset

        let difference_set     = set1.difference(&set2);
        let difference_letters = letters1.difference(&letters2);

        let other_set     = generate(vec![('3', '3'), ('6', '6')]);
        let other_letters = generate(vec![]);

        assert_eq!(difference_set, other_set);
        assert_eq!(difference_letters, other_letters);
    }
    #[test]
    fn set_intersection_partial_overlap() {
        let set   = generate(vec![('2', '7')]);
        let left  = generate(vec![('0', '3')]);
        let right = generate(vec![('6', '8')]);

        let intersection_left  = set.intersection(&left);
        let intersection_right = set.intersection(&right);

        let other_left  = generate(vec![('2', '3')]);
        let other_right = generate(vec![('6', '7')]);

        assert_eq!(intersection_left, other_left);
        assert_eq!(intersection_right, other_right);
    }
    #[test]
    fn set_intersection_subset() {
        let set = generate(vec![('2', '7')]);

        let subset      = generate(vec![('3', '6')]);
        let exact_left  = generate(vec![('2', '6')]);
        let exact_right = generate(vec![('3', '7')]);

        let intersection_subset = set.intersection(&subset);
        let intersection_left   = set.intersection(&exact_left);
        let intersection_right  = set.intersection(&exact_right);
        let intersection_both   = set.intersection(&set);

        assert_eq!(intersection_subset, subset);
        assert_eq!(intersection_left, exact_left);
        assert_eq!(intersection_right, exact_right);
        assert_eq!(intersection_both, set);
    }
    #[test]
    fn set_intersection_superset() {
        let set      = generate(vec![('2', '7')]);
        let superset = generate(vec![('1', '8')]);

        let intersection = set.intersection(&superset);

        let other = generate(vec![('2', '7')]);
        assert_eq!(intersection, other);
    }
    #[test]
    fn set_intersection_disjoint() {
        let set = generate(vec![('3', '4')]);

        let low  = generate(vec![('1', '2')]);
        let high = generate(vec![('5', '6')]);

        let intersection_low  = set.intersection(&low);
        let intersection_high = set.intersection(&high);

        let other_low  = generate(vec![]);
        let other_high = generate(vec![]);

        assert_eq!(intersection_low, other_low);
        assert_eq!(intersection_high, other_high);
    }
    #[test]
    fn set_symmetric_difference_partial_overlap() {
        let set = generate(vec![('3', '6')]);

        let low  = generate(vec![('1', '4')]);
        let high = generate(vec![('5', '9')]);

        let sym_dif_low  = set.symmetric_difference(&low);
        let sym_dif_high = set.symmetric_difference(&high);

        let other_low  = generate(vec![('1', '2'), ('5', '6')]);
        let other_high = generate(vec![('3', '4'), ('7', '9')]);

        assert_eq!(sym_dif_low, other_low);
        assert_eq!(sym_dif_high, other_high);
    }
    #[test]
    fn set_symmetric_difference_subset() {
        let set = generate(vec![('2', '7')]);

        let subset      = generate(vec![('3', '6')]);
        let exact_left  = generate(vec![('2', '6')]);
        let exact_right = generate(vec![('3', '7')]);

        let sym_dif_subset = set.symmetric_difference(&subset);
        let sym_dif_left   = set.symmetric_difference(&exact_left);
        let sym_dif_right  = set.symmetric_difference(&exact_right);
        let sym_dif_both   = set.symmetric_difference(&set);

        let other_subset = generate(vec![('2', '2'), ('7', '7')]);
        let other_left   = generate(vec![('7', '7')]);
        let other_right  = generate(vec![('2', '2')]);
        let other_both   = generate(vec![]);

        assert_eq!(sym_dif_subset, other_subset);
        assert_eq!(sym_dif_left, other_left);
        assert_eq!(sym_dif_right, other_right);
        assert_eq!(sym_dif_both, other_both);
    }
    #[test]
    fn set_symmetric_difference_superset() {
        let set      = generate(vec![('2', '7')]);
        let superset = generate(vec![('1', '8')]);

        let sym_dif = set.symmetric_difference(&superset);

        let other = generate(vec![('1', '1'), ('8', '8')]);
        assert_eq!(sym_dif, other);
    }
    fn set_symmetric_difference_disjoint() {
        let set = generate(vec![('3', '4')]);

        let low  = generate(vec![('1', '2')]);
        let high = generate(vec![('5', '6')]);

        let sym_dif_low  = set.symmetric_difference(&low);
        let sym_dif_high = set.symmetric_difference(&high);

        let other_low  = generate(vec![('1', '4')]);
        let other_high = generate(vec![('3', '6')]);

        assert_eq!(sym_dif_low, other_low);
        assert_eq!(sym_dif_high, other_high);
    }
}
<|endoftext|>