<commit_before>extern crate bytes;
extern crate combine;

use std::collections::VecDeque;
use std::fmt;
use std::io::{self, Write};
use std::marker::PhantomData;
use std::str;
use std::sync::{Arc, Mutex};

use failure;

use self::combine::combinator::{any_send_partial_state, AnySendPartialState};
use self::combine::error::{ParseError, StreamError};
use self::combine::parser::byte::digit;
use self::combine::parser::range::{range, recognize, take};
use self::combine::stream::easy;
use self::combine::stream::{PartialStream, RangeStream, StreamErrorFor};
use self::combine::{skip_many, skip_many1, Parser};

use self::bytes::{BufMut, BytesMut};

use tokio_io::codec::{Decoder, Encoder};

use futures::sync::mpsc;
use futures::{self, Async, Future, IntoFuture, Poll, Sink, StartSend, Stream};

use jsonrpc_core::{Error, ErrorCode, Params, RpcMethodSimple, RpcNotificationSimple, Value};

use serde;
use serde_json::{from_value, to_string, to_value};

use BoxFuture;

#[derive(Debug, PartialEq)]
pub struct ServerError<E> {
    pub message: String,
    pub data: Option<E>,
}

impl<E, D> From<E> for ServerError<D>
where
    E: fmt::Display,
{
    fn from(err: E) -> ServerError<D> {
        ServerError {
            message: err.to_string(),
            data: None,
        }
    }
}

pub trait LanguageServerCommand<P>: Send + Sync + 'static
where
    Self::Future: Send + 'static,
{
    type Future: IntoFuture<Item = Self::Output, Error = ServerError<Self::Error>> + Send + 'static;
    type Output: serde::Serialize;
    type Error: serde::Serialize;
    fn execute(&self, param: P) -> Self::Future;

    fn invalid_params(&self) -> Option<Self::Error> {
        None
    }
}

impl<'de, F, R, P, O, E> LanguageServerCommand<P> for F
where
    F: Fn(P) -> R + Send + Sync + 'static,
    R: IntoFuture<Item = O, Error = ServerError<E>> + Send + 'static,
    R::Future: Send + 'static,
    P: serde::Deserialize<'de>,
    O: serde::Serialize,
    E: serde::Serialize,
{
    type Future = F::Output;
    type Output = O;
    type Error = E;

    fn execute(&self, param: P) -> Self::Future {
        self(param)
    }
}

pub trait LanguageServerNotification<P>: Send + Sync + 'static {
    fn execute(&self, param: P);
}

impl<'de, F, P> LanguageServerNotification<P> for F
where
    F: Fn(P) + Send + Sync + 'static,
    P: serde::Deserialize<'de> + 'static,
{
    fn execute(&self, param: P) {
        self(param)
    }
}
pub struct ServerCommand<T, P>(pub T, PhantomData<fn(P)>);

impl<T, P> ServerCommand<T, P> {
    pub fn method(command: T) -> ServerCommand<T, P>
    where
        T: LanguageServerCommand<P>,
        <T::Future as IntoFuture>::Future: Send + 'static,
        P: for<'de> serde::Deserialize<'de> + 'static,
    {
        ServerCommand(command, PhantomData)
    }

    pub fn notification(command: T) -> ServerCommand<T, P>
    where
        T: LanguageServerNotification<P>,
        P: for<'de> serde::Deserialize<'de> + 'static,
    {
        ServerCommand(command, PhantomData)
    }
}

impl<P, T> RpcMethodSimple for ServerCommand<T, P>
where
    T: LanguageServerCommand<P>,
    <T::Future as IntoFuture>::Future: Send + 'static,
    P: for<'de> serde::Deserialize<'de> + 'static,
{
    type Out = BoxFuture<Value, Error>;
    fn call(&self, param: Params) -> BoxFuture<Value, Error> {
        let value = match param {
            Params::Map(map) => Value::Object(map),
            Params::Array(arr) => Value::Array(arr),
            Params::None => Value::Null,
        };
        let err = match from_value(value.clone()) {
            Ok(value) => {
                return Box::new(self.0.execute(value).into_future().then(|result| {
                    match result {
                        Ok(value) => {
                            Ok(to_value(&value).expect("result data could not be serialized"))
                                .into_future()
                        }
                        Err(error) => Err(Error {
                            code: ErrorCode::InternalError,
                            message: error.message,
                            data: error
                                .data
                                .as_ref()
                                .map(|v| to_value(v).expect("error data could not be serialized")),
                        })
                        .into_future(),
                    }
                }))
            }
            Err(err) => err,
        };
        let data = self.0.invalid_params();
        Box::new(futures::failed(Error {
            code: ErrorCode::InvalidParams,
            message: format!("Invalid params: {}", err),
            data: data
                .as_ref()
                .map(|v| to_value(v).expect("error data could not be serialized")),
        }))
    }
}

impl<T, P> RpcNotificationSimple for ServerCommand<T, P>
where
    T: LanguageServerNotification<P>,
    P: for<'de> serde::Deserialize<'de> + 'static,
{
    fn execute(&self, param: Params) {
        match param {
            Params::Map(map) => match from_value(Value::Object(map)) {
                Ok(value) => {
                    self.0.execute(value);
                }
                Err(err) => error!("{}", err), // FIXME log_message!("Invalid parameters. Reason: {}", err),
            },
            _ => (), // FIXME log_message!("Invalid parameters: {:?}", param),
        }
    }
}

pub fn write_message<W, T>(output: W, value: &T) -> io::Result<()>
where
    W: Write,
    T: serde::Serialize,
{
    let response = to_string(&value).unwrap();
    write_message_str(output, &response)
}

pub fn write_message_str<W>(mut output: W, response: &str) -> io::Result<()>
where
    W: Write,
{
    debug!("Respond: {}", response);
    try!(write!(
        output,
        "Content-Length: {}\r\n\r\n{}",
        response.len(),
        response
    ));
    try!(output.flush());
    Ok(())
}

pub struct LanguageServerDecoder {
    state: AnySendPartialState,
}

impl LanguageServerDecoder {
    pub fn new() -> LanguageServerDecoder {
        LanguageServerDecoder {
            state: Default::default(),
        }
    }
}

/// Parses blocks of data with length headers
///
/// ```ignore
/// Content-Length: 18
///
/// { "some": "data" }
/// ```
fn decode_parser<'a, I>(
) -> impl Parser<Input = I, Output = Vec<u8>, PartialState = AnySendPartialState> + 'a
where
    I: RangeStream<Item = u8, Range = &'a [u8]> + 'a,
    // Necessary due to rust-lang/rust#24159
    I::Error: ParseError<I::Item, I::Range, I::Position>,
{
    let content_length = range(&b"Content-Length: "[..]).with(
        recognize(skip_many1(digit())).and_then(|digits: &[u8]| {
            str::from_utf8(digits)
                .unwrap()
                .parse::<usize>()
                // Convert the error from `.parse` into an error combine understands
                .map_err(StreamErrorFor::<I>::other)
        }),
    );

    any_send_partial_state(
        (
            skip_many(range(&b"\r\n"[..])),
            content_length,
            range(&b"\r\n\r\n"[..]).map(|_| ()),
        )
            .then_partial(|&mut (_, message_length, _)| {
                take(message_length).map(|bytes: &[u8]| bytes.to_owned())
            }),
    )
}

impl Decoder for LanguageServerDecoder {
    type Item = String;
    type Error = failure::Error;

    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
        let (opt, removed_len) = combine::stream::decode(
            decode_parser(),
            easy::Stream(PartialStream(&src[..])),
            &mut self.state,
        )
        .map_err(|err| {
            let err = err
                .map_range(|r| {
                    str::from_utf8(r)
                        .ok()
                        .map_or_else(|| format!("{:?}", r), |s| s.to_string())
                })
                .map_position(|p| p.translate_position(&src[..]));
            failure::err_msg(format!(
                "{}\nIn input: `{}`",
                err,
                str::from_utf8(src).unwrap()
            ))
        })?;

        src.split_to(removed_len);

        match opt {
            None => Ok(None),

            Some(output) => {
                let value = String::from_utf8(output)?;
                Ok(Some(value))
            }
        }
    }
}

#[derive(Debug)]
pub struct LanguageServerEncoder;

impl Encoder for LanguageServerEncoder {
    type Item = String;
    type Error = failure::Error;
    fn encode(&mut self, item: Self::Item, dst: &mut BytesMut) -> Result<(), Self::Error> {
        write_message_str(dst.writer(), &item)?;
        Ok(())
    }
}

pub struct Entry<K, V, W> {
    pub key: K,
    pub value: V,
    pub version: W,
}

#[derive(Debug)]
pub struct SharedSink<S>(Arc<Mutex<S>>);

impl<S> Clone for SharedSink<S> {
    fn clone(&self) -> Self {
        SharedSink(self.0.clone())
    }
}

impl<S> SharedSink<S> {
    pub fn new(sink: S) -> SharedSink<S> {
        SharedSink(Arc::new(Mutex::new(sink)))
    }
}

impl<S> Sink for SharedSink<S>
where
    S: Sink,
{
    type SinkItem = S::SinkItem;
    type SinkError = S::SinkError;

    fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        self.0.lock().unwrap().start_send(item)
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        self.0.lock().unwrap().poll_complete()
    }

    fn close(&mut self) -> Poll<(), Self::SinkError> {
        self.0.lock().unwrap().close()
    }
}

/// Queue which only keeps the latest work item for each key
pub struct UniqueSink<K, V, W> {
    sender: mpsc::UnboundedSender<Entry<K, V, W>>,
}

impl<K, V, W> Clone for UniqueSink<K, V, W> {
    fn clone(&self) -> Self {
        UniqueSink {
            sender: self.sender.clone(),
        }
    }
}

pub struct UniqueStream<K, V, W> {
    queue: VecDeque<Entry<K, V, W>>,
    receiver: mpsc::UnboundedReceiver<Entry<K, V, W>>,
    exhausted: bool,
}

pub fn unique_queue<K, V, W>() -> (UniqueSink<K, V, W>, UniqueStream<K, V, W>)
where
    K: PartialEq,
    W: Ord,
{
    let (sender, receiver) = mpsc::unbounded();
    (
        UniqueSink { sender },
        UniqueStream {
            queue: VecDeque::new(),
            receiver,
            exhausted: false,
        },
    )
}

impl<K, V, W> Stream for UniqueStream<K, V, W>
where
    K: PartialEq,
    W: Ord,
{
    type Item = Entry<K, V, W>;
    type Error = ();

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        while !self.exhausted {
            match self.receiver.poll()? {
                Async::Ready(Some(item)) => {
                    if let Some(entry) = self.queue.iter_mut().find(|entry| entry.key == item.key) {
                        if entry.version < item.version {
                            *entry = item;
                        }
                        continue;
                    }
                    self.queue.push_back(item);
                }
                Async::Ready(None) => {
                    self.exhausted = true;
                }
                Async::NotReady => break,
            }
        }
        match self.queue.pop_front() {
            Some(item) => Ok(Async::Ready(Some(item))),
            None => {
                if self.exhausted {
                    Ok(Async::Ready(None))
                } else {
                    Ok(Async::NotReady)
                }
            }
        }
    }
}

impl<K, V, W> Sink for UniqueSink<K, V, W> {
    type SinkItem = Entry<K, V, W>;
    type SinkError = mpsc::SendError<Entry<K, V, W>>;

    fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        self.sender.start_send(item)
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        self.sender.poll_complete()
    }

    fn close(&mut self) -> Poll<(), Self::SinkError> {
        self.sender.close()
    }
}

pub struct SinkFn<F, I> {
    f: F,
    _marker: PhantomData<fn(I) -> I>,
}

pub fn sink_fn<F, I, E>(f: F) -> SinkFn<F, I>
where
    F: FnMut(I) -> StartSend<I, E>,
{
    SinkFn {
        f,
        _marker: PhantomData,
    }
}

impl<F, I, E> Sink for SinkFn<F, I>
where
    F: FnMut(I) -> StartSend<I, E>,
{
    type SinkItem = I;
    type SinkError = E;

    fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        (self.f)(item)
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        Ok(Async::Ready(()))
    }
}
<commit_msg>Remove redundant clone<commit_after>extern crate bytes;
extern crate combine;

use std::collections::VecDeque;
use std::fmt;
use std::io::{self, Write};
use std::marker::PhantomData;
use std::str;
use std::sync::{Arc, Mutex};

use failure;

use self::combine::combinator::{any_send_partial_state, AnySendPartialState};
use self::combine::error::{ParseError, StreamError};
use self::combine::parser::byte::digit;
use self::combine::parser::range::{range, recognize, take};
use self::combine::stream::easy;
use self::combine::stream::{PartialStream, RangeStream, StreamErrorFor};
use self::combine::{skip_many, skip_many1, Parser};

use self::bytes::{BufMut, BytesMut};

use tokio_io::codec::{Decoder, Encoder};

use futures::sync::mpsc;
use futures::{self, Async, Future, IntoFuture, Poll, Sink, StartSend, Stream};

use jsonrpc_core::{Error, ErrorCode, Params, RpcMethodSimple, RpcNotificationSimple, Value};

use serde;
use serde_json::{from_value, to_string, to_value};

use BoxFuture;

#[derive(Debug, PartialEq)]
pub struct ServerError<E> {
    pub message: String,
    pub data: Option<E>,
}

impl<E, D> From<E> for ServerError<D>
where
    E: fmt::Display,
{
    fn from(err: E) -> ServerError<D> {
        ServerError {
            message: err.to_string(),
            data: None,
        }
    }
}

pub trait LanguageServerCommand<P>: Send + Sync + 'static
where
    Self::Future: Send + 'static,
{
    type Future: IntoFuture<Item = Self::Output, Error = ServerError<Self::Error>> + Send + 'static;
    type Output: serde::Serialize;
    type Error: serde::Serialize;
    fn execute(&self, param: P) -> Self::Future;

    fn invalid_params(&self) -> Option<Self::Error> {
        None
    }
}

impl<'de, F, R, P, O, E> LanguageServerCommand<P> for F
where
    F: Fn(P) -> R + Send + Sync + 'static,
    R: IntoFuture<Item = O, Error = ServerError<E>> + Send + 'static,
    R::Future: Send + 'static,
    P: serde::Deserialize<'de>,
    O: serde::Serialize,
    E: serde::Serialize,
{
    type Future = F::Output;
    type Output = O;
    type Error = E;

    fn execute(&self, param: P) -> Self::Future {
        self(param)
    }
}

pub trait LanguageServerNotification<P>: Send + Sync + 'static {
    fn execute(&self, param: P);
}

impl<'de, F, P> LanguageServerNotification<P> for F
where
    F: Fn(P) + Send + Sync + 'static,
    P: serde::Deserialize<'de> + 'static,
{
    fn execute(&self, param: P) {
        self(param)
    }
}
pub struct ServerCommand<T, P>(pub T, PhantomData<fn(P)>);

impl<T, P> ServerCommand<T, P> {
    pub fn method(command: T) -> ServerCommand<T, P>
    where
        T: LanguageServerCommand<P>,
        <T::Future as IntoFuture>::Future: Send + 'static,
        P: for<'de> serde::Deserialize<'de> + 'static,
    {
        ServerCommand(command, PhantomData)
    }

    pub fn notification(command: T) -> ServerCommand<T, P>
    where
        T: LanguageServerNotification<P>,
        P: for<'de> serde::Deserialize<'de> + 'static,
    {
        ServerCommand(command, PhantomData)
    }
}

impl<P, T> RpcMethodSimple for ServerCommand<T, P>
where
    T: LanguageServerCommand<P>,
    <T::Future as IntoFuture>::Future: Send + 'static,
    P: for<'de> serde::Deserialize<'de> + 'static,
{
    type Out = BoxFuture<Value, Error>;
    fn call(&self, param: Params) -> BoxFuture<Value, Error> {
        let value = match param {
            Params::Map(map) => Value::Object(map),
            Params::Array(arr) => Value::Array(arr),
            Params::None => Value::Null,
        };
        let err = match from_value(value) {
            Ok(value) => {
                return Box::new(self.0.execute(value).into_future().then(|result| {
                    match result {
                        Ok(value) => {
                            Ok(to_value(&value).expect("result data could not be serialized"))
                                .into_future()
                        }
                        Err(error) => Err(Error {
                            code: ErrorCode::InternalError,
                            message: error.message,
                            data: error
                                .data
                                .as_ref()
                                .map(|v| to_value(v).expect("error data could not be serialized")),
                        })
                        .into_future(),
                    }
                }))
            }
            Err(err) => err,
        };
        let data = self.0.invalid_params();
        Box::new(futures::failed(Error {
            code: ErrorCode::InvalidParams,
            message: format!("Invalid params: {}", err),
            data: data
                .as_ref()
                .map(|v| to_value(v).expect("error data could not be serialized")),
        }))
    }
}

impl<T, P> RpcNotificationSimple for ServerCommand<T, P>
where
    T: LanguageServerNotification<P>,
    P: for<'de> serde::Deserialize<'de> + 'static,
{
    fn execute(&self, param: Params) {
        match param {
            Params::Map(map) => match from_value(Value::Object(map)) {
                Ok(value) => {
                    self.0.execute(value);
                }
                Err(err) => error!("{}", err), // FIXME log_message!("Invalid parameters. Reason: {}", err),
            },
            _ => (), // FIXME log_message!("Invalid parameters: {:?}", param),
        }
    }
}

pub fn write_message<W, T>(output: W, value: &T) -> io::Result<()>
where
    W: Write,
    T: serde::Serialize,
{
    let response = to_string(&value).unwrap();
    write_message_str(output, &response)
}

pub fn write_message_str<W>(mut output: W, response: &str) -> io::Result<()>
where
    W: Write,
{
    debug!("Respond: {}", response);
    try!(write!(
        output,
        "Content-Length: {}\r\n\r\n{}",
        response.len(),
        response
    ));
    try!(output.flush());
    Ok(())
}

pub struct LanguageServerDecoder {
    state: AnySendPartialState,
}

impl LanguageServerDecoder {
    pub fn new() -> LanguageServerDecoder {
        LanguageServerDecoder {
            state: Default::default(),
        }
    }
}

/// Parses blocks of data with length headers
///
/// ```ignore
/// Content-Length: 18
///
/// { "some": "data" }
/// ```
fn decode_parser<'a, I>(
) -> impl Parser<Input = I, Output = Vec<u8>, PartialState = AnySendPartialState> + 'a
where
    I: RangeStream<Item = u8, Range = &'a [u8]> + 'a,
    // Necessary due to rust-lang/rust#24159
    I::Error: ParseError<I::Item, I::Range, I::Position>,
{
    let content_length = range(&b"Content-Length: "[..]).with(
        recognize(skip_many1(digit())).and_then(|digits: &[u8]| {
            str::from_utf8(digits)
                .unwrap()
                .parse::<usize>()
                // Convert the error from `.parse` into an error combine understands
                .map_err(StreamErrorFor::<I>::other)
        }),
    );

    any_send_partial_state(
        (
            skip_many(range(&b"\r\n"[..])),
            content_length,
            range(&b"\r\n\r\n"[..]).map(|_| ()),
        )
            .then_partial(|&mut (_, message_length, _)| {
                take(message_length).map(|bytes: &[u8]| bytes.to_owned())
            }),
    )
}

impl Decoder for LanguageServerDecoder {
    type Item = String;
    type Error = failure::Error;

    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
        let (opt, removed_len) = combine::stream::decode(
            decode_parser(),
            easy::Stream(PartialStream(&src[..])),
            &mut self.state,
        )
        .map_err(|err| {
            let err = err
                .map_range(|r| {
                    str::from_utf8(r)
                        .ok()
                        .map_or_else(|| format!("{:?}", r), |s| s.to_string())
                })
                .map_position(|p| p.translate_position(&src[..]));
            failure::err_msg(format!(
                "{}\nIn input: `{}`",
                err,
                str::from_utf8(src).unwrap()
            ))
        })?;

        src.split_to(removed_len);

        match opt {
            None => Ok(None),

            Some(output) => {
                let value = String::from_utf8(output)?;
                Ok(Some(value))
            }
        }
    }
}

#[derive(Debug)]
pub struct LanguageServerEncoder;

impl Encoder for LanguageServerEncoder {
    type Item = String;
    type Error = failure::Error;
    fn encode(&mut self, item: Self::Item, dst: &mut BytesMut) -> Result<(), Self::Error> {
        write_message_str(dst.writer(), &item)?;
        Ok(())
    }
}

pub struct Entry<K, V, W> {
    pub key: K,
    pub value: V,
    pub version: W,
}

#[derive(Debug)]
pub struct SharedSink<S>(Arc<Mutex<S>>);

impl<S> Clone for SharedSink<S> {
    fn clone(&self) -> Self {
        SharedSink(self.0.clone())
    }
}

impl<S> SharedSink<S> {
    pub fn new(sink: S) -> SharedSink<S> {
        SharedSink(Arc::new(Mutex::new(sink)))
    }
}

impl<S> Sink for SharedSink<S>
where
    S: Sink,
{
    type SinkItem = S::SinkItem;
    type SinkError = S::SinkError;

    fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        self.0.lock().unwrap().start_send(item)
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        self.0.lock().unwrap().poll_complete()
    }

    fn close(&mut self) -> Poll<(), Self::SinkError> {
        self.0.lock().unwrap().close()
    }
}

/// Queue which only keeps the latest work item for each key
pub struct UniqueSink<K, V, W> {
    sender: mpsc::UnboundedSender<Entry<K, V, W>>,
}

impl<K, V, W> Clone for UniqueSink<K, V, W> {
    fn clone(&self) -> Self {
        UniqueSink {
            sender: self.sender.clone(),
        }
    }
}

pub struct UniqueStream<K, V, W> {
    queue: VecDeque<Entry<K, V, W>>,
    receiver: mpsc::UnboundedReceiver<Entry<K, V, W>>,
    exhausted: bool,
}

pub fn unique_queue<K, V, W>() -> (UniqueSink<K, V, W>, UniqueStream<K, V, W>)
where
    K: PartialEq,
    W: Ord,
{
    let (sender, receiver) = mpsc::unbounded();
    (
        UniqueSink { sender },
        UniqueStream {
            queue: VecDeque::new(),
            receiver,
            exhausted: false,
        },
    )
}

impl<K, V, W> Stream for UniqueStream<K, V, W>
where
    K: PartialEq,
    W: Ord,
{
    type Item = Entry<K, V, W>;
    type Error = ();

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        while !self.exhausted {
            match self.receiver.poll()? {
                Async::Ready(Some(item)) => {
                    if let Some(entry) = self.queue.iter_mut().find(|entry| entry.key == item.key) {
                        if entry.version < item.version {
                            *entry = item;
                        }
                        continue;
                    }
                    self.queue.push_back(item);
                }
                Async::Ready(None) => {
                    self.exhausted = true;
                }
                Async::NotReady => break,
            }
        }
        match self.queue.pop_front() {
            Some(item) => Ok(Async::Ready(Some(item))),
            None => {
                if self.exhausted {
                    Ok(Async::Ready(None))
                } else {
                    Ok(Async::NotReady)
                }
            }
        }
    }
}

impl<K, V, W> Sink for UniqueSink<K, V, W> {
    type SinkItem = Entry<K, V, W>;
    type SinkError = mpsc::SendError<Entry<K, V, W>>;

    fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        self.sender.start_send(item)
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        self.sender.poll_complete()
    }

    fn close(&mut self) -> Poll<(), Self::SinkError> {
        self.sender.close()
    }
}

pub struct SinkFn<F, I> {
    f: F,
    _marker: PhantomData<fn(I) -> I>,
}

pub fn sink_fn<F, I, E>(f: F) -> SinkFn<F, I>
where
    F: FnMut(I) -> StartSend<I, E>,
{
    SinkFn {
        f,
        _marker: PhantomData,
    }
}

impl<F, I, E> Sink for SinkFn<F, I>
where
    F: FnMut(I) -> StartSend<I, E>,
{
    type SinkItem = I;
    type SinkError = E;

    fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
        (self.f)(item)
    }

    fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
        Ok(Async::Ready(()))
    }
}
<|endoftext|>


<commit_before>//! moudule for finite automata.

trait State: Eq + Copy {}
trait Symbol: Eq + Copy {}

/// Transition represents the rule that moves from one state to another.
/// `S` means the state, `T` means the input symbol.
pub struct Transition<S: State, T: Symbol> {
  pub state: S,
  pub symbol: T,
  pub next_state: S
}

impl<S: State, T: Symbol> Transition<S, T> {
  pub fn new(state: &S, symbol: &T, next_state: &S) -> Transition<S, T> {
    Transition { state: *state, symbol: *symbol, next_state: *next_state }
  }

  /// determine whether th current transition applies to the state and symbol
  pub fn is_apply_to(&self, state: &S, symbol: &T) -> bool {
    self.state == *state && self.symbol == *symbol
  }

  /// get the next state from the transition
  pub fn follow(&self) -> &S {
    &self.next_state
  }
}

/// a collection of transition rules
pub struct TransitionRelation<S: State, T: Symbol> {
  transitions: Vec<Transition<S, T>>
}

impl<S: State, T: Symbol> TransitionRelation<S, T> {
  pub fn new(transitions: Vec<Transition<S, T>>) -> TransitionRelation<S, T> {
    TransitionRelation { transitions: transitions }
  }

  /// get the next state for the input condition
  pub fn next_state_for(&self, state: &S, symbol: &T) -> Option<&S> {
    self.transition_for(state, symbol).map(|trans| { trans.follow() })
  }

  /// get the transition of the state and the symbol
  fn transition_for(&self, state: &S, symbol: &T) -> Option<&Transition<S, T>> {
    self.transitions.iter().find(|&transition| {
      transition.is_apply_to(state, symbol)
    })
  }
}

pub struct DFA<S: State, T: Symbol> {
  current_state: S,
  accept_states: Vec<S>,
  transition_relation: TransitionRelation<S, T>
}

impl<S: State, T: Symbol> DFA<S, T> {
  pub fn new(current_state: &S, accept_states: Vec<S>,
             transition_relation: TransitionRelation<S, T>) -> DFA<S, T> {
    DFA {
      current_state: *current_state,
      accept_states: accept_states,
      transition_relation: transition_relation
    }
  }

  /// read a symbol and change the dfa state
  pub fn read_symbol(&mut self, sym: &T) {
    self.current_state = *self.transition_relation
                             .next_state_for(&self.current_state, sym)
                             .unwrap()
  }

  // pub fn read_symbol_seq(&mut self, syms: Iterator<T>) {
  //   for sym in syms {
  //     self.read_symbol(sym);
  //   }
  // }

  /// determine whether the current dfa is in an accepted state
  pub fn is_accepting(&self) -> bool {
    self.accept_states.iter().any(|&state| {
      state == self.current_state
    })
  }
}

#[cfg(test)]
mod test {
  use super::State;
  use super::Symbol;
  use super::Transition;
  use super::TransitionRelation;

  impl State for int {}
  impl Symbol for char {}

  #[test]
  fn test_transition() {
    let rule = Transition::new(&1i, & 'a', &2i);
    assert_eq!(2i, rule.next_state);
  }

  #[test]
  fn test_transition_relation() {
    let rules = vec![
      Transition::new(&1i, & 'a', &1i),
      Transition::new(&1i, & 'b', &2i),
      Transition::new(&2i, & 'c', &2i)
    ];
    let relation = TransitionRelation::new(rules);

    let some_rule = relation.transition_for(&1i, & 'a').unwrap();
    assert_eq!(some_rule.state, 1);
    assert_eq!(some_rule.symbol, 'a');
  }
}
<commit_msg>improvement<commit_after>//! moudule for finite automata.

trait State: Eq + Copy {}
trait Symbol: Eq + Copy {}

/// Transition represents the rule that moves from one state to another.
/// `S` means the state, `T` means the input symbol.
pub struct Transition<S: State, T: Symbol> {
  pub state: S,
  pub symbol: T,
  pub next_state: S
}

impl<S: State, T: Symbol> Transition<S, T> {
  pub fn new(state: &S, symbol: &T, next_state: &S) -> Transition<S, T> {
    Transition { state: *state, symbol: *symbol, next_state: *next_state }
  }

  /// determine whether th current transition applies to the state and symbol
  pub fn is_apply_to(&self, state: &S, symbol: &T) -> bool {
    self.state == *state && self.symbol == *symbol
  }

  /// get the next state from the transition
  pub fn follow(&self) -> &S {
    &self.next_state
  }
}

/// a collection of transition rules
pub struct TransitionRelation<S: State, T: Symbol> {
  transitions: Vec<Transition<S, T>>
}

impl<S: State, T: Symbol> TransitionRelation<S, T> {
  pub fn new(transitions: Vec<Transition<S, T>>) -> TransitionRelation<S, T> {
    TransitionRelation { transitions: transitions }
  }

  /// get the next state for the input condition
  pub fn next_state_for(&self, state: &S, symbol: &T) -> Option<&S> {
    self.transition_for(state, symbol).map(|trans| { trans.follow() })
  }

  /// get the transition of the state and the symbol
  fn transition_for(&self, state: &S, symbol: &T) -> Option<&Transition<S, T>> {
    self.transitions.iter().find(|transition| {
      transition.is_apply_to(state, symbol)
    })
  }
}

pub struct DFA<S: State, T: Symbol> {
  current_state: S,
  accept_states: Vec<S>,
  transition_relation: TransitionRelation<S, T>
}

impl<S: State, T: Symbol> DFA<S, T> {
  pub fn new(current_state: &S, accept_states: Vec<S>,
             transition_relation: TransitionRelation<S, T>) -> DFA<S, T> {
    DFA {
      current_state: *current_state,
      accept_states: accept_states,
      transition_relation: transition_relation
    }
  }

  /// read a symbol and change the dfa state
  pub fn read_symbol(&mut self, sym: &T) {
    self.current_state = *self.transition_relation
                             .next_state_for(&self.current_state, sym)
                             .expect("cannot read the symbol in the current state")
  }

  pub fn read_symbol_seq<I: Iterator<T>>(&mut self, syms: &mut I) {
    for ref sym in *syms {
      self.read_symbol(sym);
    }
  }

  /// determine whether the current dfa is in an accepted state
  pub fn is_accepting(&self) -> bool {
    self.accept_states.iter().any(|&state| {
      state == self.current_state
    })
  }
}

#[cfg(test)]
mod test {
  use super::State;
  use super::Symbol;
  use super::Transition;
  use super::TransitionRelation;

  impl State for int {}
  impl Symbol for char {}

  #[test]
  fn test_transition() {
    let rule = Transition::new(&1i, & 'a', &2i);
    assert_eq!(2i, rule.next_state);
  }

  #[test]
  fn test_transition_relation() {
    let rules = vec![
      Transition::new(&1i, & 'a', &1i),
      Transition::new(&1i, & 'b', &2i),
      Transition::new(&2i, & 'c', &2i)
    ];
    let relation = TransitionRelation::new(rules);

    let some_rule = relation.transition_for(&1i, & 'a').unwrap();
    assert_eq!(some_rule.state, 1);
    assert_eq!(some_rule.symbol, 'a');
  }
}
<|endoftext|>


<commit_before>use std::io;
use serialize::hex::ToHex;

use super::logger::{RecordInfo};

#[allow(missing_docs)]
mod error {
    use std::io;

    error_chain! {
        types {
            Error, ErrorKind, ChainErr, Result;
        }
        links {}
        foreign_links {
            io::Error, Io, "io error";
        }
        errors {
            Other {
                description("other serialization error")
                    display("other serialization error")
            }
        }
    }
}

pub use self::error::{Error, Result, ErrorKind};

/// Value that can be serialized
///
/// Loggers require values in key-value pairs to
/// implement this trait.
///
pub trait Serialize: Send + Sync {
    /// Serialize self into `Serializer`
    ///
    /// Structs implementing this trait should generally
    /// only call respective methods of `serializer`.
    fn serialize(&self, rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> ;
}

/// Value that can be serialized and stored
/// in logger itself.
///
/// As Loggers itself must be thread-safe, they can only
/// store values implementing this trait.
pub trait SyncSerialize: Send + Sync + 'static + Serialize {}

/// Serializer
///
/// Drains using `Format` will internally use
/// types implementing this trait.
pub trait Serializer {
    /// Emit bool
    fn emit_bool(&mut self, key: &str, val: bool) -> Result<()>;
    /// Emit `()`
    fn emit_unit(&mut self, key: &str) -> Result<()>;
    /// Emit `None`
    fn emit_none(&mut self, key: &str) -> Result<()>;
    /// Emit char
    fn emit_char(&mut self, key: &str, val: char) -> Result<()>;
    /// Emit bytes
    fn emit_bytes(&mut self, key: &str, val: &[u8]) -> Result<()>;
    /// Emit u8
    fn emit_u8(&mut self, key: &str, val: u8) -> Result<()>;
    /// Emit i8
    fn emit_i8(&mut self, key: &str, val: i8) -> Result<()>;
    /// Emit u16
    fn emit_u16(&mut self, key: &str, val: u16) -> Result<()>;
    /// Emit i16
    fn emit_i16(&mut self, key: &str, val: i16) -> Result<()>;
    /// Emit u32
    fn emit_u32(&mut self, key: &str, val: u32) -> Result<()>;
    /// Emit i32
    fn emit_i32(&mut self, key: &str, val: i32) -> Result<()>;
    /// Emit f32
    fn emit_f32(&mut self, key: &str, val: f32) -> Result<()>;
    /// Emit u64
    fn emit_u64(&mut self, key: &str, val: u64) -> Result<()>;
    /// Emit i64
    fn emit_i64(&mut self, key: &str, val: i64) -> Result<()>;
    /// Emit f64
    fn emit_f64(&mut self, key: &str, val: f64) -> Result<()>;
    /// Emit usize
    fn emit_usize(&mut self, key: &str, val: usize) -> Result<()>;
    /// Emit isize
    fn emit_isize(&mut self, key: &str, val: isize) -> Result<()>;
    /// Emit str
    fn emit_str(&mut self, key: &str, val: &str) -> Result<()>;
}

impl Serialize for str {
    fn serialize(&self, _rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        serializer.emit_str(key, self)
    }
}

impl<'a> Serialize for &'a str {
    fn serialize(&self, _rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        serializer.emit_str(key, self)
    }
}

impl SyncSerialize for &'static str {}

impl Serialize for [u8] {
    fn serialize(&self, _rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        serializer.emit_bytes(key, self)
    }
}

impl SyncSerialize for [u8] {}

impl Serialize for Vec<u8> {
    fn serialize(&self, _rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        serializer.emit_bytes(key, self.as_slice())
    }
}

impl SyncSerialize for Vec<u8> {}

impl<T: Serialize> Serialize for Option<T> {
    fn serialize(&self, rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        match *self {
            Some(ref s) => s.serialize(rinfo, key, serializer),
            None => serializer.emit_none(key),
        }
    }
}

impl<T: Serialize + 'static> SyncSerialize for Option<T> {}

impl Serialize for String {
    fn serialize(&self, _rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        serializer.emit_str(key, self.as_str())
    }
}

impl SyncSerialize for String {}

macro_rules! impl_serialize_for{
    ($t:ty, $f:ident) => {
        impl Serialize for $t {
            fn serialize(&self, _rinfo : &RecordInfo, key : &str, serializer : &mut Serializer)
                         -> Result<()> {
                serializer.$f(key, *self)
            }
        }

        impl SyncSerialize for $t where $t : Send+Sync+'static { }
    };
}

impl_serialize_for!(usize, emit_usize);
impl_serialize_for!(isize, emit_isize);
impl_serialize_for!(bool, emit_bool);
impl_serialize_for!(char, emit_char);
impl_serialize_for!(u8, emit_u8);
impl_serialize_for!(i8, emit_i8);
impl_serialize_for!(u16, emit_u16);
impl_serialize_for!(i16, emit_i16);
impl_serialize_for!(u32, emit_u32);
impl_serialize_for!(i32, emit_i32);
impl_serialize_for!(f32, emit_f32);
impl_serialize_for!(u64, emit_u64);
impl_serialize_for!(i64, emit_i64);
impl_serialize_for!(f64, emit_f64);

impl<S: 'static + Serialize, F: 'static + Sync + Send + for<'c> Fn(&'c RecordInfo<'c>) -> S> Serialize for F {
    fn serialize(&self, rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        (*self)(&rinfo).serialize(rinfo, key, serializer)
    }
}

impl<S: 'static + Serialize, F: 'static + Sync + Send + for<'c, 'd> Fn(&'c RecordInfo<'d>) -> S> SyncSerialize for F {}

impl<W: io::Write + ?Sized> Serializer for W {
    fn emit_none(&mut self, key: &str) -> Result<()> {
        try!(write!(self, "{}: {}", key, "None"));
        Ok(())
    }
    fn emit_unit(&mut self, key: &str) -> Result<()> {
        try!(write!(self, "{}: ()", key, ));
        Ok(())
    }

    fn emit_bool(&mut self, key: &str, val: bool) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }

    fn emit_char(&mut self, key: &str, val: char) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_bytes(&mut self, key: &str, val: &[u8]) -> Result<()> {
        try!(write!(self, "{}: {}", key, val.to_hex()));
        Ok(())
    }

    fn emit_usize(&mut self, key: &str, val: usize) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_isize(&mut self, key: &str, val: isize) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }

    fn emit_u8(&mut self, key: &str, val: u8) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_i8(&mut self, key: &str, val: i8) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_u16(&mut self, key: &str, val: u16) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_i16(&mut self, key: &str, val: i16) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_u32(&mut self, key: &str, val: u32) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_i32(&mut self, key: &str, val: i32) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_f32(&mut self, key: &str, val: f32) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_u64(&mut self, key: &str, val: u64) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_i64(&mut self, key: &str, val: i64) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_f64(&mut self, key: &str, val: f64) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_str(&mut self, key: &str, val: &str) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
}
<commit_msg>Don't require `'static` on in closures in `b!`<commit_after>use std::io;
use serialize::hex::ToHex;

use super::logger::{RecordInfo};

#[allow(missing_docs)]
mod error {
    use std::io;

    error_chain! {
        types {
            Error, ErrorKind, ChainErr, Result;
        }
        links {}
        foreign_links {
            io::Error, Io, "io error";
        }
        errors {
            Other {
                description("other serialization error")
                    display("other serialization error")
            }
        }
    }
}

pub use self::error::{Error, Result, ErrorKind};

/// Value that can be serialized
///
/// Loggers require values in key-value pairs to
/// implement this trait.
///
pub trait Serialize: Send + Sync {
    /// Serialize self into `Serializer`
    ///
    /// Structs implementing this trait should generally
    /// only call respective methods of `serializer`.
    fn serialize(&self, rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> ;
}

/// Value that can be serialized and stored
/// in logger itself.
///
/// As Loggers itself must be thread-safe, they can only
/// store values implementing this trait.
pub trait SyncSerialize: Send + Sync + 'static + Serialize {}

/// Serializer
///
/// Drains using `Format` will internally use
/// types implementing this trait.
pub trait Serializer {
    /// Emit bool
    fn emit_bool(&mut self, key: &str, val: bool) -> Result<()>;
    /// Emit `()`
    fn emit_unit(&mut self, key: &str) -> Result<()>;
    /// Emit `None`
    fn emit_none(&mut self, key: &str) -> Result<()>;
    /// Emit char
    fn emit_char(&mut self, key: &str, val: char) -> Result<()>;
    /// Emit bytes
    fn emit_bytes(&mut self, key: &str, val: &[u8]) -> Result<()>;
    /// Emit u8
    fn emit_u8(&mut self, key: &str, val: u8) -> Result<()>;
    /// Emit i8
    fn emit_i8(&mut self, key: &str, val: i8) -> Result<()>;
    /// Emit u16
    fn emit_u16(&mut self, key: &str, val: u16) -> Result<()>;
    /// Emit i16
    fn emit_i16(&mut self, key: &str, val: i16) -> Result<()>;
    /// Emit u32
    fn emit_u32(&mut self, key: &str, val: u32) -> Result<()>;
    /// Emit i32
    fn emit_i32(&mut self, key: &str, val: i32) -> Result<()>;
    /// Emit f32
    fn emit_f32(&mut self, key: &str, val: f32) -> Result<()>;
    /// Emit u64
    fn emit_u64(&mut self, key: &str, val: u64) -> Result<()>;
    /// Emit i64
    fn emit_i64(&mut self, key: &str, val: i64) -> Result<()>;
    /// Emit f64
    fn emit_f64(&mut self, key: &str, val: f64) -> Result<()>;
    /// Emit usize
    fn emit_usize(&mut self, key: &str, val: usize) -> Result<()>;
    /// Emit isize
    fn emit_isize(&mut self, key: &str, val: isize) -> Result<()>;
    /// Emit str
    fn emit_str(&mut self, key: &str, val: &str) -> Result<()>;
}

impl Serialize for str {
    fn serialize(&self, _rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        serializer.emit_str(key, self)
    }
}

impl<'a> Serialize for &'a str {
    fn serialize(&self, _rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        serializer.emit_str(key, self)
    }
}

impl SyncSerialize for &'static str {}

impl Serialize for [u8] {
    fn serialize(&self, _rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        serializer.emit_bytes(key, self)
    }
}

impl SyncSerialize for [u8] {}

impl Serialize for Vec<u8> {
    fn serialize(&self, _rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        serializer.emit_bytes(key, self.as_slice())
    }
}

impl SyncSerialize for Vec<u8> {}

impl<T: Serialize> Serialize for Option<T> {
    fn serialize(&self, rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        match *self {
            Some(ref s) => s.serialize(rinfo, key, serializer),
            None => serializer.emit_none(key),
        }
    }
}

impl<T: Serialize + 'static> SyncSerialize for Option<T> {}

impl Serialize for String {
    fn serialize(&self, _rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        serializer.emit_str(key, self.as_str())
    }
}

impl SyncSerialize for String {}

macro_rules! impl_serialize_for{
    ($t:ty, $f:ident) => {
        impl Serialize for $t {
            fn serialize(&self, _rinfo : &RecordInfo, key : &str, serializer : &mut Serializer)
                         -> Result<()> {
                serializer.$f(key, *self)
            }
        }

        impl SyncSerialize for $t where $t : Send+Sync+'static { }
    };
}

impl_serialize_for!(usize, emit_usize);
impl_serialize_for!(isize, emit_isize);
impl_serialize_for!(bool, emit_bool);
impl_serialize_for!(char, emit_char);
impl_serialize_for!(u8, emit_u8);
impl_serialize_for!(i8, emit_i8);
impl_serialize_for!(u16, emit_u16);
impl_serialize_for!(i16, emit_i16);
impl_serialize_for!(u32, emit_u32);
impl_serialize_for!(i32, emit_i32);
impl_serialize_for!(f32, emit_f32);
impl_serialize_for!(u64, emit_u64);
impl_serialize_for!(i64, emit_i64);
impl_serialize_for!(f64, emit_f64);

impl<S: 'static + Serialize, F: Sync + Send + for<'c> Fn(&'c RecordInfo<'c>) -> S> Serialize for F {
    fn serialize(&self, rinfo: &RecordInfo, key: &str, serializer: &mut Serializer) -> Result<()> {
        (*self)(&rinfo).serialize(rinfo, key, serializer)
    }
}

impl<S: 'static + Serialize, F: 'static + Sync + Send + for<'c, 'd> Fn(&'c RecordInfo<'d>) -> S> SyncSerialize for F {}

impl<W: io::Write + ?Sized> Serializer for W {
    fn emit_none(&mut self, key: &str) -> Result<()> {
        try!(write!(self, "{}: {}", key, "None"));
        Ok(())
    }
    fn emit_unit(&mut self, key: &str) -> Result<()> {
        try!(write!(self, "{}: ()", key, ));
        Ok(())
    }

    fn emit_bool(&mut self, key: &str, val: bool) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }

    fn emit_char(&mut self, key: &str, val: char) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_bytes(&mut self, key: &str, val: &[u8]) -> Result<()> {
        try!(write!(self, "{}: {}", key, val.to_hex()));
        Ok(())
    }

    fn emit_usize(&mut self, key: &str, val: usize) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_isize(&mut self, key: &str, val: isize) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }

    fn emit_u8(&mut self, key: &str, val: u8) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_i8(&mut self, key: &str, val: i8) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_u16(&mut self, key: &str, val: u16) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_i16(&mut self, key: &str, val: i16) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_u32(&mut self, key: &str, val: u32) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_i32(&mut self, key: &str, val: i32) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_f32(&mut self, key: &str, val: f32) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_u64(&mut self, key: &str, val: u64) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_i64(&mut self, key: &str, val: i64) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_f64(&mut self, key: &str, val: f64) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
    fn emit_str(&mut self, key: &str, val: &str) -> Result<()> {
        try!(write!(self, "{}: {}", key, val));
        Ok(())
    }
}
<|endoftext|>


<commit_before>fn main() {
    let mut i = 1u64;
    for uint::range(0u, 63u) |_n| {
        let sum = vec::foldl(0u, do vec::filter_map(str::chars(#fmt("%u", i as uint))) |c| {
            uint::from_str(str::from_char(c))
        }, |s, n| s + n);
        io::println(#fmt("%20u => %3u", i as uint, sum));
        i *= 2u64;
    }
}

<commit_msg>Add problem #16<commit_after>extern mod euler;

use euler::extnum::{ one, from_uint };
use euler::bigint::{ BigInt };

fn main() {
    let mut i = one::<BigInt>();
    for uint::range(0, 1000) |_n| {
        i *= from_uint(2);
    }
    let sum = do str::byte_slice(i.to_str()) |buf| {
        buf.map(|c| c - ('0' as u8)).foldl(0, |s, e| s + (e as uint))
    };
    io::println(fmt!("%u", sum));
}

<|endoftext|>


<commit_before>use sys;
use bullet_vector3::BulletVector3;
use collision::collision_shapes::Shape;
use mint::{Vector3, Vector4};

pub struct RigidBody {
    rigid_body: Box<sys::btRigidBody>,
    shape: Box<Shape>,
    motion_state: Box<sys::btDefaultMotionState>,
    construction_info: Box<sys::btRigidBody_btRigidBodyConstructionInfo>,
}

impl RigidBody {
    pub fn new<T1: Into<Vector3<f64>>, T2: Into<Vector3<f64>>, T3: Into<Vector4<f64>>>(
        mass: f64,
        inertia: T1,
        shape: Shape,
        translation: T2,
        orientation: T3,
    ) -> RigidBody {
        let mut inertia: BulletVector3 = inertia.into().into();
        let shape_box = Box::new(shape);
        let translation: BulletVector3 = translation.into().into();
        let orientation: [f64; 4] = orientation.into().into();
        let transform = unsafe {
            sys::btTransform::new1(
                &orientation as *const _ as *const _,
                &translation as *const _ as *const _,
            )
        };
        let mut motion_state_box = Box::new(unsafe {
            sys::btDefaultMotionState::new(&transform as *const _, sys::btTransform::getIdentity())
        });

        let construction_info_box = Box::new(unsafe {
            sys::btRigidBody_btRigidBodyConstructionInfo::new(
                mass,
                &mut *motion_state_box as *mut _ as *mut _,
                shape_box.as_ptr(),
                inertia.0.as_mut_ptr() as *mut _,
            )
        });
        RigidBody {
            rigid_body: Box::new(unsafe {
                sys::btRigidBody::new(&*construction_info_box as *const _)
            }),
            shape: shape_box,
            motion_state: motion_state_box,
            construction_info: construction_info_box,
        }
    }

    pub(crate) unsafe fn motion_state_ptr(&self) -> *mut sys::btDefaultMotionState {
        &*self.motion_state as *const _ as *mut _
    }

    pub(crate) unsafe fn as_ptr(&self) -> *mut sys::btRigidBody {
        &*self.rigid_body as *const _ as *mut _
    }
}

#[derive(Clone)]
pub struct RigidBodyHandle {
    pub(in dynamics) ptr: *mut sys::btRigidBody,
    motion_state: *mut sys::btDefaultMotionState,
    temp_transform: sys::btTransform,
}

impl RigidBodyHandle {
    pub fn new(ptr: *mut sys::btRigidBody, motion_state: *mut sys::btDefaultMotionState) -> Self {
        let temp_transform = unsafe { sys::btTransform::new() };

        RigidBodyHandle {
            ptr,
            motion_state,
            temp_transform,
        }
    }
    pub fn set_restitution(&mut self, restitution: f64) {
        unsafe {
            sys::btCollisionObject_setRestitution(self.ptr as *mut _, restitution);
        }
    }

    pub fn set_gravity<T: Into<Vector3<f64>>>(&mut self, gravity: T) {
        let gravity: BulletVector3 = gravity.into().into();
        unsafe {
            sys::btRigidBody_setGravity(self.ptr, gravity.0.as_ptr() as *const _);
        }
    }

    pub fn set_angular_factor<T: Into<Vector3<f64>>>(&mut self, angular_factor: T) {
        let angular_factor: BulletVector3 = angular_factor.into().into();
        unsafe {
            sys::btRigidBody_setAngularFactor(self.ptr, angular_factor.0.as_ptr() as *const _);
        }
    }

    pub fn set_sleeping_thresholds(&mut self, linear: f64, angular: f64) {
        unsafe { sys::btRigidBody_setSleepingThresholds(self.ptr, linear, angular) }
    }

    pub fn apply_central_impulse<T: Into<Vector3<f64>>>(&mut self, impulse: T) {
        let impulse: BulletVector3 = impulse.into().into();
        unsafe {
            sys::btRigidBody_applyCentralImpulse(self.ptr, impulse.0.as_ptr() as *const _);
        }
    }

    pub fn get_linear_velocity(&self) -> Vector3<f64> {
        let velocity = unsafe { sys::btRigidBody_getLinearVelocity(self.ptr) };

        ::bullet_vector3::vector_from_slice(unsafe {
            ::std::slice::from_raw_parts(velocity as *const _, 4)
        })
    }

    /// Override position vector and rotation quaternion.
    pub fn reset_position_and_orientation<T, T1>(&mut self, position: T, orientation: T1)
    where
        T: Into<Vector3<f64>>,
        T1: Into<Vector4<f64>>,
    {
        let orientation: [f64; 4] = orientation.into().into();
        let position: BulletVector3 = position.into().into();
        let transform = unsafe {
            sys::btTransform::new1(
                &orientation as *const _ as *const _,
                &position as *const _ as *const _,
            )
        };

        unsafe { (*self.ptr)._base.m_worldTransform = transform };
    }

    /// Get position in world space and orientation quaternion
    pub fn get_world_position_and_orientation(&self) -> (Vector3<f64>, Vector4<f64>) {
        unsafe {
            sys::btDefaultMotionState_getWorldTransform(
                &*self.motion_state as *const _ as *mut _,
                &self.temp_transform as *const _ as *mut _,
            );
        }
        let origin = unsafe { self.temp_transform.getOrigin1().as_ref().unwrap() };

        let rotation = unsafe { self.temp_transform.getRotation() };

        (
            ::bullet_vector3::vector_from_slice(&origin.m_floats[0..3]),
            ::bullet_vector3::vector4_from_slice(&rotation._base.m_floats),
        )
    }

    /// Place data on heap as a box and set to rigid body as user pointer
    pub fn set_user_data<T: 'static>(&mut self, data: T) {
        let data_box = Box::new(data);
        unsafe {
            sys::btCollisionObject_setUserPointer(
                self.ptr as *mut _,
                Box::into_raw(data_box) as *mut _,
            )
        };
    }

    /// Get data from rigidbody's user pointer
    /// Getting data from body without previously setted data is fine.
    /// Getting wrong typed data is unsafe and will cause mem::transmute to wrong pointer type.
    pub unsafe fn get_user_data<T: 'static>(&self) -> Option<&T> {
        let pointer = sys::btCollisionObject_getUserPointer(self.ptr as *mut _);
        let pointer: *const T = ::std::mem::transmute(pointer);
        return pointer.as_ref();
    }

    /// Set user index. This will not be used in bullet and this is not related to user_data.
    pub fn set_user_index(&mut self, index: i32) {
        unsafe { sys::btCollisionObject_setUserIndex(self.ptr as *mut _, index) };
    }

    /// Get previously setted user index
    /// If index was not set - will return "-1"
    pub fn get_user_index(&self) -> i32 {
        unsafe { sys::btCollisionObject_getUserIndex(self.ptr as *mut _) }
    }

    /// Was that rigid_body removed with DynamicsWorld::remove_body()
    /// Probably may return true also for any not-added bodys
    pub fn removed(&self) -> bool {
        unsafe { (*self.ptr)._base.m_worldArrayIndex == -1 }
    }
}
<commit_msg>add RigidBodyHandle::set_friction<commit_after>use sys;
use bullet_vector3::BulletVector3;
use collision::collision_shapes::Shape;
use mint::{Vector3, Vector4};

pub struct RigidBody {
    rigid_body: Box<sys::btRigidBody>,
    shape: Box<Shape>,
    motion_state: Box<sys::btDefaultMotionState>,
    construction_info: Box<sys::btRigidBody_btRigidBodyConstructionInfo>,
}

impl RigidBody {
    pub fn new<T1: Into<Vector3<f64>>, T2: Into<Vector3<f64>>, T3: Into<Vector4<f64>>>(
        mass: f64,
        inertia: T1,
        shape: Shape,
        translation: T2,
        orientation: T3,
    ) -> RigidBody {
        let mut inertia: BulletVector3 = inertia.into().into();
        let shape_box = Box::new(shape);
        let translation: BulletVector3 = translation.into().into();
        let orientation: [f64; 4] = orientation.into().into();
        let transform = unsafe {
            sys::btTransform::new1(
                &orientation as *const _ as *const _,
                &translation as *const _ as *const _,
            )
        };
        let mut motion_state_box = Box::new(unsafe {
            sys::btDefaultMotionState::new(&transform as *const _, sys::btTransform::getIdentity())
        });

        let construction_info_box = Box::new(unsafe {
            sys::btRigidBody_btRigidBodyConstructionInfo::new(
                mass,
                &mut *motion_state_box as *mut _ as *mut _,
                shape_box.as_ptr(),
                inertia.0.as_mut_ptr() as *mut _,
            )
        });
        RigidBody {
            rigid_body: Box::new(unsafe {
                sys::btRigidBody::new(&*construction_info_box as *const _)
            }),
            shape: shape_box,
            motion_state: motion_state_box,
            construction_info: construction_info_box,
        }
    }

    pub(crate) unsafe fn motion_state_ptr(&self) -> *mut sys::btDefaultMotionState {
        &*self.motion_state as *const _ as *mut _
    }

    pub(crate) unsafe fn as_ptr(&self) -> *mut sys::btRigidBody {
        &*self.rigid_body as *const _ as *mut _
    }
}

#[derive(Clone)]
pub struct RigidBodyHandle {
    pub(in dynamics) ptr: *mut sys::btRigidBody,
    motion_state: *mut sys::btDefaultMotionState,
    temp_transform: sys::btTransform,
}

impl RigidBodyHandle {
    pub fn new(ptr: *mut sys::btRigidBody, motion_state: *mut sys::btDefaultMotionState) -> Self {
        let temp_transform = unsafe { sys::btTransform::new() };

        RigidBodyHandle {
            ptr,
            motion_state,
            temp_transform,
        }
    }
    pub fn set_restitution(&mut self, restitution: f64) {
        unsafe {
            sys::btCollisionObject_setRestitution(self.ptr as *mut _, restitution);
        }
    }
    pub fn set_friction(&mut self, friction: f64) {
        unsafe {
            sys::btCollisionObject_setFriction(self.ptr as *mut _, friction);
        }
    }
    pub fn set_gravity<T: Into<Vector3<f64>>>(&mut self, gravity: T) {
        let gravity: BulletVector3 = gravity.into().into();
        unsafe {
            sys::btRigidBody_setGravity(self.ptr, gravity.0.as_ptr() as *const _);
        }
    }

    pub fn set_angular_factor<T: Into<Vector3<f64>>>(&mut self, angular_factor: T) {
        let angular_factor: BulletVector3 = angular_factor.into().into();
        unsafe {
            sys::btRigidBody_setAngularFactor(self.ptr, angular_factor.0.as_ptr() as *const _);
        }
    }

    pub fn set_sleeping_thresholds(&mut self, linear: f64, angular: f64) {
        unsafe { sys::btRigidBody_setSleepingThresholds(self.ptr, linear, angular) }
    }

    pub fn apply_central_impulse<T: Into<Vector3<f64>>>(&mut self, impulse: T) {
        let impulse: BulletVector3 = impulse.into().into();
        unsafe {
            sys::btRigidBody_applyCentralImpulse(self.ptr, impulse.0.as_ptr() as *const _);
        }
    }

    pub fn get_linear_velocity(&self) -> Vector3<f64> {
        let velocity = unsafe { sys::btRigidBody_getLinearVelocity(self.ptr) };

        ::bullet_vector3::vector_from_slice(unsafe {
            ::std::slice::from_raw_parts(velocity as *const _, 4)
        })
    }

    /// Override position vector and rotation quaternion.
    pub fn reset_position_and_orientation<T, T1>(&mut self, position: T, orientation: T1)
    where
        T: Into<Vector3<f64>>,
        T1: Into<Vector4<f64>>,
    {
        let orientation: [f64; 4] = orientation.into().into();
        let position: BulletVector3 = position.into().into();
        let transform = unsafe {
            sys::btTransform::new1(
                &orientation as *const _ as *const _,
                &position as *const _ as *const _,
            )
        };

        unsafe { (*self.ptr)._base.m_worldTransform = transform };
    }

    /// Get position in world space and orientation quaternion
    pub fn get_world_position_and_orientation(&self) -> (Vector3<f64>, Vector4<f64>) {
        unsafe {
            sys::btDefaultMotionState_getWorldTransform(
                &*self.motion_state as *const _ as *mut _,
                &self.temp_transform as *const _ as *mut _,
            );
        }
        let origin = unsafe { self.temp_transform.getOrigin1().as_ref().unwrap() };

        let rotation = unsafe { self.temp_transform.getRotation() };

        (
            ::bullet_vector3::vector_from_slice(&origin.m_floats[0..3]),
            ::bullet_vector3::vector4_from_slice(&rotation._base.m_floats),
        )
    }

    /// Place data on heap as a box and set to rigid body as user pointer
    pub fn set_user_data<T: 'static>(&mut self, data: T) {
        let data_box = Box::new(data);
        unsafe {
            sys::btCollisionObject_setUserPointer(
                self.ptr as *mut _,
                Box::into_raw(data_box) as *mut _,
            )
        };
    }

    /// Get data from rigidbody's user pointer
    /// Getting data from body without previously setted data is fine.
    /// Getting wrong typed data is unsafe and will cause mem::transmute to wrong pointer type.
    pub unsafe fn get_user_data<T: 'static>(&self) -> Option<&T> {
        let pointer = sys::btCollisionObject_getUserPointer(self.ptr as *mut _);
        let pointer: *const T = ::std::mem::transmute(pointer);
        return pointer.as_ref();
    }

    /// Set user index. This will not be used in bullet and this is not related to user_data.
    pub fn set_user_index(&mut self, index: i32) {
        unsafe { sys::btCollisionObject_setUserIndex(self.ptr as *mut _, index) };
    }

    /// Get previously setted user index
    /// If index was not set - will return "-1"
    pub fn get_user_index(&self) -> i32 {
        unsafe { sys::btCollisionObject_getUserIndex(self.ptr as *mut _) }
    }

    /// Was that rigid_body removed with DynamicsWorld::remove_body()
    /// Probably may return true also for any not-added bodys
    pub fn removed(&self) -> bool {
        unsafe { (*self.ptr)._base.m_worldArrayIndex == -1 }
    }
}
<|endoftext|>


<commit_before>//! A slow, but clear reference implementation of SeaHash.
//!
//! # Specification
//!
//! The input buffer is padded with null bytes until the length is divisible by 8.
//!
//! We start out with state
//!
//! ```notest
//! a = 0x16f11fe89b0d677c
//! b = 0xb480a793d8e6c86c
//! c = 0x6fe2e5aaf078ebc9
//! d = 0x14f994a4c5259381
//! ```
//!
//! From the stream, we read one 64-bit block (in little-endian) at a time.  This number, `n`,
//! determines the new the new state by:
//!
//! ```notest
//! a' = b
//! b' = c
//! c' = d
//! d  = g(a ⊕ n)
//! ```
//!
//! `g(x)` is defined as `g(x) = h(j(h(j(x)))))` with `h(x) = x ≫ 32` and `j(x) ≡ px (mod 2^64)`
//! with `p = 0x7ed0e9fa0d94a33`.
//!
//! Let the final state be `(x, y, z, w)`. Then the final result is given by `H = g(x ⊕ y ⊕ z ⊕ w ⊕
//! l)` where `l` is the number of bytes in the original buffer.

use diffuse;

/// Read an integer in little-endian.
fn read_int(int: &[u8]) -> u64 {
    debug_assert!(int.len() <= 8, "The buffer length of the integer must be less than or equal to \
                  the one of an u64.");

    // Start at 0.
    let mut x = 0;
    for &i in int.iter().rev() {
        // Shift up a byte.
        x <<= 8;
        // Set the lower byte.
        x |= i as u64;
    }

    x
}

/// A hash state.
struct State {
    /// The state vector.
    vec: [u64; 4],
    /// The component of the state vector which is currently being modified.
    cur: usize,
}

impl State {
    /// Write a 64-bit integer to the state.
    fn write_u64(&mut self, x: u64) {
        // Mix it into the substate by XORing it.
        self.vec[self.cur] ^= x;
        // Diffuse the component to remove deterministic behavior and commutativity.
        self.vec[self.cur] = diffuse(self.vec[self.cur]);

        // Increment the cursor.
        self.cur += 1;
        // Wrap around.
        self.cur %= 4;
    }

    /// Calculate the final hash.
    fn finish(self, total: usize) -> u64 {
        // Even though XORing is commutative, it doesn't matter, because the state vector's initial
        // components are mutually distinct, and thus swapping even and odd chunks will affect the
        // result, because it is sensitive to the initial condition. To add discreteness, we
        // diffuse.
        diffuse(self.vec[0]
            ^ self.vec[1]
            ^ self.vec[2]
            ^ self.vec[3]
            // We XOR in the number of written bytes to make it zero-sensitive when excessive bytes
            // are written (0u32.0u8 ≠ 0u16.0u8).
            ^ total as u64
        )
    }

    fn with_seed(seed: u64) -> State {
        State {
            // These values are randomly generated, and can be changed to anything (you could make
            // the hash function keyed by replacing these.)
            vec: [
                0x16f11fe89b0d677c ^ seed,
                0xb480a793d8e6c86c ^ seed,
                0x6fe2e5aaf078ebc9 ^ seed,
                0x14f994a4c5259381 ^ seed,
            ],
            // We start at the first component.
            cur: 0,
        }
    }
}

/// A reference implementation of SeaHash.
///
/// This is bloody slow when compared to the optimized version. This is because SeaHash was
/// specifically designed to take all sorts of hardware and software hacks into account to achieve
/// maximal performance, but this makes code significantly less readable. As such, this version has
/// only one goal: to make the algorithm readable and understandable.
pub fn hash(buf: &[u8]) -> u64 {
    hash_seeded(buf, 0)
}

/// The seeded version of the reference implementation.
pub fn hash_seeded(buf: &[u8], seed: u64) -> u64 {
    // Initialize the state.
    let mut state = State::with_seed(seed);

    // Partition the rounded down buffer to chunks of 8 bytes, and iterate over them. The last
    // block might not be 8 bytes long.
    for int in buf.chunks(8) {
        // Read the chunk into an integer and write into the state.
        state.write_u64(read_int(int));
    }

    // Finish the hash state and return the final value.
    state.finish(buf.len())
}
<commit_msg>Store substate fields instead of a state vector in the SeaHash reference implementation.<commit_after>//! A slow, but clear reference implementation of SeaHash.
//!
//! # Specification
//!
//! The input buffer is padded with null bytes until the length is divisible by 8.
//!
//! We start out with state
//!
//! ```notest
//! a = 0x16f11fe89b0d677c
//! b = 0xb480a793d8e6c86c
//! c = 0x6fe2e5aaf078ebc9
//! d = 0x14f994a4c5259381
//! ```
//!
//! From the stream, we read one 64-bit block (in little-endian) at a time.  This number, `n`,
//! determines the new the new state by:
//!
//! ```notest
//! a' = b
//! b' = c
//! c' = d
//! d  = g(a ⊕ n)
//! ```
//!
//! `g(x)` is defined as `g(x) = h(j(h(j(x)))))` with `h(x) = x ≫ 32` and `j(x) ≡ px (mod 2^64)`
//! with `p = 0x7ed0e9fa0d94a33`.
//!
//! Let the final state be `(x, y, z, w)`. Then the final result is given by `H = g(x ⊕ y ⊕ z ⊕ w ⊕
//! l)` where `l` is the number of bytes in the original buffer.

use diffuse;

/// Read an integer in little-endian.
fn read_int(int: &[u8]) -> u64 {
    debug_assert!(int.len() <= 8, "The buffer length of the integer must be less than or equal to \
                  the one of an u64.");

    // Start at 0.
    let mut x = 0;
    for &i in int.iter().rev() {
        // Shift up a byte.
        x <<= 8;
        // Set the lower byte.
        x |= i as u64;
    }

    x
}

/// A hash state.
struct State {
    /// The `a` substate.
    a: u64,
    /// The `b` substate.
    b: u64,
    /// The `c` substate.
    c: u64,
    /// The `d` substate.
    d: u64,
}

impl State {
    /// Write a 64-bit integer to the state.
    fn write_u64(&mut self, x: u64) {
        let mut a = self.a;

        // Mix `x` into `a`.
        a = diffuse(a ^ x);

        //  Rotate around.
        //  _______________________
        // |                       v
        // a <---- b <---- c <---- d
        self.a = self.b;
        self.b = self.c;
        self.c = self.d;
        self.d = a;
    }

    /// Calculate the final hash.
    fn finish(self, total: usize) -> u64 {
        // Even though XORing is commutative, it doesn't matter, because the state vector's initial
        // components are mutually distinct, and thus swapping even and odd chunks will affect the
        // result, because it is sensitive to the initial condition. To add discreteness, we
        // diffuse.
        diffuse(self.a
            ^ self.b
            ^ self.c
            ^ self.d
            // We XOR in the number of written bytes to make it zero-sensitive when excessive bytes
            // are written (0u32.0u8 ≠ 0u16.0u8).
            ^ total as u64
        )
    }

    fn with_seed(seed: u64) -> State {
        State {
            // These values are randomly generated.
            a: 0x16f11fe89b0d677c ^ seed,
            b: 0xb480a793d8e6c86c ^ seed,
            c: 0x6fe2e5aaf078ebc9 ^ seed,
            d: 0x14f994a4c5259381 ^ seed,
        }
    }
}

/// A reference implementation of SeaHash.
///
/// This is bloody slow when compared to the optimized version. This is because SeaHash was
/// specifically designed to take all sorts of hardware and software hacks into account to achieve
/// maximal performance, but this makes code significantly less readable. As such, this version has
/// only one goal: to make the algorithm readable and understandable.
#[inline]
pub fn hash(buf: &[u8]) -> u64 {
    hash_seeded(buf, 0)
}

/// The seeded version of the reference implementation.
#[inline]
pub fn hash_seeded(buf: &[u8], seed: u64) -> u64 {
    // Initialize the state.
    let mut state = State::with_seed(seed);

    // Partition the rounded down buffer to chunks of 8 bytes, and iterate over them. The last
    // block might not be 8 bytes long.
    for int in buf.chunks(8) {
        // Read the chunk into an integer and write into the state.
        state.write_u64(read_int(int));
    }

    // Finish the hash state and return the final value.
    state.finish(buf.len())
}
<|endoftext|>


<commit_before>#![feature(box_syntax,box_patterns)]
#![feature(compile)]
#![feature(scheme)]

/// Scheme compiler integration tests
///
/// These are based on the sample programs in Zach Allaun's Clojure SECD
/// [implementation](https://github.com/zachallaun/secd).
/// And from http://webdocs.cs.ualberta.ca/%7Eyou/courses/325/Mynotes/Fun/SECD-slides.html

#[macro_use]
extern crate seax_svm as svm;
extern crate seax_scheme as scheme;

use svm::slist::List::{Cons,Nil};
use svm::cell::Atom::*;
use svm::cell::SVMCell::*;
use svm::Inst::*;

/// Test for simple list construction through CONS.
///
/// ```lisp
/// (cons 10 (cons 20 nil))
/// ```
#[test]
fn compile_list_creation() {
    assert_eq!(
        scheme::compile("(cons 10 (cons 20 nil))"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS)
        ))
    );
}

/// Test for simple list construction and destructuring
///
/// ```lisp
/// (car (cons 20 (cons 10 nil)))
/// ```
#[test]
fn  compile_list_car() {
    assert_eq!(
        scheme::compile("(car (cons 20 (cons 10 nil)))"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS),
            InstCell(CAR)
        ))
    );
}

/// Test for simple list construction and destructuring
///
/// ```lisp
/// (cdr (cons 20 (cons 10 nil)))
/// ```
#[test]
fn compile_list_cdr() {
    assert_eq!(
        scheme::compile("(cdr (cons 20 (cons 10 nil)))"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS),
            InstCell(CDR)
        ))
    );
}

/// Test for simple mathematics application
///
/// ```lisp
/// (+ 10 10)
/// ```
#[test]
fn compile_simple_add(){
    assert_eq!(
        scheme::compile("(+ 10 10)"),
        Ok(list!(
            InstCell(LDC), AtomCell(SInt(10)),
            InstCell(LDC), AtomCell(SInt(10)),
            InstCell(ADD)
        ))
    );
}

/// Test for nested arithmetic
///
/// ```lisp
/// (- 20 (+ 5 5))
/// ```
#[test]
fn compile_nested_arith() {
     assert_eq!(
        scheme::compile("(- 20 (+ 5 5))"),
        Ok(list!(
            InstCell(LDC), AtomCell(SInt(5)),
            InstCell(LDC), AtomCell(SInt(5)),
            InstCell(ADD),
            InstCell(LDC), AtomCell(SInt(20)),
            InstCell(SUB)
        ))
    );
}

/// Tests for basic branching
///
/// ```lisp
/// (if (= 0 (- 1 1)) #t #f)
/// ```
#[test]
fn compile_basic_branching_1() {
    assert_eq!(
        scheme::compile("(if (= 0 (- 1 1)) #t #f)"),
        Ok(list!(
            InstCell(LDC), AtomCell(SInt(1)), InstCell(LDC), AtomCell(SInt(1)),
            InstCell(SUB),
            InstCell(LDC), AtomCell(SInt(0)),
            InstCell(EQ),
            InstCell(SEL),
                ListCell(box list!(InstCell(LDC), AtomCell(SInt(1)), InstCell(JOIN))),
                ListCell(box list!(InstCell(NIL), InstCell(JOIN))
            )
        ))
    );
}
///
/// ```lisp
/// (+ 10 (if (nil? nil) 10 20))
/// ```
#[test]
fn compile_basic_branching_2() {
    assert_eq!(
        scheme::compile("(+ 10 (if (nil? nil) 10 20))"),
        Ok(list!(
            InstCell(NIL), InstCell(NULL),
            InstCell(SEL),
                ListCell(box list!(InstCell(LDC), AtomCell(SInt(10)), InstCell(JOIN))),
                ListCell(box list!(InstCell(LDC), AtomCell(SInt(20)), InstCell(JOIN))),
            InstCell(LDC), AtomCell(SInt(10)),
            InstCell(ADD)
        ))
    );
}

/// Lambda
///
/// ```lisp
/// (lambda (x y) (+ x y))
/// ```
///
/// (LDF (LD (1.2) LD (1.1) + RTN))
#[test]
fn compile_lambda() {
    assert_eq!(
        scheme::compile("(lambda (x y) (+ x y))"),
        Ok(list!(
            InstCell(LDF),
            ListCell(box list!(
                InstCell(LD),
                ListCell(box list!(
                    AtomCell(UInt(1)), AtomCell(UInt(2))
                    )),
                InstCell(LD),
                ListCell(box list!(
                    AtomCell(UInt(1)), AtomCell(UInt(1))
                    )),
                InstCell(ADD),
                InstCell(RET)
            ))
        ))
    )
}

/// Lambda application
///
/// ```lisp
/// ((lambda (x y) (+ x y)) 2 3)
/// ```
///
/// (NIL LDC 3 CONS LDC 2 CONS LDF (LD (1.2) LD (1.1) + RTN) AP)
#[test]
fn compile_lambda_ap() {
    assert_eq!(
        scheme::compile("((lambda (x y) (+ x y)) 2 3)"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(3)),
            InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(2)),
            InstCell(CONS),
            InstCell(LDF),
            ListCell(box list!(
                InstCell(LD), ListCell(box list!(
                    AtomCell(UInt(1)), AtomCell(UInt(2))
                    )),
                InstCell(LD), ListCell(box list!(
                    AtomCell(UInt(1)), AtomCell(UInt(1))
                    )),
                InstCell(ADD),
                InstCell(RET)
            )),
            InstCell(AP)
        ))
    )
}

/// Nested lambdas
///
/// ```lisp
/// ((lambda (z) ((lambda (x y) (+ (- x y) z)) 3 5)) 6)
/// ```
///
/// ```seax
/// (NIL LDC 6 CONS LDF
///     (NIL LDC 5 CONS LDC 3 CONS
///         LDF
///             (LD (2.1) LD (1.2) LD (1.1) SUB ADD RTN)
///         AP
///         RTN)
///     AP
/// ```
#[test]
fn compile_nested_lambda() {
    assert_eq!(
        scheme::compile("((lambda (z) ((lambda (x y) (+ (- x y) z)) 3 5)) 6)"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(6)), InstCell(CONS),
            InstCell(LDF),
            ListCell(box list!(
                InstCell(NIL),
                InstCell(LDC), AtomCell(SInt(5)), InstCell(CONS),
                InstCell(LDC), AtomCell(SInt(3)), InstCell(CONS),
                InstCell(LDF),
                ListCell(box list!(
                    InstCell(LD), ListCell(box list!(
                        AtomCell(UInt(2)),AtomCell(UInt(1))
                        )),
                    InstCell(LD), ListCell(box list!(
                        AtomCell(UInt(1)),AtomCell(UInt(2))
                        )),
                    InstCell(LD), ListCell(box list!(
                        AtomCell(UInt(1)),AtomCell(UInt(1))
                        )),
                    InstCell(SUB),
                    InstCell(ADD),
                    InstCell(RET)
                )),
                InstCell(AP),
                InstCell(RET)
            )),
            InstCell(AP)
        ))
    )
}

/// Test for the compilation of a single simple `let` binding.
///
/// ```lisp
/// (let ([x 5]) x)
/// ```
#[test]
fn compile_single_let() {
    assert_eq!(
        scheme::compile("(let ([x 5]) x)"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(5)), InstCell(CONS),
            InstCell(LDF),
            ListCell(box list!(
                InstCell(LD), ListCell(box list!(
                        AtomCell(UInt(1)),AtomCell(UInt(1))
                    )),
                InstCell(RET)
            )),
            InstCell(AP)
        ))
    );
}<commit_msg>Add a test for compilation of multiple `let` bindings<commit_after>#![feature(box_syntax,box_patterns)]
#![feature(compile)]
#![feature(scheme)]

/// Scheme compiler integration tests
///
/// These are based on the sample programs in Zach Allaun's Clojure SECD
/// [implementation](https://github.com/zachallaun/secd).
/// And from http://webdocs.cs.ualberta.ca/%7Eyou/courses/325/Mynotes/Fun/SECD-slides.html

#[macro_use]
extern crate seax_svm as svm;
extern crate seax_scheme as scheme;

use svm::slist::List::{Cons,Nil};
use svm::cell::Atom::*;
use svm::cell::SVMCell::*;
use svm::Inst::*;

/// Test for simple list construction through CONS.
///
/// ```lisp
/// (cons 10 (cons 20 nil))
/// ```
#[test]
fn compile_list_creation() {
    assert_eq!(
        scheme::compile("(cons 10 (cons 20 nil))"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS)
        ))
    );
}

/// Test for simple list construction and destructuring
///
/// ```lisp
/// (car (cons 20 (cons 10 nil)))
/// ```
#[test]
fn  compile_list_car() {
    assert_eq!(
        scheme::compile("(car (cons 20 (cons 10 nil)))"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS),
            InstCell(CAR)
        ))
    );
}

/// Test for simple list construction and destructuring
///
/// ```lisp
/// (cdr (cons 20 (cons 10 nil)))
/// ```
#[test]
fn compile_list_cdr() {
    assert_eq!(
        scheme::compile("(cdr (cons 20 (cons 10 nil)))"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS),
            InstCell(CDR)
        ))
    );
}

/// Test for simple mathematics application
///
/// ```lisp
/// (+ 10 10)
/// ```
#[test]
fn compile_simple_add(){
    assert_eq!(
        scheme::compile("(+ 10 10)"),
        Ok(list!(
            InstCell(LDC), AtomCell(SInt(10)),
            InstCell(LDC), AtomCell(SInt(10)),
            InstCell(ADD)
        ))
    );
}

/// Test for nested arithmetic
///
/// ```lisp
/// (- 20 (+ 5 5))
/// ```
#[test]
fn compile_nested_arith() {
     assert_eq!(
        scheme::compile("(- 20 (+ 5 5))"),
        Ok(list!(
            InstCell(LDC), AtomCell(SInt(5)),
            InstCell(LDC), AtomCell(SInt(5)),
            InstCell(ADD),
            InstCell(LDC), AtomCell(SInt(20)),
            InstCell(SUB)
        ))
    );
}

/// Tests for basic branching
///
/// ```lisp
/// (if (= 0 (- 1 1)) #t #f)
/// ```
#[test]
fn compile_basic_branching_1() {
    assert_eq!(
        scheme::compile("(if (= 0 (- 1 1)) #t #f)"),
        Ok(list!(
            InstCell(LDC), AtomCell(SInt(1)), InstCell(LDC), AtomCell(SInt(1)),
            InstCell(SUB),
            InstCell(LDC), AtomCell(SInt(0)),
            InstCell(EQ),
            InstCell(SEL),
                ListCell(box list!(InstCell(LDC), AtomCell(SInt(1)), InstCell(JOIN))),
                ListCell(box list!(InstCell(NIL), InstCell(JOIN))
            )
        ))
    );
}
///
/// ```lisp
/// (+ 10 (if (nil? nil) 10 20))
/// ```
#[test]
fn compile_basic_branching_2() {
    assert_eq!(
        scheme::compile("(+ 10 (if (nil? nil) 10 20))"),
        Ok(list!(
            InstCell(NIL), InstCell(NULL),
            InstCell(SEL),
                ListCell(box list!(InstCell(LDC), AtomCell(SInt(10)), InstCell(JOIN))),
                ListCell(box list!(InstCell(LDC), AtomCell(SInt(20)), InstCell(JOIN))),
            InstCell(LDC), AtomCell(SInt(10)),
            InstCell(ADD)
        ))
    );
}

/// Lambda
///
/// ```lisp
/// (lambda (x y) (+ x y))
/// ```
///
/// (LDF (LD (1.2) LD (1.1) + RTN))
#[test]
fn compile_lambda() {
    assert_eq!(
        scheme::compile("(lambda (x y) (+ x y))"),
        Ok(list!(
            InstCell(LDF),
            ListCell(box list!(
                InstCell(LD),
                ListCell(box list!(
                    AtomCell(UInt(1)), AtomCell(UInt(2))
                    )),
                InstCell(LD),
                ListCell(box list!(
                    AtomCell(UInt(1)), AtomCell(UInt(1))
                    )),
                InstCell(ADD),
                InstCell(RET)
            ))
        ))
    )
}

/// Lambda application
///
/// ```lisp
/// ((lambda (x y) (+ x y)) 2 3)
/// ```
///
/// (NIL LDC 3 CONS LDC 2 CONS LDF (LD (1.2) LD (1.1) + RTN) AP)
#[test]
fn compile_lambda_ap() {
    assert_eq!(
        scheme::compile("((lambda (x y) (+ x y)) 2 3)"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(3)),
            InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(2)),
            InstCell(CONS),
            InstCell(LDF),
            ListCell(box list!(
                InstCell(LD), ListCell(box list!(
                    AtomCell(UInt(1)), AtomCell(UInt(2))
                    )),
                InstCell(LD), ListCell(box list!(
                    AtomCell(UInt(1)), AtomCell(UInt(1))
                    )),
                InstCell(ADD),
                InstCell(RET)
            )),
            InstCell(AP)
        ))
    )
}

/// Nested lambdas
///
/// ```lisp
/// ((lambda (z) ((lambda (x y) (+ (- x y) z)) 3 5)) 6)
/// ```
///
/// ```seax
/// (NIL LDC 6 CONS LDF
///     (NIL LDC 5 CONS LDC 3 CONS
///         LDF
///             (LD (2.1) LD (1.2) LD (1.1) SUB ADD RTN)
///         AP
///         RTN)
///     AP
/// ```
#[test]
fn compile_nested_lambda() {
    assert_eq!(
        scheme::compile("((lambda (z) ((lambda (x y) (+ (- x y) z)) 3 5)) 6)"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(6)), InstCell(CONS),
            InstCell(LDF),
            ListCell(box list!(
                InstCell(NIL),
                InstCell(LDC), AtomCell(SInt(5)), InstCell(CONS),
                InstCell(LDC), AtomCell(SInt(3)), InstCell(CONS),
                InstCell(LDF),
                ListCell(box list!(
                    InstCell(LD), ListCell(box list!(
                        AtomCell(UInt(2)),AtomCell(UInt(1))
                        )),
                    InstCell(LD), ListCell(box list!(
                        AtomCell(UInt(1)),AtomCell(UInt(2))
                        )),
                    InstCell(LD), ListCell(box list!(
                        AtomCell(UInt(1)),AtomCell(UInt(1))
                        )),
                    InstCell(SUB),
                    InstCell(ADD),
                    InstCell(RET)
                )),
                InstCell(AP),
                InstCell(RET)
            )),
            InstCell(AP)
        ))
    )
}

/// Test for the compilation of a single simple `let` binding.
///
/// ```lisp
/// (let ([x 5]) x)
/// ```
#[test]
fn compile_single_let() {
    assert_eq!(
        scheme::compile("(let ([x 5]) x)"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(5)), InstCell(CONS),
            InstCell(LDF),
            ListCell(box list!(
                InstCell(LD), ListCell(box list!(
                        AtomCell(UInt(1)),AtomCell(UInt(1))
                    )),
                InstCell(RET)
            )),
            InstCell(AP)
        ))
    );
}

/// Test for the compilation of multiple simple `let` bindings.
///
/// ```lisp
/// (let ([x 1]
///       [y 2]
///       [z 3])
///      (+ x y z))
/// ```
#[test]
fn compile_multiple_let() {
    assert_eq!(
        scheme::compile(
            "(let ([x 1]
                   [y 2]
                   [z 3])
                (+ x y z))"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(1)), InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(2)), InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(3)), InstCell(CONS),
            InstCell(LDF),
            ListCell(box list!(
                InstCell(LD), ListCell(box list!(
                        AtomCell(UInt(1)),AtomCell(UInt(3))
                    )),
                InstCell(LD), ListCell(box list!(
                        AtomCell(UInt(1)),AtomCell(UInt(2))
                    )),
                InstCell(ADD),
                InstCell(LD), ListCell(box list!(
                        AtomCell(UInt(1)),AtomCell(UInt(1))
                    )),
                InstCell(ADD),
                InstCell(RET)
            )),
            InstCell(AP)
        ))
    );
}<|endoftext|>