<commit_before>use std::ops::{Deref, DerefMut};

use serde_urlencoded;
use serde::de::{self, Deserializer, DeserializeOwned, Visitor, Error as DeError};
use futures::future::{Future, FutureResult, result};

use error::Error;
use httprequest::HttpRequest;

pub trait HttpRequestExtractor<S>: Sized where S: 'static
{
    type Result: Future<Item=Self, Error=Error>;

    fn extract(req: &HttpRequest<S>) -> Self::Result;
}

/// Extract typed information from the request's path.
///
/// `S` - application state type
///
/// ## Example
///
/// ```rust
/// # extern crate bytes;
/// # extern crate actix_web;
/// # extern crate futures;
/// #[macro_use] extern crate serde_derive;
/// # use actix_web::*;
/// use actix_web::Path;
///
/// /// Application state
/// struct State {}
///
/// #[derive(Deserialize)]
/// struct Info {
///     username: String,
/// }
///
/// /// extract path info using serde
/// fn index(info: Path<Info, State>) -> Result<String> {
///     Ok(format!("Welcome {}!", info.username))
/// }
///
/// fn main() {
///     let app = Application::with_state(State{}).resource(
///        "/{username}/index.html",                // <- define path parameters
///        |r| r.method(Method::GET).with(index));  // <- use `with` extractor
/// }
/// ```
pub struct Path<T, S=()>{
    item: T,
    req: HttpRequest<S>,
}

impl<T, S> Deref for Path<T, S> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.item
    }
}

impl<T, S> DerefMut for Path<T, S> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.item
    }
}

impl<T, S> Path<T, S> {

    /// Shared application state
    #[inline]
    pub fn state(&self) -> &S {
        self.req.state()
    }

    /// Incoming request
    #[inline]
    pub fn request(&self) -> &HttpRequest<S> {
        &self.req
    }

    /// Deconstruct instance into a parts
    pub fn into(self) -> (T, HttpRequest<S>) {
        (self.item, self.req)
    }

}

impl<T, S> HttpRequestExtractor<S> for Path<T, S>
    where T: DeserializeOwned, S: 'static
{
    type Result = FutureResult<Self, Error>;

    #[inline]
    fn extract(req: &HttpRequest<S>) -> Self::Result {
        let req = req.clone();
        result(de::Deserialize::deserialize(PathExtractor{req: &req})
               .map_err(|e| e.into())
               .map(|item| Path{item, req}))
    }
}

/// Extract typed information from from the request's query.
///
/// `S` - application state type
///
/// ## Example
///
/// ```rust
/// # extern crate bytes;
/// # extern crate actix_web;
/// # extern crate futures;
/// #[macro_use] extern crate serde_derive;
/// # use actix_web::*;
/// use actix_web::Query;
///
/// /// Application state
/// struct State {}
///
/// #[derive(Deserialize)]
/// struct Info {
///     username: String,
/// }
///
/// // use `with` extractor for query info
/// // this handler get called only if request's query contains `username` field
/// fn index(info: Query<Info, State>) -> Result<String> {
///     Ok(format!("Welcome {}!", info.username))
/// }
///
/// fn main() {
///     let app = Application::with_state(State{}).resource(
///        "/index.html",
///        |r| r.method(Method::GET).with(index)); // <- use `with` extractor
/// }
/// ```
pub struct Query<T, S=()>{
    item: T,
    req: HttpRequest<S>,
}

impl<T, S> Deref for Query<T, S> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.item
    }
}

impl<T, S> DerefMut for Query<T, S> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.item
    }
}

impl<T, S> Query<T, S> {

    /// Shared application state
    #[inline]
    pub fn state(&self) -> &S {
        self.req.state()
    }

    /// Incoming request
    #[inline]
    pub fn request(&self) -> &HttpRequest<S> {
        &self.req
    }

    /// Deconstruct instance into a parts
    pub fn into(self) -> (T, HttpRequest<S>) {
        (self.item, self.req)
    }
}

impl<T, S> HttpRequestExtractor<S> for Query<T, S>
    where T: de::DeserializeOwned, S: 'static
{
    type Result = FutureResult<Self, Error>;

    #[inline]
    fn extract(req: &HttpRequest<S>) -> Self::Result {
        let req = req.clone();
        result(serde_urlencoded::from_str::<T>(req.query_string())
               .map_err(|e| e.into())
               .map(|item| Query{ item, req}))
    }
}

/// Extract typed information from from the request's path and query.
///
/// `S` - application state type
///
/// ## Example
///
/// ```rust
/// # extern crate bytes;
/// # extern crate actix_web;
/// # extern crate futures;
/// #[macro_use] extern crate serde_derive;
/// # use actix_web::*;
/// use actix_web::PathAndQuery;
///
/// /// Application state
/// struct State {}
///
/// #[derive(Deserialize)]
/// struct PathParam {
///     username: String,
/// }
///
/// #[derive(Deserialize)]
/// struct QueryParam {
///     count: u32,
/// }
///
/// // use `with` extractor for query info
/// // this handler get called only if request's path contains `username` field
/// // and query contains `count` field
/// fn index(data: PathAndQuery<PathParam, QueryParam, State>) -> Result<String> {
///     Ok(format!("Welcome {}!", data.path().username))
/// }
///
/// fn main() {
///     let app = Application::with_state(State{}).resource(
///        "/index.html",
///        |r| r.method(Method::GET).with(index)); // <- use `with` extractor
/// }
/// ```
pub struct PathAndQuery<P, Q, S=()>{
    pitem: P,
    qitem: Q,
    req: HttpRequest<S>,
}

impl<P, Q, S> PathAndQuery<P, Q, S> {

    /// Path information
    #[inline]
    pub fn path(&self) -> &P {
        &self.pitem
    }

    /// Query information
    #[inline]
    pub fn query(&self) -> &Q {
        &self.qitem
    }

    /// Shared application state
    #[inline]
    pub fn state(&self) -> &S {
        self.req.state()
    }

    /// Incoming request
    #[inline]
    pub fn request(&self) -> &HttpRequest<S> {
        &self.req
    }

    /// Deconstruct instance into a parts
    pub fn into(self) -> (P, Q, HttpRequest<S>) {
        (self.pitem, self.qitem, self.req)
    }
}

impl<T, Q, S> HttpRequestExtractor<T, S> for PathAndQuery<T, Q, S>
    where T: de::DeserializeOwned, Q: de::DeserializeOwned, S: 'static
{
    type Result = FutureResult<Self, Error>;

    #[inline]
    fn extract(req: &HttpRequest<S>) -> Self::Result {
        let req = req.clone();

        let qitem = match serde_urlencoded::from_str::<Q>(req.query_string())
            .map_err(|e| e.into())
        {
            Ok(item) => item,
            Err(err) => return result(Err(err))
        };
        let pitem = match de::Deserialize::deserialize(PathExtractor{req: &req})
            .map_err(|e| e.into())
        {
            Ok(item) => item,
            Err(err) => return result(Err(err))
        };

        result(Ok(PathAndQuery{pitem, qitem, req}))
    }
}

macro_rules! unsupported_type {
    ($trait_fn:ident, $name:expr) => {
        fn $trait_fn<V>(self, _: V) -> Result<V::Value, Self::Error>
            where V: Visitor<'de>
        {
            Err(de::value::Error::custom(concat!("unsupported type: ", $name)))
        }
    };
}

pub struct PathExtractor<'de, S: 'de> {
    req: &'de HttpRequest<S>
}

impl<'de, S: 'de> Deserializer<'de> for PathExtractor<'de, S>
{
    type Error = de::value::Error;

    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
        where V: Visitor<'de>,
    {
        visitor.visit_map(de::value::MapDeserializer::new(
            self.req.match_info().iter().map(|&(ref k, ref v)| (k.as_ref(), v.as_ref()))))
    }

    fn deserialize_struct<V>(self, _: &'static str, _: &'static [&'static str], visitor: V)
                             -> Result<V::Value, Self::Error>
        where V: Visitor<'de>,
    {
        self.deserialize_map(visitor)
    }

    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
        where
        V: Visitor<'de>,
    {
        visitor.visit_unit()
    }

    fn deserialize_unit_struct<V>(self, _: &'static str, visitor: V)
                                  -> Result<V::Value, Self::Error>
        where V: Visitor<'de>
    {
        self.deserialize_unit(visitor)
    }

    fn deserialize_newtype_struct<V>(self, _: &'static str, visitor: V)
                                     -> Result<V::Value, Self::Error>
        where V: Visitor<'de>,
    {
        visitor.visit_newtype_struct(self)
    }

    fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
        where V: Visitor<'de>
    {
        if self.req.match_info().len() < len {
            Err(de::value::Error::custom(
                format!("wrong number of parameters: {} expected {}",
                        self.req.match_info().len(), len).as_str()))
        } else {
            visitor.visit_seq(de::value::SeqDeserializer::new(
                self.req.match_info().iter().map(|&(_, ref v)| v.as_ref())))
        }
    }

    fn deserialize_tuple_struct<V>(self, _: &'static str, _: usize, visitor: V)
                                   -> Result<V::Value, Self::Error>
        where V: Visitor<'de>
    {
        visitor.visit_seq(de::value::SeqDeserializer::new(
            self.req.match_info().iter().map(|&(_, ref v)| v.as_ref())))
    }

    fn deserialize_enum<V>(self, _: &'static str, _: &'static [&'static str], _: V)
                           -> Result<V::Value, Self::Error>
        where V: Visitor<'de>
    {
        Err(de::value::Error::custom("unsupported type: enum"))
    }

    unsupported_type!(deserialize_any, "'any'");
    unsupported_type!(deserialize_bool, "bool");
    unsupported_type!(deserialize_i8, "i8");
    unsupported_type!(deserialize_i16, "i16");
    unsupported_type!(deserialize_i32, "i32");
    unsupported_type!(deserialize_i64, "i64");
    unsupported_type!(deserialize_u8, "u8");
    unsupported_type!(deserialize_u16, "u16");
    unsupported_type!(deserialize_u32, "u32");
    unsupported_type!(deserialize_u64, "u64");
    unsupported_type!(deserialize_f32, "f32");
    unsupported_type!(deserialize_f64, "f64");
    unsupported_type!(deserialize_char, "char");
    unsupported_type!(deserialize_str, "str");
    unsupported_type!(deserialize_string, "String");
    unsupported_type!(deserialize_bytes, "bytes");
    unsupported_type!(deserialize_byte_buf, "byte buf");
    unsupported_type!(deserialize_option, "Option<T>");
    unsupported_type!(deserialize_seq, "sequence");
    unsupported_type!(deserialize_identifier, "identifier");
    unsupported_type!(deserialize_ignored_any, "ignored_any");
}

#[cfg(test)]
mod tests {
    use router::{Router, Pattern};
    use resource::Resource;
    use test::TestRequest;
    use server::ServerSettings;

    #[derive(Deserialize)]
    struct MyStruct {
        key: String,
        value: String,
    }

    #[derive(Deserialize)]
    struct Id {
        id: String,
    }

    #[test]
    fn test_request_extract() {
        let mut req = TestRequest::with_uri("/name/user1/?id=test").finish();

        let mut resource = Resource::<()>::default();
        resource.name("index");
        let mut routes = Vec::new();
        routes.push((Pattern::new("index", "/{key}/{value}/"), Some(resource)));
        let (router, _) = Router::new("", ServerSettings::default(), routes);
        assert!(router.recognize(&mut req).is_some());

        let s: MyStruct = req.extract_path().unwrap();
        assert_eq!(s.key, "name");
        assert_eq!(s.value, "user1");

        let s: (String, String) = req.extract_path().unwrap();
        assert_eq!(s.0, "name");
        assert_eq!(s.1, "user1");

        let s: Id = req.extract_query().unwrap();
        assert_eq!(s.id, "test");
    }
}
<commit_msg>remove unused code<commit_after>use std::ops::{Deref, DerefMut};

use serde_urlencoded;
use serde::de::{self, Deserializer, DeserializeOwned, Visitor, Error as DeError};
use futures::future::{Future, FutureResult, result};

use error::Error;
use httprequest::HttpRequest;

pub trait HttpRequestExtractor<S>: Sized where S: 'static
{
    type Result: Future<Item=Self, Error=Error>;

    fn extract(req: &HttpRequest<S>) -> Self::Result;
}

/// Extract typed information from the request's path.
///
/// `S` - application state type
///
/// ## Example
///
/// ```rust
/// # extern crate bytes;
/// # extern crate actix_web;
/// # extern crate futures;
/// #[macro_use] extern crate serde_derive;
/// # use actix_web::*;
/// use actix_web::Path;
///
/// /// Application state
/// struct State {}
///
/// #[derive(Deserialize)]
/// struct Info {
///     username: String,
/// }
///
/// /// extract path info using serde
/// fn index(info: Path<Info, State>) -> Result<String> {
///     Ok(format!("Welcome {}!", info.username))
/// }
///
/// fn main() {
///     let app = Application::with_state(State{}).resource(
///        "/{username}/index.html",                // <- define path parameters
///        |r| r.method(Method::GET).with(index));  // <- use `with` extractor
/// }
/// ```
pub struct Path<T, S=()>{
    item: T,
    req: HttpRequest<S>,
}

impl<T, S> Deref for Path<T, S> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.item
    }
}

impl<T, S> DerefMut for Path<T, S> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.item
    }
}

impl<T, S> Path<T, S> {

    /// Shared application state
    #[inline]
    pub fn state(&self) -> &S {
        self.req.state()
    }

    /// Incoming request
    #[inline]
    pub fn request(&self) -> &HttpRequest<S> {
        &self.req
    }

    /// Deconstruct instance into a parts
    pub fn into(self) -> (T, HttpRequest<S>) {
        (self.item, self.req)
    }

}

impl<T, S> HttpRequestExtractor<S> for Path<T, S>
    where T: DeserializeOwned, S: 'static
{
    type Result = FutureResult<Self, Error>;

    #[inline]
    fn extract(req: &HttpRequest<S>) -> Self::Result {
        let req = req.clone();
        result(de::Deserialize::deserialize(PathExtractor{req: &req})
               .map_err(|e| e.into())
               .map(|item| Path{item, req}))
    }
}

/// Extract typed information from from the request's query.
///
/// `S` - application state type
///
/// ## Example
///
/// ```rust
/// # extern crate bytes;
/// # extern crate actix_web;
/// # extern crate futures;
/// #[macro_use] extern crate serde_derive;
/// # use actix_web::*;
/// use actix_web::Query;
///
/// /// Application state
/// struct State {}
///
/// #[derive(Deserialize)]
/// struct Info {
///     username: String,
/// }
///
/// // use `with` extractor for query info
/// // this handler get called only if request's query contains `username` field
/// fn index(info: Query<Info, State>) -> Result<String> {
///     Ok(format!("Welcome {}!", info.username))
/// }
///
/// fn main() {
///     let app = Application::with_state(State{}).resource(
///        "/index.html",
///        |r| r.method(Method::GET).with(index)); // <- use `with` extractor
/// }
/// ```
pub struct Query<T, S=()>{
    item: T,
    req: HttpRequest<S>,
}

impl<T, S> Deref for Query<T, S> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.item
    }
}

impl<T, S> DerefMut for Query<T, S> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.item
    }
}

impl<T, S> Query<T, S> {

    /// Shared application state
    #[inline]
    pub fn state(&self) -> &S {
        self.req.state()
    }

    /// Incoming request
    #[inline]
    pub fn request(&self) -> &HttpRequest<S> {
        &self.req
    }

    /// Deconstruct instance into a parts
    pub fn into(self) -> (T, HttpRequest<S>) {
        (self.item, self.req)
    }
}

impl<T, S> HttpRequestExtractor<S> for Query<T, S>
    where T: de::DeserializeOwned, S: 'static
{
    type Result = FutureResult<Self, Error>;

    #[inline]
    fn extract(req: &HttpRequest<S>) -> Self::Result {
        let req = req.clone();
        result(serde_urlencoded::from_str::<T>(req.query_string())
               .map_err(|e| e.into())
               .map(|item| Query{ item, req}))
    }
}

macro_rules! unsupported_type {
    ($trait_fn:ident, $name:expr) => {
        fn $trait_fn<V>(self, _: V) -> Result<V::Value, Self::Error>
            where V: Visitor<'de>
        {
            Err(de::value::Error::custom(concat!("unsupported type: ", $name)))
        }
    };
}

pub struct PathExtractor<'de, S: 'de> {
    req: &'de HttpRequest<S>
}

impl<'de, S: 'de> Deserializer<'de> for PathExtractor<'de, S>
{
    type Error = de::value::Error;

    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
        where V: Visitor<'de>,
    {
        visitor.visit_map(de::value::MapDeserializer::new(
            self.req.match_info().iter().map(|&(ref k, ref v)| (k.as_ref(), v.as_ref()))))
    }

    fn deserialize_struct<V>(self, _: &'static str, _: &'static [&'static str], visitor: V)
                             -> Result<V::Value, Self::Error>
        where V: Visitor<'de>,
    {
        self.deserialize_map(visitor)
    }

    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
        where
        V: Visitor<'de>,
    {
        visitor.visit_unit()
    }

    fn deserialize_unit_struct<V>(self, _: &'static str, visitor: V)
                                  -> Result<V::Value, Self::Error>
        where V: Visitor<'de>
    {
        self.deserialize_unit(visitor)
    }

    fn deserialize_newtype_struct<V>(self, _: &'static str, visitor: V)
                                     -> Result<V::Value, Self::Error>
        where V: Visitor<'de>,
    {
        visitor.visit_newtype_struct(self)
    }

    fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
        where V: Visitor<'de>
    {
        if self.req.match_info().len() < len {
            Err(de::value::Error::custom(
                format!("wrong number of parameters: {} expected {}",
                        self.req.match_info().len(), len).as_str()))
        } else {
            visitor.visit_seq(de::value::SeqDeserializer::new(
                self.req.match_info().iter().map(|&(_, ref v)| v.as_ref())))
        }
    }

    fn deserialize_tuple_struct<V>(self, _: &'static str, _: usize, visitor: V)
                                   -> Result<V::Value, Self::Error>
        where V: Visitor<'de>
    {
        visitor.visit_seq(de::value::SeqDeserializer::new(
            self.req.match_info().iter().map(|&(_, ref v)| v.as_ref())))
    }

    fn deserialize_enum<V>(self, _: &'static str, _: &'static [&'static str], _: V)
                           -> Result<V::Value, Self::Error>
        where V: Visitor<'de>
    {
        Err(de::value::Error::custom("unsupported type: enum"))
    }

    unsupported_type!(deserialize_any, "'any'");
    unsupported_type!(deserialize_bool, "bool");
    unsupported_type!(deserialize_i8, "i8");
    unsupported_type!(deserialize_i16, "i16");
    unsupported_type!(deserialize_i32, "i32");
    unsupported_type!(deserialize_i64, "i64");
    unsupported_type!(deserialize_u8, "u8");
    unsupported_type!(deserialize_u16, "u16");
    unsupported_type!(deserialize_u32, "u32");
    unsupported_type!(deserialize_u64, "u64");
    unsupported_type!(deserialize_f32, "f32");
    unsupported_type!(deserialize_f64, "f64");
    unsupported_type!(deserialize_char, "char");
    unsupported_type!(deserialize_str, "str");
    unsupported_type!(deserialize_string, "String");
    unsupported_type!(deserialize_bytes, "bytes");
    unsupported_type!(deserialize_byte_buf, "byte buf");
    unsupported_type!(deserialize_option, "Option<T>");
    unsupported_type!(deserialize_seq, "sequence");
    unsupported_type!(deserialize_identifier, "identifier");
    unsupported_type!(deserialize_ignored_any, "ignored_any");
}

#[cfg(test)]
mod tests {
    use router::{Router, Pattern};
    use resource::Resource;
    use test::TestRequest;
    use server::ServerSettings;

    #[derive(Deserialize)]
    struct MyStruct {
        key: String,
        value: String,
    }

    #[derive(Deserialize)]
    struct Id {
        id: String,
    }

    #[test]
    fn test_request_extract() {
        let mut req = TestRequest::with_uri("/name/user1/?id=test").finish();

        let mut resource = Resource::<()>::default();
        resource.name("index");
        let mut routes = Vec::new();
        routes.push((Pattern::new("index", "/{key}/{value}/"), Some(resource)));
        let (router, _) = Router::new("", ServerSettings::default(), routes);
        assert!(router.recognize(&mut req).is_some());

        let s: MyStruct = req.extract_path().unwrap();
        assert_eq!(s.key, "name");
        assert_eq!(s.value, "user1");

        let s: (String, String) = req.extract_path().unwrap();
        assert_eq!(s.0, "name");
        assert_eq!(s.1, "user1");

        let s: Id = req.extract_query().unwrap();
        assert_eq!(s.id, "test");
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;
use std::mem;
use session_types::*;
use peano::{Peano,Pop};
use super::{IO, Transfers};

/// A `Protocol` describes the underlying protocol, including the "initial" session
/// type. `Handler`s are defined over concrete `Protocol`s to implement the behavior
/// of a protocol in a given `SessionType`.
pub trait Protocol {
    type Initial: SessionType;
}

/// Handlers must return `Defer` to indicate to the `Session` how to proceed in
/// the future. `Defer` can be obtained by calling `.defer()` on the channel, or
/// by calling `.close()` when the session is `End`.
pub struct Defer
 {
    io: Option,
    func: DeferFunc
,
    open: bool,
    _marker: PhantomData

}

impl
 Defer
 {
    pub fn new(io: I, next: DeferFunc
, open: bool)
               -> Defer

    {
        Defer {
            io: Some(io),
            func: next,
            open: open,
            _marker: PhantomData
        }
    }
}

impl
 Defer
 {
    pub fn with(&mut self) -> bool {
        let p: Channel
 = Channel(self.io.take().unwrap(), PhantomData);

        let mut new = (self.func)(p);
        self.func = new.func;
        self.open = new.open;
        self.io = Some(new.io.take().unwrap());

        self.open
    }
}

#[doc(hidden)]
pub type DeferFunc
 = fn(Channel
) -> Defer
;

/// Channels are provided to handlers to act as a "courier" for the session type
/// and a guard for the IO backend.
pub struct Channel
(I, PhantomData<(P, E, S)>);

/// `Handler` is implemented on `Protocol` for every session type you expect to defer,
/// including the initial state.
pub trait Handler: Protocol + Sized {
    /// Given a channel in a particular state, with a particular environment,
    /// do whatever you'd like with the channel and return `Defer`, which you
    /// can obtain by doing `.defer()` on the channel or `.close()` on the
    /// channel.
    fn with(Channel<Self, I, E, S>) -> Defer<Self, I>;
}

pub fn channel
(io: I) -> Channel
 {
    Channel(io, PhantomData)
}

pub fn channel_dual
(io: I) -> Channel {
    Channel(io, PhantomData)
}

impl<I, E: SessionType, S: SessionType, P: Handler> Channel
 {
    /// Defer the rest of the protocol execution. Useful for returning early.
    ///
    /// There must be a [`Handler`](trait.Handler.html) implemented for the protocol state you're deferring.
    pub fn defer(self) -> Defer
 {
        let next_func: DeferFunc
 = Handler::::with;

        Defer::new(self.0, unsafe { mem::transmute(next_func) }, true)
    }
}

impl Channel
 {
    /// Close the channel. Only possible if it's in the `End` state.
    pub fn close(mut self) -> Defer
 {
        unsafe { self.0.close() };

        let next_func: DeferFunc
 = Dummy::
::with;

        Defer::new(self.0, unsafe { mem::transmute(next_func) }, false)
    }
}

impl<I: Transfers<T>, T, E: SessionType, S: SessionType, P: Protocol> Channel<P, I, E, Send<T, S>> {
    /// Send a `T` to IO.
    pub fn send(mut self, a: T) -> Channel
 {
        unsafe { self.0.send(a) };

        Channel(self.0, PhantomData)
    }
}

impl<I: Transfers<T>, T, E: SessionType, S: SessionType, P: Protocol> Channel<P, I, E, Recv<T, S>> {
    /// Receive a `T` from IO.
    pub fn recv(mut self) -> Result<(T, Channel
), Self> {
        match unsafe { self.0.recv() } {
            Some(res) => Ok((res, Channel(self.0, PhantomData))),
            None => {
                Err(self)
            }
        }
    }
}

impl Channel<P, I, E, Nest<S>> {
    /// Enter into a nested protocol.
    pub fn enter(self) -> Channel
 {
        Channel(self.0, PhantomData)
    }
}

impl<I, N: Peano, E: SessionType + Pop<N>, P: Protocol> Channel<P, I, E, Escape<N>> {
    /// Escape from a nested protocol.
    pub fn pop(self) -> Channel
 {
        Channel(self.0, PhantomData)
    }
}

impl Channel
 {
    /// Select a protocol to advance to.
    pub fn choose<S: SessionType>(mut self) -> Channel
 where R: Chooser<S> {
        unsafe { self.0.send_varint(R::num()); }

        Channel(self.0, PhantomData)
    }
}

impl<I: IO, // Our IO
         E: SessionType, // Our current environment
         S: SessionType, // The first branch of our accepting session
         Q: SessionType, // The second branch of our accepting session
         P: Handler<I, E, Accept<S, Q>> // We must be able to handle our current state
            + Acceptor<I, E, Accept<S, Q>> // And we must be able to "accept" with our current state
    > Channel<P, I, E, Accept<S, Q>> {
    /// Accept one of many protocols and advance to its handler.
    pub fn accept(mut self) -> Defer
 {
        match unsafe { self.0.recv_varint() } {
            Some(num) => {
                <P as Acceptor<I, E, Accept<S, Q>>>::defer(self.0, num)
            },
            None => {
                self.defer()
            }
        }
    }
}

struct Dummy
(PhantomData<(P, I, E, S)>);
impl Dummy
 {
    fn with(_: Channel
) -> Defer
 {
        panic!("Channel was closed!");
    }
}<commit_msg>Turn Channel into a struct<commit_after>use std::marker::PhantomData;
use std::mem;
use session_types::*;
use peano::{Peano,Pop};
use super::{IO, Transfers};

/// A `Protocol` describes the underlying protocol, including the "initial" session
/// type. `Handler`s are defined over concrete `Protocol`s to implement the behavior
/// of a protocol in a given `SessionType`.
pub trait Protocol {
    type Initial: SessionType;
}

/// Handlers must return `Defer` to indicate to the `Session` how to proceed in
/// the future. `Defer` can be obtained by calling `.defer()` on the channel, or
/// by calling `.close()` when the session is `End`.
pub struct Defer
 {
    io: Option,
    func: DeferFunc
,
    open: bool,
    _marker: PhantomData

}

impl
 Defer
 {
    pub fn new(io: I, next: DeferFunc
, open: bool)
               -> Defer

    {
        Defer {
            io: Some(io),
            func: next,
            open: open,
            _marker: PhantomData
        }
    }
}

impl
 Defer
 {
    pub fn with(&mut self) -> bool {
        let p: Channel
 = Channel::new(self.io.take().unwrap());

        let mut new = (self.func)(p);
        self.func = new.func;
        self.open = new.open;
        self.io = Some(new.io.take().unwrap());

        self.open
    }
}

#[doc(hidden)]
pub type DeferFunc
 = fn(Channel
) -> Defer
;

/// Channels are provided to handlers to act as a "courier" for the session type
/// and a guard for the IO backend.
pub struct Channel
 {
    io: I,
    _marker: PhantomData<(P, E, S)>
}

impl
 Channel
 {
    fn new(io: I) -> Channel
 {
        Channel {
            io: io,
            _marker: PhantomData
        }
    }
}

/// `Handler` is implemented on `Protocol` for every session type you expect to defer,
/// including the initial state.
pub trait Handler: Protocol + Sized {
    /// Given a channel in a particular state, with a particular environment,
    /// do whatever you'd like with the channel and return `Defer`, which you
    /// can obtain by doing `.defer()` on the channel or `.close()` on the
    /// channel.
    fn with(Channel<Self, I, E, S>) -> Defer<Self, I>;
}

pub fn channel
(io: I) -> Channel
 {
    Channel::new(io)
}

pub fn channel_dual
(io: I) -> Channel {
    Channel::new(io)
}

impl<I, E: SessionType, S: SessionType, P: Handler> Channel
 {
    /// Defer the rest of the protocol execution. Useful for returning early.
    ///
    /// There must be a [`Handler`](trait.Handler.html) implemented for the protocol state you're deferring.
    pub fn defer(self) -> Defer
 {
        let next_func: DeferFunc
 = Handler::::with;

        Defer::new(self.io, unsafe { mem::transmute(next_func) }, true)
    }
}

impl Channel
 {
    /// Close the channel. Only possible if it's in the `End` state.
    pub fn close(mut self) -> Defer
 {
        unsafe { self.io.close() };

        let next_func: DeferFunc
 = Dummy::
::with;

        Defer::new(self.io, unsafe { mem::transmute(next_func) }, false)
    }
}

impl<I: Transfers<T>, T, E: SessionType, S: SessionType, P: Protocol> Channel<P, I, E, Send<T, S>> {
    /// Send a `T` to IO.
    pub fn send(mut self, a: T) -> Channel
 {
        unsafe { self.io.send(a) };

        Channel::new(self.io)
    }
}

impl<I: Transfers<T>, T, E: SessionType, S: SessionType, P: Protocol> Channel<P, I, E, Recv<T, S>> {
    /// Receive a `T` from IO.
    pub fn recv(mut self) -> Result<(T, Channel
), Self> {
        match unsafe { self.io.recv() } {
            Some(res) => Ok((res, Channel::new(self.io))),
            None => {
                Err(self)
            }
        }
    }
}

impl Channel<P, I, E, Nest<S>> {
    /// Enter into a nested protocol.
    pub fn enter(self) -> Channel
 {
        Channel::new(self.io)
    }
}

impl<I, N: Peano, E: SessionType + Pop<N>, P: Protocol> Channel<P, I, E, Escape<N>> {
    /// Escape from a nested protocol.
    pub fn pop(self) -> Channel
 {
        Channel::new(self.io)
    }
}

impl Channel
 {
    /// Select a protocol to advance to.
    pub fn choose<S: SessionType>(mut self) -> Channel
 where R: Chooser<S> {
        unsafe { self.io.send_varint(R::num()); }

        Channel::new(self.io)
    }
}

impl<I: IO, // Our IO
         E: SessionType, // Our current environment
         S: SessionType, // The first branch of our accepting session
         Q: SessionType, // The second branch of our accepting session
         P: Handler<I, E, Accept<S, Q>> // We must be able to handle our current state
            + Acceptor<I, E, Accept<S, Q>> // And we must be able to "accept" with our current state
    > Channel<P, I, E, Accept<S, Q>> {
    /// Accept one of many protocols and advance to its handler.
    pub fn accept(mut self) -> Defer
 {
        match unsafe { self.io.recv_varint() } {
            Some(num) => {
                <P as Acceptor<I, E, Accept<S, Q>>>::defer(self.io, num)
            },
            None => {
                self.defer()
            }
        }
    }
}

struct Dummy
(PhantomData<(P, I, E, S)>);
impl Dummy
 {
    fn with(_: Channel
) -> Defer
 {
        panic!("Channel was closed!");
    }
}<|endoftext|>


<commit_before>use std::io::{Read, Write};
use std::mem::size_of;
use std::net::{
    TcpStream,
    ToSocketAddrs
};
use byteorder::{ReadBytesExt, BigEndian, WriteBytesExt};

enum Types {
    Request = 0x80,
    Response = 0x81
}

enum Commands {
    Get = 0x00,
    Set = 0x01,
    Add = 0x02,
    Replace = 0x03,
    Delete = 0x04,
    Increment = 0x05,
    Decrement = 0x06,
    Quit = 0x07,
    Flush = 0x08,
    GetQ = 0x09,
    NoOp = 0x0A,
    Version = 0x0B,
    GetK = 0x0C,
    GetKQ = 0x0D,
    Append = 0x0E,
    Prepend = 0x0F,
    Stat = 0x10,
    SetQ = 0x11,
    AddQ = 0x12,
    ReplaceQ = 0x13,
    DeleteQ = 0x14,
    IncrementQ = 0x15,
    DecrementQ = 0x16,
    QuitQ = 0x17,
    FlushQ = 0x18,
    AppendQ = 0x19,
    PrependQ = 0x1A
}

pub struct Request {
    magic: u8,
    opcode: u8,
    key_length: u16,
    extras_length: u8,
    data_type: u8,
    reserved: u16,
    body_length: u32,
    opaque: u32,
    cas: u64
}

pub struct Response {
    magic: u8,
    opcode: u8,
    key_length: u16,
    extras_length: u8,
    data_type: u8,
    status: u16,
    opaque: u32,
    cas: u64
}

pub struct SetAddReplace {
    flags: u32,
    expiration: u32
}

pub struct Protocol {
    connection: TcpStream
}

impl Protocol {
    pub fn connect<A: ToSocketAddrs>(addr: A) -> Protocol {
        assert_eq!(size_of::<Response>(), 24);
        Protocol{connection: TcpStream::connect(addr).unwrap()}
    }

    fn set(&mut self, key: &'static str, value: &'static str, time: u32) -> usize {
        let extras_length = size_of::<SetAddReplace>() as u8;
        let request = Request{magic: Types::Request as u8, opcode: Commands::Set as u8,
            key_length: key.len() as u16,
            extras_length: extras_length,
            data_type: 0, reserved: 0, body_length: value.len() as u32 + extras_length as u32,
            opaque: 0, cas: 0x00};
        let mut buf = vec![];
        buf.write_u8(request.magic).unwrap();
        buf.write_u8(request.opcode).unwrap();
        buf.write_u16::<BigEndian>(request.key_length).unwrap();
        buf.write_u8(request.extras_length).unwrap();
        buf.write_u8(request.data_type).unwrap();
        buf.write_u16::<BigEndian>(request.reserved).unwrap();
        buf.write_u32::<BigEndian>(request.body_length).unwrap();
        buf.write_u32::<BigEndian>(request.opaque).unwrap();
        buf.write_u64::<BigEndian>(request.cas).unwrap();
        // Flags
        buf.write_u32::<BigEndian>(0);
        buf.write_u32::<BigEndian>(time).unwrap();
        buf.write(key.as_bytes()).unwrap();
        buf.write(value.as_bytes()).unwrap();
        println!("{:?} {}", buf, buf.len());
        let wrote_size = self.connection.write(buf.as_slice()).unwrap();
        let mut outbuf = [0; 24];
        self.connection.read_exact(&mut outbuf).unwrap();
        println!("{:?} {}", outbuf, outbuf.len());
        wrote_size
    }
}

#[test]
fn test_set_key() {
    let mut p = Protocol::connect("127.0.0.1:11211");
    assert_eq!(p.set("abc", "123", 100), 201);
}
<commit_msg>Ugly get works but it is time to refactor<commit_after>use std::io::{Cursor, Read, Write};
use std::mem::size_of;
use std::net::{
    TcpStream,
    ToSocketAddrs
};
use std::str::{
    from_utf8
};

use byteorder::{ReadBytesExt, BigEndian, WriteBytesExt};

enum Types {
    Request = 0x80,
    Response = 0x81
}

#[derive(Debug)]
enum Commands {
    Get = 0x00,
    Set = 0x01,
    Add = 0x02,
    Replace = 0x03,
    Delete = 0x04,
    Increment = 0x05,
    Decrement = 0x06,
    Quit = 0x07,
    Flush = 0x08,
    GetQ = 0x09,
    NoOp = 0x0A,
    Version = 0x0B,
    GetK = 0x0C,
    GetKQ = 0x0D,
    Append = 0x0E,
    Prepend = 0x0F,
    Stat = 0x10,
    SetQ = 0x11,
    AddQ = 0x12,
    ReplaceQ = 0x13,
    DeleteQ = 0x14,
    IncrementQ = 0x15,
    DecrementQ = 0x16,
    QuitQ = 0x17,
    FlushQ = 0x18,
    AppendQ = 0x19,
    PrependQ = 0x1A
}

pub struct Request {
    magic: u8,
    opcode: u8,
    key_length: u16,
    extras_length: u8,
    data_type: u8,
    reserved: u16,
    body_length: u32,
    opaque: u32,
    cas: u64
}

pub struct Response {
    magic: u8,
    opcode: u8,
    key_length: u16,
    extras_length: u8,
    data_type: u8,
    status: u16,
    opaque: u32,
    cas: u64
}

pub struct SetAddReplace {
    flags: u32,
    expiration: u32
}

pub struct Protocol {
    connection: TcpStream
}

impl Protocol {
    pub fn connect<A: ToSocketAddrs>(addr: A) -> Protocol {
        assert_eq!(size_of::<Response>(), 24);
        Protocol{connection: TcpStream::connect(addr).unwrap()}
    }

    fn set(&mut self, key: &'static str, value: &'static str, time: u32) -> usize {
        let extras_length = size_of::<SetAddReplace>() as u8;
        println!("Using command {:?} with value {:?}", Commands::Set, Commands::Set as u8);
        println!("Extras length {:?}", extras_length);
        let request = Request{magic: Types::Request as u8, opcode: Commands::Set as u8,
            key_length: key.len() as u16,
            extras_length: extras_length,
            data_type: 0, reserved: 0, body_length: key.len() as u32 + value.len() as u32 + extras_length as u32,
            opaque: 0, cas: 0x00};
        let mut buf = vec![];
        buf.write_u8(request.magic).unwrap();
        buf.write_u8(request.opcode).unwrap();
        buf.write_u16::<BigEndian>(request.key_length).unwrap();
        buf.write_u8(request.extras_length).unwrap();
        buf.write_u8(request.data_type).unwrap();
        buf.write_u16::<BigEndian>(request.reserved).unwrap();
        buf.write_u32::<BigEndian>(request.body_length).unwrap();
        buf.write_u32::<BigEndian>(request.opaque).unwrap();
        buf.write_u64::<BigEndian>(request.cas).unwrap();
        // Flags
        buf.write_u32::<BigEndian>(0);
        buf.write_u32::<BigEndian>(time).unwrap();
        buf.write(key.as_bytes()).unwrap();
        buf.write(value.as_bytes()).unwrap();
        println!("{:?} {}", buf, buf.len());
        let wrote_size = self.connection.write(buf.as_slice()).unwrap();
        let mut outbuf = [0; 24];
        self.connection.read_exact(&mut outbuf).unwrap();
        println!("{:?} {}", outbuf, outbuf.len());
        wrote_size
    }

    fn get(&mut self, key: &'static str) -> String {
        println!("Get");
        let request = Request{magic: Types::Request as u8, opcode: Commands::Get as u8,
            key_length: key.len() as u16,
            extras_length: 0,
            data_type: 0, reserved: 0, body_length: key.len() as u32,
            opaque: 0, cas: 0x00};
            let mut buf = vec![];
            buf.write_u8(request.magic).unwrap();
            buf.write_u8(request.opcode).unwrap();
            buf.write_u16::<BigEndian>(request.key_length).unwrap();
            buf.write_u8(request.extras_length).unwrap();
            buf.write_u8(request.data_type).unwrap();
            buf.write_u16::<BigEndian>(request.reserved).unwrap();
            buf.write_u32::<BigEndian>(request.body_length).unwrap();
            buf.write_u32::<BigEndian>(request.opaque).unwrap();
            buf.write_u64::<BigEndian>(request.cas).unwrap();
            buf.write(key.as_bytes()).unwrap();
            println!("Request read {:?}", buf);
            self.connection.write(buf.as_slice()).unwrap();
            let mut outbuf = [0; 24];
            self.connection.read_exact(&mut outbuf).unwrap();
            println!("Got {:?} of size {:?}", outbuf, outbuf.len());
            let mut cur = Cursor::new(outbuf);
            assert_eq!(Types::Response as u8, cur.read_u8().unwrap());
            let mut read_return = [0; 5];
            self.connection.read_u32::<BigEndian>().unwrap();
            self.connection.read_exact(&mut read_return);
            let a = from_utf8(&read_return).unwrap();
            a.to_owned()
    }
}

#[test]
fn test_set_key() {
    let mut p = Protocol::connect("127.0.0.1:11211");
    assert_eq!(p.set("Hello", "World", 100), 201);
}

#[test]
fn test_get_key() {
    let mut p = Protocol::connect("127.0.0.1:11211");
    p.set("Hello", "World", 100);
    assert_eq!(p.get("Hello"),  "World");
}
<|endoftext|>


<commit_before>use triangle::*;

#[test]
fn positive_length_sides_are_ok() {
    let sides = [2, 2, 2];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_some());
}

#[test]
#[ignore]
fn zero_length_sides_are_illegal() {
    let sides = [0, 0, 0];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
fn one_length_zero_side_first() {
    let sides = [0, 2, 2];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
fn one_length_zero_side_second() {
    let sides = [2, 0, 2];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
fn one_length_zero_side_third() {
    let sides = [2, 2, 0];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
fn equilateral_triangles_have_equal_sides() {
    let sides = [2, 2, 2];
    let triangle = Triangle::build(sides).unwrap();
    assert!(triangle.is_equilateral());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn larger_equilateral_triangles_have_equal_sides() {
    let sides = [10, 10, 10];
    let triangle = Triangle::build(sides).unwrap();
    assert!(triangle.is_equilateral());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn isosceles_triangles_have_two_equal_sides_one() {
    let sides = [3, 4, 4];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(triangle.is_isosceles());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn isosceles_triangles_have_two_equal_sides_two() {
    let sides = [4, 4, 3];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(triangle.is_isosceles());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn isosceles_triangles_have_two_equal_sides_three() {
    let sides = [4, 3, 4];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(triangle.is_isosceles());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn isosceles_triangles_have_two_equal_sides_four() {
    let sides = [4, 7, 4];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(triangle.is_isosceles());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn scalene_triangle_has_no_equal_sides_one() {
    let sides = [3, 4, 5];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(!triangle.is_isosceles());
    assert!(triangle.is_scalene());
}

#[test]
#[ignore]
fn scalene_triangle_has_no_equal_sides_two() {
    let sides = [5, 4, 6];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(!triangle.is_isosceles());
    assert!(triangle.is_scalene());
}

#[test]
#[ignore]
fn scalene_triangle_has_no_equal_sides_three() {
    let sides = [10, 11, 12];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(!triangle.is_isosceles());
    assert!(triangle.is_scalene());
}

#[test]
#[ignore]
fn scalene_triangle_has_no_equal_sides_four() {
    let sides = [5, 4, 2];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(!triangle.is_isosceles());
    assert!(triangle.is_scalene());
}

#[test]
#[ignore]
fn sum_of_two_sides_must_equal_or_exceed_the_remaining_side_one() {
    let sides = [7, 3, 2];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
fn sum_of_two_sides_must_equal_or_exceed_the_remaining_side_two() {
    let sides = [1, 1, 3];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
#[cfg(feature = "generic")]
fn scalene_triangle_with_floating_point_sides() {
    let sides = [0.4, 0.6, 0.3];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(!triangle.is_isosceles());
    assert!(triangle.is_scalene());
}

#[test]
#[ignore]
#[cfg(feature = "generic")]
fn equilateral_triangles_with_floating_point_sides() {
    let sides = [0.2, 0.2, 0.2];
    let triangle = Triangle::build(sides).unwrap();
    assert!(triangle.is_equilateral());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
#[cfg(feature = "generic")]
fn isosceles_triangle_with_floating_point_sides() {
    let sides = [0.3, 0.4, 0.4];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(triangle.is_isosceles());
    assert!(!triangle.is_scalene());
}
<commit_msg>triangle: Add invalid floating-point tests (#879)<commit_after>use triangle::*;

#[test]
fn positive_length_sides_are_ok() {
    let sides = [2, 2, 2];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_some());
}

#[test]
#[ignore]
fn zero_length_sides_are_illegal() {
    let sides = [0, 0, 0];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
fn one_length_zero_side_first() {
    let sides = [0, 2, 2];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
fn one_length_zero_side_second() {
    let sides = [2, 0, 2];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
fn one_length_zero_side_third() {
    let sides = [2, 2, 0];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
fn equilateral_triangles_have_equal_sides() {
    let sides = [2, 2, 2];
    let triangle = Triangle::build(sides).unwrap();
    assert!(triangle.is_equilateral());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn larger_equilateral_triangles_have_equal_sides() {
    let sides = [10, 10, 10];
    let triangle = Triangle::build(sides).unwrap();
    assert!(triangle.is_equilateral());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn isosceles_triangles_have_two_equal_sides_one() {
    let sides = [3, 4, 4];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(triangle.is_isosceles());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn isosceles_triangles_have_two_equal_sides_two() {
    let sides = [4, 4, 3];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(triangle.is_isosceles());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn isosceles_triangles_have_two_equal_sides_three() {
    let sides = [4, 3, 4];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(triangle.is_isosceles());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn isosceles_triangles_have_two_equal_sides_four() {
    let sides = [4, 7, 4];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(triangle.is_isosceles());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
fn scalene_triangle_has_no_equal_sides_one() {
    let sides = [3, 4, 5];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(!triangle.is_isosceles());
    assert!(triangle.is_scalene());
}

#[test]
#[ignore]
fn scalene_triangle_has_no_equal_sides_two() {
    let sides = [5, 4, 6];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(!triangle.is_isosceles());
    assert!(triangle.is_scalene());
}

#[test]
#[ignore]
fn scalene_triangle_has_no_equal_sides_three() {
    let sides = [10, 11, 12];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(!triangle.is_isosceles());
    assert!(triangle.is_scalene());
}

#[test]
#[ignore]
fn scalene_triangle_has_no_equal_sides_four() {
    let sides = [5, 4, 2];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(!triangle.is_isosceles());
    assert!(triangle.is_scalene());
}

#[test]
#[ignore]
fn sum_of_two_sides_must_equal_or_exceed_the_remaining_side_one() {
    let sides = [7, 3, 2];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
fn sum_of_two_sides_must_equal_or_exceed_the_remaining_side_two() {
    let sides = [1, 1, 3];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
#[cfg(feature = "generic")]
fn scalene_triangle_with_floating_point_sides() {
    let sides = [0.4, 0.6, 0.3];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(!triangle.is_isosceles());
    assert!(triangle.is_scalene());
}

#[test]
#[ignore]
#[cfg(feature = "generic")]
fn equilateral_triangles_with_floating_point_sides() {
    let sides = [0.2, 0.2, 0.2];
    let triangle = Triangle::build(sides).unwrap();
    assert!(triangle.is_equilateral());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
#[cfg(feature = "generic")]
fn isosceles_triangle_with_floating_point_sides() {
    let sides = [0.3, 0.4, 0.4];
    let triangle = Triangle::build(sides).unwrap();
    assert!(!triangle.is_equilateral());
    assert!(triangle.is_isosceles());
    assert!(!triangle.is_scalene());
}

#[test]
#[ignore]
#[cfg(feature = "generic")]
fn invalid_triangle_with_floating_point_sides_one() {
    let sides = [0.0, 0.4, 0.3];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}

#[test]
#[ignore]
#[cfg(feature = "generic")]
fn invalid_triangle_with_floating_point_sides_two() {
    let sides = [0.1, 0.3, 0.5];
    let triangle = Triangle::build(sides);
    assert!(triangle.is_none());
}
<|endoftext|>


<commit_before>//! A simple wait-free, grow-only pagetable, assumes a dense keyspace.
#![allow(unsafe_code)]

use std::{
    alloc::{alloc_zeroed, Layout},
    convert::TryFrom,
    mem::{align_of, size_of},
    sync::atomic::{
        AtomicPtr,
        Ordering::{Acquire, Relaxed, Release},
    },
};

use crate::debug_delay;

#[allow(unused)]
#[doc(hidden)]
pub const PAGETABLE_NODE_SZ: usize = size_of::<Node1<()>>();

const FAN_FACTOR: usize = 18;
const FAN_OUT: usize = 1 << FAN_FACTOR;
const FAN_MASK: usize = FAN_OUT - 1;

pub type PageId = u64;

struct Node1<T: Send + 'static> {
    children: [AtomicPtr<Node2<T>>; FAN_OUT],
}

struct Node2<T: Send + 'static> {
    children: [AtomicPtr<T>; FAN_OUT],
}

impl<T: Send + 'static> Node1<T> {
    fn new() -> Box<Self> {
        let size = size_of::<Self>();
        let align = align_of::<Self>();

        unsafe {
            let layout = Layout::from_size_align_unchecked(size, align);

            #[allow(clippy::cast_ptr_alignment)]
            let ptr = alloc_zeroed(layout) as *mut Self;

            Box::from_raw(ptr)
        }
    }
}

impl<T: Send + 'static> Node2<T> {
    fn new() -> Box<Self> {
        let size = size_of::<Self>();
        let align = align_of::<Self>();

        unsafe {
            let layout = Layout::from_size_align_unchecked(size, align);

            #[allow(clippy::cast_ptr_alignment)]
            let ptr = alloc_zeroed(layout) as *mut Self;

            Box::from_raw(ptr)
        }
    }
}

impl<T: Send + 'static> Drop for Node1<T> {
    fn drop(&mut self) {
        drop_iter(self.children.iter());
    }
}

impl<T: Send + 'static> Drop for Node2<T> {
    fn drop(&mut self) {
        drop_iter(self.children.iter());
    }
}

fn drop_iter<T>(iter: core::slice::Iter<'_, AtomicPtr<T>>) {
    for child in iter {
        let shared_child = child.load(Relaxed);
        if shared_child.is_null() {
            // this does not leak because the PageTable is
            // assumed to be dense.
            break;
        }
        unsafe {
            drop(Box::from_raw(shared_child));
        }
    }
}

/// A simple lock-free radix tree.
pub struct PageTable<T>
where
    T: 'static + Send + Sync,
{
    head: AtomicPtr<Node1<T>>,
}

impl<T> Default for PageTable<T>
where
    T: 'static + Send + Sync,
{
    fn default() -> Self {
        let head = Node1::new();
        Self { head: AtomicPtr::from(Box::into_raw(head)) }
    }
}

impl<T> PageTable<T>
where
    T: 'static + Send + Sync,
{
    /// # Panics
    ///
    /// will panic if the item is not null already,
    /// which represents a serious failure to
    /// properly handle lifecycles of pages in the
    /// using system.
    pub fn insert(&self, pid: PageId, item: T) {
        debug_delay();
        let tip = traverse(self.head.load(Acquire), pid);

        let old = tip.swap(Box::into_raw(Box::new(item)), Release);
        assert!(old.is_null());
    }

    /// Try to get a value from the tree.
    pub fn get<'g>(&self, pid: PageId) -> Option<&'g T> {
        debug_delay();
        let tip = traverse(self.head.load(Acquire), pid);

        let res = tip.load(Acquire);
        if res.is_null() {
            None
        } else {
            Some(unsafe { &*res })
        }
    }
}

fn traverse<'g, T: 'static + Send>(
    head: *mut Node1<T>,
    k: PageId,
) -> &'g AtomicPtr<T> {
    let (l1k, l2k) = split_fanout(k);

    debug_delay();
    let l1 = unsafe { &(*head).children };

    debug_delay();
    let mut l2_ptr = l1[l1k].load(Acquire);

    if l2_ptr.is_null() {
        let next_child = Box::into_raw(Node2::new());

        debug_delay();
        let ret =
            l1[l1k].compare_and_swap(std::ptr::null_mut(), next_child, Release);

        if ret.is_null() {
            // success
            l2_ptr = next_child;
        } else {
            unsafe {
                drop(Box::from_raw(next_child));
            }
            l2_ptr = ret;
        }
    }

    debug_delay();
    let l2 = unsafe { &(*l2_ptr).children };

    &l2[l2k]
}

#[inline]
fn split_fanout(id: PageId) -> (usize, usize) {
    // right shift 32 on 32-bit pointer systems panics
    #[cfg(target_pointer_width = "64")]
    assert!(
        id <= 1 << (FAN_FACTOR * 2),
        "trying to access key of {}, which is \
         higher than 2 ^ {}",
        id,
        (FAN_FACTOR * 2)
    );

    let left = id >> FAN_FACTOR;
    let right = id & u64::try_from(FAN_MASK).unwrap();

    (safe_usize(left), safe_usize(right))
}

#[inline]
fn safe_usize(value: PageId) -> usize {
    usize::try_from(value).unwrap()
}

impl<T> Drop for PageTable<T>
where
    T: 'static + Send + Sync,
{
    fn drop(&mut self) {
        unsafe {
            let head = self.head.load(Relaxed);
            drop(Box::from_raw(head));
        }
    }
}

#[test]
fn test_split_fanout() {
    assert_eq!(
        split_fanout(0b11_1111_1111_1111_1111),
        (0, 0b11_1111_1111_1111_1111)
    );
    assert_eq!(
        split_fanout(0b111_1111_1111_1111_1111),
        (0b1, 0b11_1111_1111_1111_1111)
    );
}
<commit_msg>Switch PageTable back to crossbeam_epoch<commit_after>//! A simple wait-free, grow-only pagetable, assumes a dense keyspace.
#![allow(unsafe_code)]

use std::{
    alloc::{alloc_zeroed, Layout},
    convert::TryFrom,
    mem::{align_of, size_of},
    sync::atomic::Ordering::{Acquire, Relaxed, Release},
};

use crossbeam_epoch::{pin, Atomic, Guard, Owned, Shared};

use crate::debug_delay;

#[allow(unused)]
#[doc(hidden)]
pub const PAGETABLE_NODE_SZ: usize = size_of::<Node1<()>>();

const FAN_FACTOR: usize = 18;
const FAN_OUT: usize = 1 << FAN_FACTOR;
const FAN_MASK: usize = FAN_OUT - 1;

pub type PageId = u64;

struct Node1<T: Send + 'static> {
    children: [Atomic<Node2<T>>; FAN_OUT],
}

struct Node2<T: Send + 'static> {
    children: [Atomic<T>; FAN_OUT],
}

impl<T: Send + 'static> Node1<T> {
    fn new() -> Owned<Self> {
        let size = size_of::<Self>();
        let align = align_of::<Self>();

        unsafe {
            let layout = Layout::from_size_align_unchecked(size, align);

            #[allow(clippy::cast_ptr_alignment)]
            let ptr = alloc_zeroed(layout) as *mut Self;

            Owned::from_raw(ptr)
        }
    }
}

impl<T: Send + 'static> Node2<T> {
    fn new() -> Owned<Node2<T>> {
        let size = size_of::<Self>();
        let align = align_of::<Self>();

        unsafe {
            let layout = Layout::from_size_align_unchecked(size, align);

            #[allow(clippy::cast_ptr_alignment)]
            let ptr = alloc_zeroed(layout) as *mut Self;

            Owned::from_raw(ptr)
        }
    }
}

impl<T: Send + 'static> Drop for Node1<T> {
    fn drop(&mut self) {
        drop_iter(self.children.iter());
    }
}

impl<T: Send + 'static> Drop for Node2<T> {
    fn drop(&mut self) {
        drop_iter(self.children.iter());
    }
}

fn drop_iter<T>(iter: core::slice::Iter<'_, Atomic<T>>) {
    let guard = pin();
    for child in iter {
        let shared_child = child.load(Relaxed, &guard);
        if shared_child.is_null() {
            // this does not leak because the PageTable is
            // assumed to be dense.
            break;
        }
        unsafe {
            drop(shared_child.into_owned());
        }
    }
}

/// A simple lock-free radix tree.
pub struct PageTable<T>
where
    T: 'static + Send + Sync,
{
    head: Atomic<Node1<T>>,
}

impl<T> Default for PageTable<T>
where
    T: 'static + Send + Sync,
{
    fn default() -> Self {
        let head = Node1::new();
        Self { head: Atomic::from(head) }
    }
}

impl<T> PageTable<T>
where
    T: 'static + Send + Sync,
{
    /// # Panics
    ///
    /// will panic if the item is not null already,
    /// which represents a serious failure to
    /// properly handle lifecycles of pages in the
    /// using system.
    pub fn insert(&self, pid: PageId, item: T, guard: &Guard) {
        debug_delay();
        let tip = self.traverse(pid, guard);

        let old = tip.swap(Owned::new(item), Release, guard);
        assert!(old.is_null());
    }

    /// Try to get a value from the tree.
    pub fn get<'g>(&self, pid: PageId, guard: &'g Guard) -> Option<&'g T> {
        debug_delay();
        let tip = self.traverse(pid, guard);

        let res = tip.load(Acquire, guard);
        if res.is_null() { None } else { Some(unsafe { res.deref() }) }
    }

    fn traverse<'g>(self, k: PageId, guard: &'g Guard) -> &'g Atomic<T> {
        let (l1k, l2k) = split_fanout(k);

        debug_delay();
        let head = self.head.load(Acquire, guard);

        debug_delay();
        let l1 = unsafe { head.deref().children };

        debug_delay();
        let mut l2_ptr = l1[l1k].load(Acquire, guard);

        if l2_ptr.is_null() {
            let next_child = Node2::new();

            debug_delay();
            let ret = l1[l1k].compare_and_set(
                Shared::null(),
                next_child,
                Release,
                guard,
            );

            l2_ptr = match ret {
                Ok(next_child) => next_child,
                Err(returned) => {
                    drop(returned.new);
                    returned.current
                }
            };
        }

        debug_delay();
        let l2 = unsafe { l2_ptr.deref().children };

        &l2[l2k]
    }
}

#[inline]
fn split_fanout(id: PageId) -> (usize, usize) {
    // right shift 32 on 32-bit pointer systems panics
    #[cfg(target_pointer_width = "64")]
    assert!(
        id <= 1 << (FAN_FACTOR * 2),
        "trying to access key of {}, which is \
         higher than 2 ^ {}",
        id,
        (FAN_FACTOR * 2)
    );

    let left = id >> FAN_FACTOR;
    let right = id & u64::try_from(FAN_MASK).unwrap();

    (safe_usize(left), safe_usize(right))
}

#[inline]
fn safe_usize(value: PageId) -> usize {
    usize::try_from(value).unwrap()
}

impl<T> Drop for PageTable<T>
where
    T: 'static + Send + Sync,
{
    fn drop(&mut self) {
        let guard = pin();
        let head = self.head.load(Relaxed, &guard);
        unsafe {
            drop(head.into_owned());
        }
    }
}

#[test]
fn test_split_fanout() {
    assert_eq!(
        split_fanout(0b11_1111_1111_1111_1111),
        (0, 0b11_1111_1111_1111_1111)
    );
    assert_eq!(
        split_fanout(0b111_1111_1111_1111_1111),
        (0b1, 0b11_1111_1111_1111_1111)
    );
}
<|endoftext|>


<commit_before>//! Functionality for sending requests to Slack.
use async_trait::async_trait;

use std::{borrow::Borrow, error};

/// Functionality for sending authenticated and unauthenticated requests to Slack via HTTP.
///
/// If you do not have a custom client to integrate with and just want to send requests, use
/// the [`default_client()`] function to get a simple request sender.
#[async_trait]
pub trait SlackWebRequestSender {
    type Error: error::Error;

    /// Make an API call to Slack. Takes a map of parameters that get appended to the request as query
    /// params.
    async fn send<I, K, V, S>(&self, method: S, params: I) -> Result<String, Self::Error>
    where
        I: IntoIterator + Send,
        K: AsRef<str>,
        V: AsRef<str>,
        I::Item: Borrow<(K, V)>,
        S: AsRef<str> + Send;
}

#[cfg(feature = "reqwest")]
mod reqwest_support {
    pub use self::reqwest::Error;
    use async_trait::async_trait;
    use reqwest_ as reqwest;
    use std::borrow::Borrow;

    use super::SlackWebRequestSender;

    #[async_trait]
    impl SlackWebRequestSender for reqwest::Client {
        type Error = reqwest::Error;

        async fn send<I, K, V, S>(&self, method_url: S, params: I) -> Result<String, Self::Error>
        where
            I: IntoIterator + Send,
            K: AsRef<str>,
            V: AsRef<str>,
            I::Item: Borrow<(K, V)>,
            S: AsRef<str> + Send,
        {
            let mut url = reqwest::Url::parse(method_url.as_ref()).expect("Unable to parse url");

            url.query_pairs_mut().extend_pairs(params);

            Ok(self.get(url).send().await?.text().await?)
        }
    }

    /// Provides a default `reqwest` client to give to the API functions to send requests.
    ///
    /// # Examples
    ///
    /// ```
    /// # let token = "some_token";
    /// let client = slack_api::requests::default_client().unwrap();
    /// let response = slack_api::channels::list(&client, &token, &Default::default());
    /// ```
    pub fn default_client() -> Result<reqwest::Client, reqwest::Error> {
        Ok(reqwest::Client::new())
    }
}

#[cfg(feature = "reqwest")]
pub use self::reqwest_support::*;
<commit_msg>update doc test for for async<commit_after>//! Functionality for sending requests to Slack.
use async_trait::async_trait;

use std::{borrow::Borrow, error};

/// Functionality for sending authenticated and unauthenticated requests to Slack via HTTP.
///
/// If you do not have a custom client to integrate with and just want to send requests, use
/// the [`default_client()`] function to get a simple request sender.
#[async_trait]
pub trait SlackWebRequestSender {
    type Error: error::Error;

    /// Make an API call to Slack. Takes a map of parameters that get appended to the request as query
    /// params.
    async fn send<I, K, V, S>(&self, method: S, params: I) -> Result<String, Self::Error>
    where
        I: IntoIterator + Send,
        K: AsRef<str>,
        V: AsRef<str>,
        I::Item: Borrow<(K, V)>,
        S: AsRef<str> + Send;
}

#[cfg(feature = "reqwest")]
mod reqwest_support {
    pub use self::reqwest::Error;
    use async_trait::async_trait;
    use reqwest_ as reqwest;
    use std::borrow::Borrow;

    use super::SlackWebRequestSender;

    #[async_trait]
    impl SlackWebRequestSender for reqwest::Client {
        type Error = reqwest::Error;

        async fn send<I, K, V, S>(&self, method_url: S, params: I) -> Result<String, Self::Error>
        where
            I: IntoIterator + Send,
            K: AsRef<str>,
            V: AsRef<str>,
            I::Item: Borrow<(K, V)>,
            S: AsRef<str> + Send,
        {
            let mut url = reqwest::Url::parse(method_url.as_ref()).expect("Unable to parse url");

            url.query_pairs_mut().extend_pairs(params);

            Ok(self.get(url).send().await?.text().await?)
        }
    }

    /// Provides a default `reqwest` client to give to the API functions to send requests.
    ///
    /// # Examples
    ///
    /// ```
    /// # let token = "some_token";
    /// let client = slack_api::requests::default_client().unwrap();
    /// let params = Default::default();
    /// let response = slack_api::channels::list(&client, &token, &params);
    /// ```
    pub fn default_client() -> Result<reqwest::Client, reqwest::Error> {
        Ok(reqwest::Client::new())
    }
}

#[cfg(feature = "reqwest")]
pub use self::reqwest_support::*;
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2015 Johan Johansson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Infer types where explicit type signatures are not available

// TODO: Check for mutual recursion when infering types. Maybe list of function call ancestry.
// Like: foo calling bar calling baz calling foo => ERROR

// TODO: Consider redisigning this module. Maybe have an Inferer that takes expressions instead
// of implementing inference for each expression type.

use std::collections::{ HashMap, HashSet };
use std::hash::Hash;
use super::{ FnDef, Item, Type, TypedBinding, Expr, ExprMeta };

impl super::FnDef {
	// TODO: Infer types for incomplete function sig. E.g. inc: <→ u32 _> => inc: <→ u32 u32>
	fn infer_types(&mut self, def_map: HashMap<&str, FnDef>) {
		let mut arg_bindings = self.arg_bindings.clone();

		if let Some((fn_arg_types, fn_body_type)) = self.extract_type_sig() {
			// Type signature already exists. Just infer types for body and make sure
			// there are no collisions

			self.set_arg_types(fn_arg_types);

			self.body.infer_types(Some(fn_body_type), def_map, &mut arg_bindings);
		} else {
			// No type signature for function binding. Pass arg bindings to body and infer types
			// for body, then get function signature from updated arg types and body type

			let arg_bindings_old_len = arg_bindings.len();

			// args: type_to_infer_to, def_map, var_stack
			self.body.infer_types(None, def_map, &mut arg_bindings);

			if arg_bindings.len() != arg_bindings_old_len {
				panic!("FnDef::infer_types: arg_bindings.len() != arg_bindings_old_len");
			}

			let arg_types = arg_bindings.into_iter()
				.map(|b| b.type_sig.expect("FnDef::infer_types: Arg has no type"))
				.collect();

			self.set_arg_types(&mut arg_types);

			self.construct_fn_sig(
				arg_types,
				self.body.type_sig.expect("FnDef::infer_types: Body has no type"));
		}
	}
}

/// Extract a function type signature in the form of <→ arg1 arg2 body> to (&[arg1, arg2], body)
fn extract_fn_sig(sig: &Type) -> (&[Type], &Type) {
	match sig {
		&Type::Construct(ref c, ref ts) if c == "fn" || c == "→" => (ts.init(), ts.last()),
		t => panic!("extract_fn_sig: `{:?}` is not a function type", t),
	}
}

impl super::SExpr {
	fn body_type(&self) -> Option<&Type> {
		self.func.type_sig.as_ref().map(extract_fn_sig).map(|(_, body_t)| body_t)
	}

	fn infer_types(
		&mut self,
		parent_expected_type: Option<&Type>,
		def_map: &mut HashMap<&str, FnDef>,
		var_stack: &mut Vec<TypedBinding>)
	{
		self.infer_arg_types(None, def_map, var_stack);

		// TODO: Partial inference when not all bindings have type signatures
		let expected_fn_type = if self.args.iter().all(TypedBinding::has_type)
			&& parent_expected_type.is_some()
		{
			Some(Type::construct("→", self.args.iter().map(|tb| tb.type_sig).collect()))
		} else {
			None
		};

		self.func.infer_types(expected_fn_type, def_map, var_stack);

		let found_fn_type = self.func.type_sig;

		// TODO: This only works for function pointers, i.e. lambdas will need some different type.
		//       When traits are added, use a function trait like Rusts Fn/FnMut/FnOnce
		if found_fn_type.is_some() && expected_fn_type.is_none() {
			if let Type::Construct(_, ref fn_arg_types) = found_fn_type {
				self.infer_arg_types(Some(fn_arg_types), def_map, var_stack);
			} else {
				panic!("SExpr::infer_types: `{:?}` is not a function type", found_fn_type);
			}
		} else if found_fn_type.is_none() {
			panic!("SExpr::infer_types: Could not infer type for function");
		} else if found_fn_type != expected_fn_type {
			panic!(
				"SExpr::infer_types: Function type mismatch. Expected `{:?}`, found `{:?}`",
				expected_fn_type,
				found_fn_type);
		}
	}
}

/// Moves all values in `rhs` to `main`, creating a union of the two maps.
/// If a key from `rhs` already exists in `main`, return `rhs` as an error.
/// On success, return the HashSet of the keys of `rhs`
fn join_map<K: Hash+Eq, V, S>(main: &mut HashMap<K, V, S>, rhs: HashMap<K, V, S>)
	-> Result(HashSet<K>, HashMap<K, V, S>)
{
	if rhs.keys().all(|key| main.contains_key(key)) {
		let mut set = HashSet::with_capacity(rhs.len());

		for (key, val) in rhs {
			main.insert(key, val);
			set.insert(key);
		}

		Ok(set)
	} else {
		Err(rhs)
	}
}

/// Subtract all entries in `map` of keys in `keys` and return the difference.
fn subtract_map<K: Hash+Eq, V, S>(map: &mut HashMap<K, V, S>, keys: &HashSet<K>)
	-> Option<HashMap<K, V>>
{
	if keys.iter().all(|key| map.contains_key(key)) {
		Some(HashMap::from_iter(keys.iter().map(|key| (key, map.remove(key).unwrap()))))
	} else {
		None
	}
}

impl super::Block {
	fn get_type(&self) -> Option<&Type> {
		self.exprs.last().type_sig.as_ref()
	}
	fn infer_types(
		&mut self,
		parent_expected_type: Option<&Type>,
		def_map: &mut HashMap<&str, FnDef>,
		var_stack: &mut Vec<TypedBinding>)
	{
		let constant_keys = join_map(def_map, self.constant_defs.drain());

		let old_vars_len = var_stack.len();

		// First pass. If possible, all vars defined in block should have types infered.
		for expr in self.exprs.init_mut() {
			if let Expr::VarDef(ref mut var_def) = *expr {
				var_def.infer_types(def_map, var_stack);

				var_stack.push(var_def.binding);
			} else {
				expr.infer_types(None, def_map, var_stack);
			}
		}

		if self.exprs.last_mut().expr().is_var_def() {
			panic!("Block::infer_types: Last expression in block is var definition")
		} else {
			self.exprs.last_mut().infer_types(parent_expected_type, def_map, var_stack);
		}

		let block_defined_vars = var_stack.split_off(old_vars_len).into_iter();

		// Second pass. Infer types for all expressions in block now that types for all bindings
		// are, if possible, known.
		for expr in self.exprs.init_mut() {
			if let Expr::VarDef(ref mut var_def) = *expr {
				var_def.infer_types(def_map, var_stack);

				var_stack.push(block_defined_vars.next().unwrap());
			} else {
				expr.infer_types(None, def_map, var_stack);
			}
		}

		if self.exprs.last_mut().expr().is_var_def() {
			panic!("Block::infer_types: Last expression in block is var definition")
		} else {
			self.exprs.last_mut().infer_types(parent_expected_type, def_map, var_stack);
		}

		self.constant_defs = subtract_map(def_map, constant_keys);
	}
}

impl super::Cond {
	fn infer_types(
		&mut self,
		parent_expected_type: Option<&Type>,
		def_map: &mut HashMap<&str, FnDef>,
		var_stack: &mut Vec<TypedBinding>,
		caller_stack: &mut Vec<&str>)
	{
		for (predicate, consequence) in self.clauses.iter_mut()
			.map(|&mut (ref mut p, ref mut c)| (p, c))
			.chain(self.else_clause.iter_mut().map(|c| (&mut ExprMeta::new_true(), c)))
		{
			predicate.infer_types(Some(&Type::bool()), def_map, var_stack, caller_stack);
			consequence.infer_types(parent_expected_type, def_map, var_stack, caller_stack);
		}

		if parent_expected_type.is_none() {
			match self.clauses.iter()
				.map(|&(_, ref c)| c)
				.chain(self.else_clause.iter())
				.find(|clause| clause.type_sig.is_some())
				.map(|t| t.cloned())
			{
				Some(expected_type) => if !self.clauses.iter().map(|&(_, ref c)| c)
					.chain(self.else_clause.iter())
					.all(|clause| clause.type_sig.is_some())
				{
					self.infer_types(expected_type.as_ref(), def_map, var_stack, caller_stack)
				},
				None => panic!("Cond::infer_types: Could not infer type for any clause"),
			}
		}
	}
}

fn get_stack_binding<'a>(var_stack: &'a mut [TypedBinding], bnd: &str) -> &'a mut TypedBinding {
	var_stack.iter_mut()
		.rev()
		.find(|stack_bnd| stack_bnd.ident == bnd)
		.expect(format!("get_stack_binding: Binding not in stack, `{}`", bnd))
}

fn update_binding_stack(var_stack: &mut [TypedBinding], bnd: &str, expected_ty: Type) {
	let stack_bnd = get_stack_binding(var_stack, bnd);

	if stack_bnd.type_sig.is_none() {
		stack_bnd.type_sig = Some(expected_ty)
	}
}

// TODO: Shouldn't necessarily panic if types differ. Add some sort of coercion and polymorphism.
/// Checks binding stack for the type of binding `bnd` and resolves conflicts.
/// If expected type is None, return stack type. If stack type is None, update stack type
/// with to expected type. If both are Some but differ in value, panic.
fn resolve_var_type(var_stack: &mut [TypedBinding], bnd: &str, expected_ty: Option<Type>)
	-> Option<Type>
{
	match expected_ty {
		Some(ty) => update_binding_stack(var_stack, bnd, ty),
		None => get_stack_binding(var_stack, bnd).clone(),
	}
}

impl ExprMeta {
	fn infer_types(
		&mut self,
		parent_expected_type: Option<&Type>,
		def_map: &mut HashMap<&str, FnDef>,
		var_stack: &mut Vec<TypedBinding>)
	{
		let expected_type = self.coerce_type.or(parent_expected_type);

		let found_type = match *self.value {
			// Doesn't have children to infer types for
			Expr::Nil => Type::nil(),
			// TODO: This should be an internal, more general integer type
			Expr::NumLit(_) => Type::basic("u64"),
			// TODO: This should be a construct somehow
			Expr::StrLit(_) => Type::basic("&str"),
			Expr::Binding(ref bnd) => resolve_var_type(var_stack, bnd, expected_type)
				.or(resolve_def_type(def_map, bnd, expected_type)),
			Expr::SExpr(ref mut sexpr) => {
				sexpr.infer_types(expected_type, var_stack);
				sexpr.body_type()
			},
			Expr::Block(ref mut block) => {
				block.infer_types(expected_type, var_stack);
				block.type_sig
			},
			Expr::Cond(ref mut cond) => {
				cond.infer_types(expected_type, var_stack);
				cond.type_sig
			},
			Expr::Lambda(ref mut lambda) => {
				lambda.infer_types(expected_type, var_stack);
				lambda.type_sig
			},
		};

		self.set_type(found_type);
	}
}

impl super::AST {
	pub fn infer_types(&mut self) {
		if let Some(main_def) = self.items.iter_mut()
			.find(|meta| if let Item::FnDef(ref def) = *meta.item {
				def.binding.ident == "main"
			} else {
				false
			})
		{
			main_def.infer_types(&mut self.items).unwrap()
		} else {
			panic!("AST::infer_types: No main function found")
		}
	}
}
<commit_msg>Add resolve_const_type ad refactor resolve_var_type<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2015 Johan Johansson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Infer types where explicit type signatures are not available

// TODO: Check for mutual recursion when infering types. Maybe list of function call ancestry.
// Like: foo calling bar calling baz calling foo => ERROR

// TODO: Consider redisigning this module. Maybe have an Inferer that takes expressions instead
// of implementing inference for each expression type.

use std::collections::{ HashMap, HashSet };
use std::hash::Hash;
use super::{ FnDef, Item, Type, TypedBinding, Expr, ExprMeta, Path };

/// A map of constant definitions
type ConstDefMap = HashMap<&Path, FnDef>;

impl super::FnDef {
	// TODO: Infer types for incomplete function sig. E.g. inc: <→ u32 _> => inc: <→ u32 u32>
	fn infer_types(&mut self, const_defs: ConstDefMap) {
		let mut arg_bindings = self.arg_bindings.clone();

		if let Some((fn_arg_types, fn_body_type)) = self.extract_type_sig() {
			// Type signature already exists. Just infer types for body and make sure
			// there are no collisions

			self.set_arg_types(fn_arg_types);

			self.body.infer_types(Some(fn_body_type), const_defs, &mut arg_bindings);
		} else {
			// No type signature for function binding. Pass arg bindings to body and infer types
			// for body, then get function signature from updated arg types and body type

			let arg_bindings_old_len = arg_bindings.len();

			// args: type_to_infer_to, const_defs, var_stack
			self.body.infer_types(None, const_defs, &mut arg_bindings);

			if arg_bindings.len() != arg_bindings_old_len {
				panic!("FnDef::infer_types: arg_bindings.len() != arg_bindings_old_len");
			}

			let arg_types = arg_bindings.into_iter()
				.map(|b| b.type_sig.expect("FnDef::infer_types: Arg has no type"))
				.collect();

			self.set_arg_types(&mut arg_types);

			self.construct_fn_sig(
				arg_types,
				self.body.type_sig.expect("FnDef::infer_types: Body has no type"));
		}
	}
}

/// Extract a function type signature in the form of <→ arg1 arg2 body> to (&[arg1, arg2], body)
fn extract_fn_sig(sig: &Type) -> (&[Type], &Type) {
	match sig {
		&Type::Construct(ref c, ref ts) if c == "fn" || c == "→" => (ts.init(), ts.last()),
		t => panic!("extract_fn_sig: `{:?}` is not a function type", t),
	}
}

impl super::SExpr {
	fn body_type(&self) -> Option<&Type> {
		self.func.type_sig.as_ref().map(extract_fn_sig).map(|(_, body_t)| body_t)
	}

	fn infer_types(
		&mut self,
		parent_expected_type: Option<&Type>,
		const_defs: &mut ConstDefMap,
		var_stack: &mut Vec<TypedBinding>)
	{
		self.infer_arg_types(None, const_defs, var_stack);

		// TODO: Partial inference when not all bindings have type signatures
		let expected_fn_type = if self.args.iter().all(TypedBinding::has_type)
			&& parent_expected_type.is_some()
		{
			Some(Type::construct("→", self.args.iter().map(|tb| tb.type_sig).collect()))
		} else {
			None
		};

		self.func.infer_types(expected_fn_type, const_defs, var_stack);

		let found_fn_type = self.func.type_sig;

		// TODO: This only works for function pointers, i.e. lambdas will need some different type.
		//       When traits are added, use a function trait like Rusts Fn/FnMut/FnOnce
		if found_fn_type.is_some() && expected_fn_type.is_none() {
			if let Type::Construct(_, ref fn_arg_types) = found_fn_type {
				self.infer_arg_types(Some(fn_arg_types), const_defs, var_stack);
			} else {
				panic!("SExpr::infer_types: `{:?}` is not a function type", found_fn_type);
			}
		} else if found_fn_type.is_none() {
			panic!("SExpr::infer_types: Could not infer type for function");
		} else if found_fn_type != expected_fn_type {
			panic!(
				"SExpr::infer_types: Function type mismatch. Expected `{:?}`, found `{:?}`",
				expected_fn_type,
				found_fn_type);
		}
	}
}

/// Moves all values in `rhs` to `main`, creating a union of the two maps.
/// If a key from `rhs` already exists in `main`, return `rhs` as an error.
/// On success, return the HashSet of the keys of `rhs`
fn join_map<K: Hash+Eq, V, S>(main: &mut HashMap<K, V, S>, rhs: HashMap<K, V, S>)
	-> Result(HashSet<K>, HashMap<K, V, S>)
{
	if rhs.keys().all(|key| main.contains_key(key)) {
		let mut set = HashSet::with_capacity(rhs.len());

		for (key, val) in rhs {
			main.insert(key, val);
			set.insert(key);
		}

		Ok(set)
	} else {
		Err(rhs)
	}
}

/// Subtract all entries in `map` of keys in `keys` and return the difference.
fn subtract_map<K: Hash+Eq, V, S>(map: &mut HashMap<K, V, S>, keys: &HashSet<K>)
	-> Option<HashMap<K, V>>
{
	if keys.iter().all(|key| map.contains_key(key)) {
		Some(HashMap::from_iter(keys.iter().map(|key| (key, map.remove(key).unwrap()))))
	} else {
		None
	}
}

impl super::Block {
	fn get_type(&self) -> Option<&Type> {
		self.exprs.last().type_sig.as_ref()
	}
	fn infer_types(
		&mut self,
		parent_expected_type: Option<&Type>,
		const_defs: &mut ConstDefMap,
		var_stack: &mut Vec<TypedBinding>)
	{
		let constant_keys = join_map(const_defs, self.constant_defs.drain());

		let old_vars_len = var_stack.len();

		// First pass. If possible, all vars defined in block should have types infered.
		for expr in self.exprs.init_mut() {
			if let Expr::VarDef(ref mut var_def) = *expr {
				var_def.infer_types(const_defs, var_stack);

				var_stack.push(var_def.binding);
			} else {
				expr.infer_types(None, const_defs, var_stack);
			}
		}

		if self.exprs.last_mut().expr().is_var_def() {
			panic!("Block::infer_types: Last expression in block is var definition")
		} else {
			self.exprs.last_mut().infer_types(parent_expected_type, const_defs, var_stack);
		}

		let block_defined_vars = var_stack.split_off(old_vars_len).into_iter();

		// Second pass. Infer types for all expressions in block now that types for all bindings
		// are, if possible, known.
		for expr in self.exprs.init_mut() {
			if let Expr::VarDef(ref mut var_def) = *expr {
				var_def.infer_types(const_defs, var_stack);

				var_stack.push(block_defined_vars.next().unwrap());
			} else {
				expr.infer_types(None, const_defs, var_stack);
			}
		}

		if self.exprs.last_mut().expr().is_var_def() {
			panic!("Block::infer_types: Last expression in block is var definition")
		} else {
			self.exprs.last_mut().infer_types(parent_expected_type, const_defs, var_stack);
		}

		self.constant_defs = subtract_map(const_defs, constant_keys);
	}
}

impl super::Cond {
	fn infer_types(
		&mut self,
		parent_expected_type: Option<&Type>,
		const_defs: &mut ConstDefMap,
		var_stack: &mut Vec<TypedBinding>,
		caller_stack: &mut Vec<&str>)
	{
		for (predicate, consequence) in self.clauses.iter_mut()
			.map(|&mut (ref mut p, ref mut c)| (p, c))
			.chain(self.else_clause.iter_mut().map(|c| (&mut ExprMeta::new_true(), c)))
		{
			predicate.infer_types(Some(&Type::bool()), const_defs, var_stack, caller_stack);
			consequence.infer_types(parent_expected_type, const_defs, var_stack, caller_stack);
		}

		if parent_expected_type.is_none() {
			match self.clauses.iter()
				.map(|&(_, ref c)| c)
				.chain(self.else_clause.iter())
				.find(|clause| clause.type_sig.is_some())
				.map(|t| t.cloned())
			{
				Some(expected_type) => if !self.clauses.iter().map(|&(_, ref c)| c)
					.chain(self.else_clause.iter())
					.all(|clause| clause.type_sig.is_some())
				{
					self.infer_types(expected_type.as_ref(), const_defs, var_stack, caller_stack)
				},
				None => panic!("Cond::infer_types: Could not infer type for any clause"),
			}
		}
	}
}

/// Checks binding stack for the type of binding `bnd` and resolves conflicts.
/// If expected type is None, return stack type. If stack type is None, update stack type
/// with to expected type. If both are Some but differ in value, panic.
fn resolve_var_type(var_stack: &mut [TypedBinding], bnd: &str, expected_ty: Option<&Type>)
	-> Option<&Type>
{
	fn get_stack_binding_type<'a>(var_stack: &mut [TypedBinding], bnd: &str) -> &mut Option<Type> {
		&mut var_stack.iter_mut()
			.rev()
			.find(|stack_bnd| stack_bnd.ident == bnd)
			.expect(format!("get_stack_binding_type: Binding not in stack, `{}`", bnd))
			.type_sig
	}

	fn update_binding_stack(var_stack: &mut [TypedBinding], bnd: &str, expected_ty: &Type) {
		let stack_bnd_ty = get_stack_binding_type(var_stack, bnd);

		if stack_bnd_ty.is_none() {
			*stack_bnd_ty = Some(expected_ty.clone())
		} else if stack_bnd_ty.as_ref() != Some(expected_ty) {
			// TODO: Shouldn't necessarily panic if types differ. Add some sort of coercion and polymorphism.
			panic!(
				"update_binding_stack: Tried to set type of binding on stack to `{:?}` \
					when it already had type `{:?}`",
				expected_ty,
				stack_bnd_ty.as_ref().unwrap())
		}
	}

	match expected_ty {
		Some(ty) => {
			update_binding_stack(var_stack, bnd, ty);
			expected_ty
		},
		None => get_stack_binding_type(var_stack, bnd).as_ref(),
	}
}

fn resolve_const_type(const_defs: &mut ConstDefMap, path: &Path, expected_type: Option<&Type>)
	-> Option<&Type>
{
	fn get_const_def(const_defs: &mut ConstDefMap, path: &Path) -> &mut FnDef {
		const_defs.get_mut(path).expect(format!("get_const_def: No entry exists for `{}`", path))
	}

	match expected_type {
		Some(ty) => {
			get_const_def(const_defs, path).set_type(ty);
			expected_type
		},
		None => get_const_def(const_defs, path).get_type(),
	}
}

impl ExprMeta {
	fn infer_types(
		&mut self,
		parent_expected_type: Option<&Type>,
		const_defs: &mut ConstDefMap,
		var_stack: &mut Vec<TypedBinding>)
	{
		let expected_type = self.coerce_type.as_ref().or(parent_expected_type);

		let found_type = match *self.value {
			// Doesn't have children to infer types for
			Expr::Nil => Some(&Type::nil()),
			// TODO: This should be an internal, more general integer type
			Expr::NumLit(_) => Some(&Type::basic("u64")),
			// TODO: This should be a construct somehow
			Expr::StrLit(_) => Some(&Type::basic("&str")),
			Expr::Binding(ref path) => resolve_var_type(var_stack, path, expected_type)
				.or(resolve_const_type(const_defs, path, expected_type)),
			Expr::SExpr(ref mut sexpr) => {
				sexpr.infer_types(expected_type, var_stack);
				sexpr.body_type()
			},
			Expr::Block(ref mut block) => {
				block.infer_types(expected_type, var_stack);
				block.type_sig.as_ref()
			},
			Expr::Cond(ref mut cond) => {
				cond.infer_types(expected_type, var_stack);
				cond.type_sig.as_ref()
			},
			Expr::Lambda(ref mut lambda) => {
				lambda.infer_types(expected_type, var_stack);
				lambda.type_sig.as_ref()
			},
		};

		self.set_type(found_type);
	}
}

impl super::AST {
	pub fn infer_types(&mut self) {
		if let Some(main_def) = self.items.iter_mut()
			.find(|meta| if let Item::FnDef(ref def) = *meta.item {
				def.binding.ident == "main"
			} else {
				false
			})
		{
			main_def.infer_types(&mut self.items).unwrap()
		} else {
			panic!("AST::infer_types: No main function found")
		}
	}
}
<|endoftext|>