<commit_before>extern crate futures;
extern crate hyper;
#[macro_use]
extern crate log;
extern crate oauthcli;
extern crate serde_json;
extern crate url;

mod lines;

use futures::{Poll, Stream};
use hyper::client::Client;
use hyper::status::StatusCode;
use lines::Lines;
use std::convert::From;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display, Formatter};
use std::io::{self, BufReader};

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Token<'a>(pub &'a str, pub &'a str);

pub struct TwitterUserStreamBuilder<'a> {
    consumer: Token<'a>,
    token: Token<'a>,
    end_point: Option<&'a str>,
    client: Option<&'a Client>,
    user_agent: Option<String>,
}

pub struct TwitterUserStream {
    lines: Lines,
}

pub enum Error {
    Url(url::ParseError),
    Hyper(hyper::Error),
    Http(StatusCode),
    Io(io::Error),
    TimedOut,
    InternalPanicError,
}

pub type Result<T> = std::result::Result<T, Error>;

impl<'a> TwitterUserStreamBuilder<'a> {
    pub fn new(consumer: Token<'a>, token: Token<'a>) -> Self {
        TwitterUserStreamBuilder {
            consumer: consumer,
            token: token,
            client: None,
            end_point: None,
            user_agent: None,
        }
    }

    pub fn client(&mut self, client: Option<&'a Client>) -> &mut Self {
        self.client = client;
        self
    }

    pub fn end_point(&mut self, url: Option<&'a str>) -> &mut Self {
        self.end_point = url;
        self
    }

    pub fn user_agent(&mut self, user_agent: Option<String>) -> &mut Self {
        self.user_agent = user_agent;
        self
    }

    pub fn login(&self) -> Result<TwitterUserStream> {
        use hyper::header::{Headers, Authorization, UserAgent};
        use hyper::status::StatusCode;
        use oauthcli::{OAuthAuthorizationHeaderBuilder, SignatureMethod};
        use url::Url;

        let end_point = self.end_point.unwrap_or("https://userstream.twitter.com/1.1/user.json?with=user");
        let url = Url::parse(end_point)?;

        let auth = OAuthAuthorizationHeaderBuilder::new(
            "GET", &url, self.consumer.0, self.consumer.1, SignatureMethod::HmacSha1)
            .token(self.token.0, self.token.1)
            .finish_for_twitter();

        let mut headers = Headers::new();
        headers.set(Authorization(auth));
        if let Some(ua) = self.user_agent {
            headers.set(UserAgent(ua));
        }

        let res = if let Some(client) = self.client {
            client
                .get(url)
                .headers(headers)
                .send()?
        } else {
            Client::new()
                .get(url)
                .headers(headers)
                .send()?
        };

        match &res.status {
            &StatusCode::Ok => (),
            _ => return Err(res.status.into()),
        }

        Ok(TwitterUserStream {
            lines: lines::lines(BufReader::new(res))
        })
    }
}

impl TwitterUserStream {
    pub fn login<'a>(consumer: Token<'a>, token: Token<'a>) -> Result<Self> {
        TwitterUserStreamBuilder::new(consumer, token).login()
    }
}

impl Stream for TwitterUserStream {
    type Item = String;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<String>, Error> {
        self.lines.poll()
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        match self {
            &Error::Url(ref e) => e.description(),
            &Error::Hyper(ref e) => e.description(),
            &Error::Http(ref status) => status.canonical_reason().unwrap_or("unknown HTTP error"),
            &Error::Io(ref e) => e.description(),
            &Error::TimedOut => "the connection has timed out",
            &Error::InternalPanicError => "internal error: sender panicked",
        }
    }

    fn cause(&self) -> Option<&std::error::Error> {
        match self {
            &Error::Url(ref e) => e.cause(),
            &Error::Hyper(ref e) => e.cause(),
            &Error::Http(_) => None,
            &Error::Io(ref e) => e.cause(),
            &Error::TimedOut => None,
            &Error::InternalPanicError => None,
        }
    }
}

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

impl Debug for Error {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        Display::fmt(self, f)
    }
}

impl From<url::ParseError> for Error {
    fn from(e: url::ParseError) -> Self {
        Error::Url(e)
    }
}

impl From<hyper::Error> for Error {
    fn from(e: hyper::Error) -> Self {
        Error::Hyper(e)
    }
}

impl From<StatusCode> for Error {
    fn from(e: StatusCode) -> Self {
        Error::Http(e)
    }
}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Self {
        Error::Io(e)
    }
}
<commit_msg>Add a trace!() message<commit_after>extern crate futures;
extern crate hyper;
#[macro_use]
extern crate log;
extern crate oauthcli;
extern crate serde_json;
extern crate url;

mod lines;

use futures::{Poll, Stream};
use hyper::client::Client;
use hyper::status::StatusCode;
use lines::Lines;
use std::convert::From;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display, Formatter};
use std::io::{self, BufReader};

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Token<'a>(pub &'a str, pub &'a str);

pub struct TwitterUserStreamBuilder<'a> {
    consumer: Token<'a>,
    token: Token<'a>,
    end_point: Option<&'a str>,
    client: Option<&'a Client>,
    user_agent: Option<&'a str>,
}

pub struct TwitterUserStream {
    lines: Lines,
}

pub enum Error {
    Url(url::ParseError),
    Hyper(hyper::Error),
    Http(StatusCode),
    Io(io::Error),
    TimedOut,
    InternalPanicError,
}

pub type Result<T> = std::result::Result<T, Error>;

impl<'a> TwitterUserStreamBuilder<'a> {
    pub fn new(consumer: Token<'a>, token: Token<'a>) -> Self {
        TwitterUserStreamBuilder {
            consumer: consumer,
            token: token,
            client: None,
            end_point: None,
            user_agent: None,
        }
    }

    pub fn client(&mut self, client: Option<&'a Client>) -> &mut Self {
        self.client = client;
        self
    }

    pub fn end_point(&mut self, url: Option<&'a str>) -> &mut Self {
        self.end_point = url;
        self
    }

    pub fn user_agent(&mut self, user_agent: Option<&'a str>) -> &mut Self {
        self.user_agent = user_agent;
        self
    }

    pub fn login(&self) -> Result<TwitterUserStream> {
        use hyper::header::{Headers, Authorization, UserAgent};
        use hyper::status::StatusCode;
        use oauthcli::{OAuthAuthorizationHeaderBuilder, SignatureMethod};
        use url::Url;

        let end_point = self.end_point.unwrap_or("https://userstream.twitter.com/1.1/user.json?with=user");
        let url = Url::parse(end_point)?;

        let auth = OAuthAuthorizationHeaderBuilder::new(
            "GET", &url, self.consumer.0, self.consumer.1, SignatureMethod::HmacSha1)
            .token(self.token.0, self.token.1)
            .finish_for_twitter();

        let mut headers = Headers::new();
        headers.set(Authorization(auth));
        if let Some(ua) = self.user_agent {
            headers.set(UserAgent(ua.to_owned()));
        }

        let res = if let Some(client) = self.client {
            client
                .get(url)
                .headers(headers)
                .send()?
        } else {
            Client::new()
                .get(url)
                .headers(headers)
                .send()?
        };

        match &res.status {
            &StatusCode::Ok => (),
            _ => return Err(res.status.into()),
        }

        Ok(TwitterUserStream {
            lines: lines::lines(BufReader::new(res))
        })
    }
}

impl TwitterUserStream {
    pub fn login<'a>(consumer: Token<'a>, token: Token<'a>) -> Result<Self> {
        TwitterUserStreamBuilder::new(consumer, token).login()
    }
}

impl Stream for TwitterUserStream {
    type Item = String;
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<String>, Error> {
        self.lines.poll()
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        match self {
            &Error::Url(ref e) => e.description(),
            &Error::Hyper(ref e) => e.description(),
            &Error::Http(ref status) => status.canonical_reason().unwrap_or("unknown HTTP error"),
            &Error::Io(ref e) => e.description(),
            &Error::TimedOut => "the connection has timed out",
            &Error::InternalPanicError => "internal error: sender panicked",
        }
    }

    fn cause(&self) -> Option<&std::error::Error> {
        match self {
            &Error::Url(ref e) => e.cause(),
            &Error::Hyper(ref e) => e.cause(),
            &Error::Http(_) => None,
            &Error::Io(ref e) => e.cause(),
            &Error::TimedOut => None,
            &Error::InternalPanicError => None,
        }
    }
}

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

impl Debug for Error {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        Display::fmt(self, f)
    }
}

impl From<url::ParseError> for Error {
    fn from(e: url::ParseError) -> Self {
        Error::Url(e)
    }
}

impl From<hyper::Error> for Error {
    fn from(e: hyper::Error) -> Self {
        Error::Hyper(e)
    }
}

impl From<StatusCode> for Error {
    fn from(e: StatusCode) -> Self {
        Error::Http(e)
    }
}

impl From<io::Error> for Error {
    fn from(e: io::Error) -> Self {
        Error::Io(e)
    }
}
<|endoftext|>


<commit_before>#![crate_name = "rusoto"]
#![crate_type = "lib"]
#![cfg_attr(feature = "unstable", feature(proc_macro))]
#![cfg_attr(feature = "nightly-testing", feature(plugin))]
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
#![cfg_attr(feature = "nightly-testing", allow(cyclomatic_complexity, used_underscore_binding, ptr_arg, suspicious_else_formatting))]
#![allow(dead_code)]
#![cfg_attr(not(feature = "unstable"), deny(warnings))]

//! Rusoto is an [AWS](https://aws.amazon.com/) SDK for Rust.
//! A high level overview is available in `README.md` at https://github.com/rusoto/rusoto.
//!
//! # Example
//!
//! The following code shows a simple example of using Rusoto's DynamoDB API to
//! list the names of all tables in a database.
//!
//! ```rust,ignore
//! use std::default::Default;
//!
//! use rusoto::{DefaultCredentialsProvider, Region};
//! use rusoto::dynamodb::{DynamoDbClient, ListTablesInput};
//!
//! let provider = DefaultCredentialsProvider::new().unwrap();
//! let client = DynamoDbClient::new(provider, Region::UsEast1);
//! let list_tables_input: ListTablesInput = Default::default();
//!
//! match client.list_tables(&list_tables_input) {
//!     Ok(output) => {
//!         match output.table_names {
//!             Some(table_name_list) => {
//!                 println!("Tables in database:");
//!
//!                 for table_name in table_name_list {
//!                     println!("{}", table_name);
//!                 }
//!             },
//!             None => println!("No tables in database!"),
//!         }
//!     },
//!     Err(error) => {
//!         println!("Error: {:?}", error);
//!     },
//! }

extern crate chrono;
extern crate hyper;
extern crate hyper_native_tls;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
extern crate md5;
extern crate regex;
extern crate ring;
extern crate rusoto_credential;
extern crate rustc_serialize;
extern crate serde;
extern crate serde_json;
extern crate time;
extern crate url;
extern crate xml;

#[cfg(feature = "serde_derive")]
#[macro_use]
extern crate serde_derive;

pub use region::{ParseRegionError, Region};
pub use rusoto_credential::{
    AwsCredentials,
    ChainProvider,
    ContainerProvider,
    CredentialsError,
    EnvironmentProvider,
    InstanceMetadataProvider,
    ProfileProvider,
    ProvideAwsCredentials,
    DefaultCredentialsProvider,
    DefaultCredentialsProviderSync,
};
pub use request::{DispatchSignedRequest, HttpResponse, HttpDispatchError};
pub use signature::SignedRequest;
pub use request::default_tls_client;

mod param;
mod region;
mod request;
mod xmlerror;
mod xmlutil;
mod serialization;
#[macro_use] mod signature;

#[cfg(test)]
mod mock;

#[cfg(feature = "acm")]
pub mod acm;
#[allow(unused_imports)]
#[cfg(feature = "cloudformation")]
pub mod cloudformation;
#[cfg(feature = "cloudfront")]
pub mod cloudfront;
#[cfg(feature = "cloudhsm")]
pub mod cloudhsm;
#[cfg(feature = "cloudtrail")]
pub mod cloudtrail;
#[cfg(feature = "cloudwatch")]
pub mod cloudwatch;
#[cfg(feature = "codecommit")]
pub mod codecommit;
#[cfg(feature = "codedeploy")]
pub mod codedeploy;
#[cfg(feature = "codepipeline")]
pub mod codepipeline;
#[cfg(feature = "cognito-identity")]
pub mod cognitoidentity;
#[cfg(feature = "config")]
pub mod config;
#[cfg(feature = "datapipeline")]
pub mod datapipeline;
#[cfg(feature = "devicefarm")]
pub mod devicefarm;
#[cfg(feature = "directconnect")]
pub mod directconnect;
#[cfg(feature = "ds")]
pub mod ds;
#[cfg(feature = "dynamodb")]
pub mod dynamodb;
#[cfg(feature = "dynamodbstreams")]
pub mod dynamodbstreams;
#[cfg(feature = "ec2")]
pub mod ec2;
#[cfg(feature = "ecr")]
pub mod ecr;
#[cfg(feature = "ecs")]
pub mod ecs;
#[cfg(feature = "emr")]
pub mod emr;
#[cfg(feature = "elastictranscoder")]
pub mod elastictranscoder;
#[cfg(feature = "events")]
pub mod events;
#[cfg(feature = "firehose")]
pub mod firehose;
#[cfg(feature = "iam")]
pub mod iam;
#[cfg(feature = "inspector")]
pub mod inspector;
#[cfg(feature = "iot")]
pub mod iot;
#[cfg(feature = "kinesis")]
pub mod kinesis;
#[cfg(feature = "kms")]
pub mod kms;
#[cfg(feature = "logs")]
pub mod logs;
#[cfg(feature = "machinelearning")]
pub mod machinelearning;
#[cfg(feature = "marketplacecommerceanalytics")]
pub mod marketplacecommerceanalytics;
#[cfg(feature = "opsworks")]
pub mod opsworks;
#[cfg(feature = "route53")]
pub mod route53;
#[cfg(feature = "route53domains")]
pub mod route53domains;
#[cfg(feature = "s3")]
pub mod s3;
#[cfg(feature = "sqs")]
pub mod sqs;
#[cfg(feature = "ssm")]
pub mod ssm;
#[cfg(feature = "storagegateway")]
pub mod storagegateway;
#[cfg(feature = "swf")]
pub mod swf;
#[cfg(feature = "waf")]
pub mod waf;
#[cfg(feature = "workspaces")]
pub mod workspaces;

/*
#[cfg(feature = "gamelift")]
pub mod gamelift;
#[cfg(feature = "support")]
pub mod support;
*/
<commit_msg>make `TlsError` public<commit_after>#![crate_name = "rusoto"]
#![crate_type = "lib"]
#![cfg_attr(feature = "unstable", feature(proc_macro))]
#![cfg_attr(feature = "nightly-testing", feature(plugin))]
#![cfg_attr(feature = "nightly-testing", plugin(clippy))]
#![cfg_attr(feature = "nightly-testing", allow(cyclomatic_complexity, used_underscore_binding, ptr_arg, suspicious_else_formatting))]
#![allow(dead_code)]
#![cfg_attr(not(feature = "unstable"), deny(warnings))]

//! Rusoto is an [AWS](https://aws.amazon.com/) SDK for Rust.
//! A high level overview is available in `README.md` at https://github.com/rusoto/rusoto.
//!
//! # Example
//!
//! The following code shows a simple example of using Rusoto's DynamoDB API to
//! list the names of all tables in a database.
//!
//! ```rust,ignore
//! use std::default::Default;
//!
//! use rusoto::{DefaultCredentialsProvider, Region};
//! use rusoto::dynamodb::{DynamoDbClient, ListTablesInput};
//!
//! let provider = DefaultCredentialsProvider::new().unwrap();
//! let client = DynamoDbClient::new(provider, Region::UsEast1);
//! let list_tables_input: ListTablesInput = Default::default();
//!
//! match client.list_tables(&list_tables_input) {
//!     Ok(output) => {
//!         match output.table_names {
//!             Some(table_name_list) => {
//!                 println!("Tables in database:");
//!
//!                 for table_name in table_name_list {
//!                     println!("{}", table_name);
//!                 }
//!             },
//!             None => println!("No tables in database!"),
//!         }
//!     },
//!     Err(error) => {
//!         println!("Error: {:?}", error);
//!     },
//! }

extern crate chrono;
extern crate hyper;
extern crate hyper_native_tls;
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
extern crate md5;
extern crate regex;
extern crate ring;
extern crate rusoto_credential;
extern crate rustc_serialize;
extern crate serde;
extern crate serde_json;
extern crate time;
extern crate url;
extern crate xml;

#[cfg(feature = "serde_derive")]
#[macro_use]
extern crate serde_derive;

pub use region::{ParseRegionError, Region};
pub use rusoto_credential::{
    AwsCredentials,
    ChainProvider,
    ContainerProvider,
    CredentialsError,
    EnvironmentProvider,
    InstanceMetadataProvider,
    ProfileProvider,
    ProvideAwsCredentials,
    DefaultCredentialsProvider,
    DefaultCredentialsProviderSync,
};
pub use request::{DispatchSignedRequest, HttpResponse, HttpDispatchError, TlsError};
pub use signature::SignedRequest;
pub use request::default_tls_client;

mod param;
mod region;
mod request;
mod xmlerror;
mod xmlutil;
mod serialization;
#[macro_use] mod signature;

#[cfg(test)]
mod mock;

#[cfg(feature = "acm")]
pub mod acm;
#[allow(unused_imports)]
#[cfg(feature = "cloudformation")]
pub mod cloudformation;
#[cfg(feature = "cloudfront")]
pub mod cloudfront;
#[cfg(feature = "cloudhsm")]
pub mod cloudhsm;
#[cfg(feature = "cloudtrail")]
pub mod cloudtrail;
#[cfg(feature = "cloudwatch")]
pub mod cloudwatch;
#[cfg(feature = "codecommit")]
pub mod codecommit;
#[cfg(feature = "codedeploy")]
pub mod codedeploy;
#[cfg(feature = "codepipeline")]
pub mod codepipeline;
#[cfg(feature = "cognito-identity")]
pub mod cognitoidentity;
#[cfg(feature = "config")]
pub mod config;
#[cfg(feature = "datapipeline")]
pub mod datapipeline;
#[cfg(feature = "devicefarm")]
pub mod devicefarm;
#[cfg(feature = "directconnect")]
pub mod directconnect;
#[cfg(feature = "ds")]
pub mod ds;
#[cfg(feature = "dynamodb")]
pub mod dynamodb;
#[cfg(feature = "dynamodbstreams")]
pub mod dynamodbstreams;
#[cfg(feature = "ec2")]
pub mod ec2;
#[cfg(feature = "ecr")]
pub mod ecr;
#[cfg(feature = "ecs")]
pub mod ecs;
#[cfg(feature = "emr")]
pub mod emr;
#[cfg(feature = "elastictranscoder")]
pub mod elastictranscoder;
#[cfg(feature = "events")]
pub mod events;
#[cfg(feature = "firehose")]
pub mod firehose;
#[cfg(feature = "iam")]
pub mod iam;
#[cfg(feature = "inspector")]
pub mod inspector;
#[cfg(feature = "iot")]
pub mod iot;
#[cfg(feature = "kinesis")]
pub mod kinesis;
#[cfg(feature = "kms")]
pub mod kms;
#[cfg(feature = "logs")]
pub mod logs;
#[cfg(feature = "machinelearning")]
pub mod machinelearning;
#[cfg(feature = "marketplacecommerceanalytics")]
pub mod marketplacecommerceanalytics;
#[cfg(feature = "opsworks")]
pub mod opsworks;
#[cfg(feature = "route53")]
pub mod route53;
#[cfg(feature = "route53domains")]
pub mod route53domains;
#[cfg(feature = "s3")]
pub mod s3;
#[cfg(feature = "sqs")]
pub mod sqs;
#[cfg(feature = "ssm")]
pub mod ssm;
#[cfg(feature = "storagegateway")]
pub mod storagegateway;
#[cfg(feature = "swf")]
pub mod swf;
#[cfg(feature = "waf")]
pub mod waf;
#[cfg(feature = "workspaces")]
pub mod workspaces;

/*
#[cfg(feature = "gamelift")]
pub mod gamelift;
#[cfg(feature = "support")]
pub mod support;
*/
<|endoftext|>


<commit_before>// #get
// #set
// #peek
// #new
// #clear
//has
use std::collections::HashMap;

// Doubly linked list
struct Node <V> {
    prev: Option<Box<Node<V>>>,
    next: Option<Box<Node<V>>>,
    val: V,
}

pub struct LRU <K, V> {
    cache: HashMap<K, V>,
    head: Option<Node<V>>,
    tail: Option<Node<V>>,
    len: u16,
}

impl <K: Eq + std::hash::Hash, V> LRU <K, V> {
    pub fn new() -> LRU<K, V> {
        LRU {
            cache: HashMap::new(),
            head: None,
            tail: None,
            len: 0
        }
    }
    pub fn set(&mut self, key: K, val: V) -> &mut LRU<K, V>{
        use std::collections::hash_map::Entry;

        match self.cache.entry(&key) {
            Entry::Occupied(_, val) => {},
            Entry::Vacant(_) => {}
        }
    }
}

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

    #[test]
    fn lru_instantiaion() {
        let lru: LRU<&str, u8> = LRU::new();
    }

    // #[test]
}
<commit_msg>attempting to outsmart hashmap/match statement borrowing rules<commit_after>// #get
// #set
// #peek
// #new
// #clear
//has
use std::collections::HashMap;
use std::rc::Rc;

// Doubly linked list
struct Node <V> {
    prev: Option<Box<Node<V>>>,
    next: Option<Box<Node<V>>>,
    val: V,
}

pub struct LRU <K, V> {
    cache: HashMap<K, Node<V>>,
    head: Option<Node<V>>,
    tail: Option<Node<V>>,
    len: u16,
}

impl <K: Eq + std::hash::Hash + Copy, V> LRU <K, V> {
    pub fn new() -> Self {
        LRU {
            cache: HashMap::new(),
            head: None,
            tail: None,
            len: 0
        }
    }
    pub fn set(&mut self, key: K, val: V) -> &mut LRU<K, V>{
        use std::collections::hash_map::Entry;

        match self.cache.entry(key) {
            Entry::Occupied(node) => {},
            Entry::Vacant(_) => {
                let node = Node {
                    prev: self.head.take().map(|x| Box::new(x)),
                    next: None,
                    val: val
                };
                self.cache.insert(key, node);
                self.head = Some(node);
            }
        };

        self
    }
}

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

    #[test]
    fn lru_instantiaion() {
        let lru: LRU<&str, u8> = LRU::new();
    }

    // #[test]
}
<|endoftext|>


<commit_before>//! Promises in Rust.

#![warn(incomplete_docs)]

use std::thread;
use std::sync::mpsc::channel;
use std::time::Duration;
use std::thread::JoinHandle;
use std::sync::mpsc::{Sender, Receiver};

/// A promise is a way of doing work in the background
pub struct Promise<T, E> {
    //sender: Sender<PromiseMessage<T, E>>, // Send messages to the promise
    receiver: Receiver<Result<T, E>> // Get the result of the promise for chaining (pass into then)
}

enum PromiseJoinType {
    Race,
    All
}

impl<T, E> Promise<T, E> {

    /// Chains a function to be called after this promise resolves.
    pub fn then<T2, E2>(self, callback: fn(f: T) -> Result<T2, E2>,
                              errback:  fn(e: E) -> Result<T2, E2>)
                        -> Promise<T2, E2> {
        let recv = self.receiver;
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            if let Some(message) = recv.recv() { // Blocking receive until message
                match message {
                    Ok(val) => {
                        let _ = tx.send(callback(val)).unwrap_or(());
                    }
                    Err(err) => {
                        let _ = tx.send(errback(err)).unwrap_or(());
                    }
                }
            }
            else { // Receive failed, origin was dropped
            }
        });
        return Promise { receiver: rx };
    }

    /// Chains a function to be called after this promise resolves.
    pub fn then_result<T2, E2>(self,
                               callback: fn(input: Result<T, E>) -> Result<T2, E2>),
                               -> Promise<T2, E2> {
        let recv = self.receiver;
        let recv2 = self.receiver;
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            if let Some(result) = recv.recv() { // Blocking receive until message
                let _ = tx.send(callback(result)).unwrap_or(());
            }
            else { // Receive failed, origin was dropped
            }
        });
        return Promise { receiver: rx };
    }

    pub fn new(func: fn() -> Result<T, E>) -> Promise<T, E> {
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            let result = func();
            let _ = tx.send(func).unwrap_or(());
        });

        return Promise { receiver: rx };
    }
}

pub fn race<T, E>(promises: Vec<Promise<T, E>>) -> Promise<T, E> {
}

pub fn all<T, E>(promises: Vec<Promise<T, E>>) -> Promise<T, E> {
}

pub fn resolve<T, E>(val: E) -> Promise<T, E> {
}

pub fn reject<T, E>(val: E) -> Promise<T, E> {
}

// Dispatcher methods

fn spawn_vat<T, E>(func: fn(reciever: Receiver<PromiseMessage>) -> Result<T, E>) -> (Receiver<Result<T, E>>, JoinHandle<()>) {
    let (tx, rx) = channel();

}

fn vat_join() {

}

#[test]
fn test_channels() {
    println!("Begin test...");
    let mut guard: Option<JoinHandle<_>> = None;
    let mut rec: Option<Receiver<_>> = None;

    {
        println!("\tBegin inner scope...");
        let (tx, rx) = channel();
        guard = Some(thread::spawn(move || {
            println!("\t\tThread created!");
            tx.send("Hello!").unwrap();
            println!("\t\tThread finished!");
        }));
        rec = Some(rx);
        println!("\t(tx, rx) out of scope");
    }

    println!("Sleeping...");
    thread::sleep(Duration::from_secs(2));
    println!("Receiving result...");
    let result = rec.unwrap().recv();
    assert_eq!(result, Ok("Hello!"));
}
<commit_msg>Add requirements for Send trait<commit_after>//! Promises in Rust.

#![warn(incomplete_docs)]

use std::thread;
use std::sync::mpsc::channel;
use std::time::Duration;
use std::thread::JoinHandle;
use std::marker::{Send};
use std::sync::mpsc::{Sender, Receiver, TryRecvError};

/// A promise is a way of doing work in the background
pub struct Promise<T, E> where T: Send, E: Send {
    //sender: Sender<PromiseMessage<T, E>>, // Send messages to the promise
    receiver: Receiver<Result<T, E>> // Get the result of the promise for chaining (pass into then)
}

enum PromiseJoinType {
    Race,
    All
}

impl<T, E> Promise<T, E> where T: Send, E: Send {

    /// Chains a function to be called after this promise resolves.
    pub fn then<T2, E2>(self, callback: fn(f: T) -> Result<T2, E2>,
                              errback:  fn(e: E) -> Result<T2, E2>)
                        -> Promise<T2, E2>
    where T2: Send, E2: Send {
        let recv = self.receiver;
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            if let Ok(message) = recv.recv() { // Blocking receive until message
                match message {
                    Ok(val) => {
                        let _ = tx.send(callback(val)).unwrap_or(());
                    }
                    Err(err) => {
                        let _ = tx.send(errback(err)).unwrap_or(());
                    }
                }
            }
            else { // Receive failed, origin was dropped
            }
        });
        return Promise { receiver: rx };
    }

    /// Chains a function to be called after this promise resolves.
    pub fn then_result<T2, E2>(self,
                               callback: fn(input: Result<T, E>) -> Result<T2, E2>)
                               -> Promise<T2, E2>
    where T2: Sync, E2: Sync {
        let recv = self.receiver;
        let recv2 = self.receiver;
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            if let Ok(result) = recv.recv() { // Blocking receive until message
                let _ = tx.send(callback(result)).unwrap_or(());
            }
            else { // Receive failed, origin was dropped
            }
        });
        return Promise { receiver: rx };
    }

    /// Creates a new promsie
    pub fn new(func: fn() -> Result<T, E>) -> Promise<T, E> {
        let (tx, rx) = channel();

        let thread = thread::spawn(move || {
            let result = func();
            let _ = tx.send(result).unwrap_or(());
        });

        return Promise { receiver: rx };
    }
}

pub fn race<T, E>(promises: Vec<Promise<T, E>>) -> Promise<T, E>
where T: Send, E: Send {
    let mut receivers = promises.into_iter().map(|x| x.receiver).collect();
    let (tx, rx) = channel();

    thread::spawn(move || {
        'outer: loop {
            for i in 0..receivers.len() {
                match receivers[i].try_recv() {
                    Ok(val) => {
                        let _ = tx.send(val).unwrap_or(());
                        return;
                    }
                    Err(err) => {
                        if err == TryRecvError::Disconnected {
                            receivers.remove(i);
                        }
                    }
                }
            }
        }
    });
}

pub fn all<T, E>(promises: Vec<Promise<T, E>>) -> Promise<T, E> {
}

pub fn resolve<T, E>(val: E) -> Promise<T, E> {
}

pub fn reject<T, E>(val: E) -> Promise<T, E> {
}

#[test]
fn test_channels() {
    println!("Begin test...");
    let mut guard: Option<JoinHandle<_>> = None;
    let mut rec: Option<Receiver<_>> = None;

    {
        println!("\tBegin inner scope...");
        let (tx, rx) = channel();
        guard = Some(thread::spawn(move || {
            println!("\t\tThread created!");
            tx.send("Hello!").unwrap();
            println!("\t\tThread finished!");
        }));
        rec = Some(rx);
        println!("\t(tx, rx) out of scope");
    }

    println!("Sleeping...");
    thread::sleep(Duration::from_secs(2));
    println!("Receiving result...");
    let result = rec.unwrap().recv();
    assert_eq!(result, Ok("Hello!"));
}
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use clap::{Arg, App, SubCommand};

pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
    app
}
<commit_msg>Add CLI spec<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

use clap::{Arg, App, SubCommand};

pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
    app
        .subcommand(SubCommand::with_name("status")
                   .about("Show the current status. Remind of not-yet-done habits, shows upcoming. Default if no command is passed.")
                   .version("0.1")
                   )

        .subcommand(SubCommand::with_name("create")
                   .about("Create a new Habit")
                   .version("0.1")
                   .arg(Arg::with_name("create-name")
                        .index(1)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("NAME")
                        .help("Name of the new habit"))
                   .arg(Arg::with_name("create-date")
                        .index(2)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("DATE")
                        .help("Date when the first instance should be done"))
                   .arg(Arg::with_name("create-date-recurr-spec")
                        .index(3)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("RECURRENCE-SPEC")
                        .help("Spec how the habit should recur (eg: 'weekly', 'monthly', '5days', '12hours')"))
                   .arg(Arg::with_name("create-comment")
                        .index(4)
                        .multiple(true)
                        .required(true)
                        .takes_value(true)
                        .value_name("COMMENT")
                        .help("Comment for the habit"))
                   )

        .subcommand(SubCommand::with_name("delete")
                   .about("Delete a Habit (and its instances)")
                   .version("0.1")
                   .arg(Arg::with_name("delete-instances")
                        .long("instances")
                        .short("I")
                        .multiple(false)
                        .required(false)
                        .takes_value(false)
                        .help("Delete instances as well"))
                   .arg(Arg::with_name("delete-yes")
                        .long("yes")
                        .multiple(false)
                        .required(false)
                        .takes_value(false)
                        .help("Do not ask for confirmation"))
                   .arg(Arg::with_name("delete-name")
                        .index(1)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("NAME")
                        .help("Name of the habit"))
                   )

        .subcommand(SubCommand::with_name("list")
                   .about("List Habits")
                   .version("0.1")
                   .arg(Arg::with_name("list-long")
                        .long("long")
                        .short("l")
                        .multiple(false)
                        .required(false)
                        .takes_value(false)
                        .help("List with details (how many instances)"))
                   )

        .subcommand(SubCommand::with_name("show")
                   .about("Show a Habit and its instances")
                   .version("0.1")
                   .arg(Arg::with_name("show-name")
                        .index(1)
                        .multiple(false)
                        .required(true)
                        .takes_value(true)
                        .value_name("NAME")
                        .help("Name of the habit to show"))
                   )
}
<|endoftext|>


<commit_before>//! This crate aims to be a functional
//! port of the Math.NET Numerics Distribution package and in doing so providing the Rust numerical
//! computing community with a robust, well-tested statistical distribution package. This crate
//! also ports over some of the special statistical functions from Math.NET in so far as they are
//! used in the computation of distribution values. This crate depends on the `rand` crate to provide
//! RNG.
//!
//! # Example
//! The following example samples from a standard normal distribution
//!
//! ```
//! # extern crate rand;
//! # extern crate statrs;

//! use rand::StdRng;
//! use statrs::distribution::{Distribution, Normal};
//!
//! # fn main() {
//! let mut r = rand::StdRng::new().unwrap();
//! let n = Normal::new(0.0, 1.0).unwrap();
//! for _ in 0..10 {
//!     print!("{}", n.sample::<StdRng>(&mut r));
//! }
//! # }
//! ```

#![crate_type = "lib"]
#![crate_name = "statrs"]

extern crate rand;

#[macro_export]
macro_rules! assert_almost_eq {
    ($a:expr, $b:expr, $prec:expr) => (assert!($crate::prec::almost_eq($a, $b, $prec)));
}

pub mod distribution;
pub mod function;
pub mod consts;
pub mod prec;

mod result;
mod statistics;
mod error;

pub use result::Result;
pub use statistics::Statistics;
pub use error::StatsError;
<commit_msg>fix assert_almost_eq macro for more informative display<commit_after>//! This crate aims to be a functional
//! port of the Math.NET Numerics Distribution package and in doing so providing the Rust numerical
//! computing community with a robust, well-tested statistical distribution package. This crate
//! also ports over some of the special statistical functions from Math.NET in so far as they are
//! used in the computation of distribution values. This crate depends on the `rand` crate to provide
//! RNG.
//!
//! # Example
//! The following example samples from a standard normal distribution
//!
//! ```
//! # extern crate rand;
//! # extern crate statrs;

//! use rand::StdRng;
//! use statrs::distribution::{Distribution, Normal};
//!
//! # fn main() {
//! let mut r = rand::StdRng::new().unwrap();
//! let n = Normal::new(0.0, 1.0).unwrap();
//! for _ in 0..10 {
//!     print!("{}", n.sample::<StdRng>(&mut r));
//! }
//! # }
//! ```

#![crate_type = "lib"]
#![crate_name = "statrs"]

extern crate rand;

#[macro_export]
macro_rules! assert_almost_eq {
    ($a:expr, $b:expr, $prec:expr) => (
        if !$crate::prec::almost_eq($a, $b, $prec) {
            panic!(format!("assertion failed: `abs(left - right) < {:e}`, (left: `{}`, right: `{}`)", $prec, $a, $b));
        }
    );
}

pub mod distribution;
pub mod function;
pub mod consts;
pub mod prec;

mod result;
mod statistics;
mod error;

pub use result::Result;
pub use statistics::Statistics;
pub use error::StatsError;
<|endoftext|>


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

extern crate chrono;
extern crate rusqlite;

pub mod catalog;
pub mod collections;
pub mod content;
pub mod folders;
pub mod fromdb;
pub mod images;
pub mod keywords;
pub mod keywordtree;
pub mod libraryfiles;
pub mod lrobject;

pub use catalog::{Catalog,CatalogVersion};
pub use collections::Collection;
pub use content::Content;
pub use folders::{Folder,Folders,RootFolder};
pub use images::Image;
pub use keywords::Keyword;
pub use keywordtree::KeywordTree;
pub use libraryfiles::LibraryFile;
pub use lrobject::{LrObject,LrId};

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>remove unused test stub<commit_after>/*
  This Source Code Form is subject to the terms of the Mozilla Public
  License, v. 2.0. If a copy of the MPL was not distributed with this
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

extern crate chrono;
extern crate rusqlite;

pub mod catalog;
pub mod collections;
pub mod content;
pub mod folders;
pub mod fromdb;
pub mod images;
pub mod keywords;
pub mod keywordtree;
pub mod libraryfiles;
pub mod lrobject;

pub use catalog::{Catalog,CatalogVersion};
pub use collections::Collection;
pub use content::Content;
pub use folders::{Folder,Folders,RootFolder};
pub use images::Image;
pub use keywords::Keyword;
pub use keywordtree::KeywordTree;
pub use libraryfiles::LibraryFile;
pub use lrobject::{LrObject,LrId};
<|endoftext|>


<commit_before>extern crate bincode;
extern crate rustc_serialize;

use std::collections::HashMap;
use std::collections::hash_map::Keys;
use std::option::Option;
use std::io::*;
use std::marker::PhantomData;
use std::hash::Hash;
use std::cell::RefCell;
use rustc_serialize::{Encodable, Decodable};
use bincode::SizeLimit;
use bincode::rustc_serialize::{encode_into, encoded_size, decode};

#[derive(RustcEncodable, RustcDecodable)]
struct Entry<K, V> {
  key: K,
  value: V
}

pub struct Location {
  start: u64,
  size: usize
}

pub struct Store<K, V, F> {
  file: RefCell<F>,
  keys: HashMap<K, Location>,
  data: PhantomData<V>,
  buffer: RefCell<Option<Vec<u8>>>,
  offset: u64
}

impl<K, V, F> Store<K, V, F>
where K: Eq + Hash + Encodable + Decodable,
      V: Encodable + Decodable,
      F: Read + Write + Seek
{
  pub fn new(target: F) -> Store<K, V, F> {
    Store {
      file: RefCell::new(target),
      keys: HashMap::new(),
      data: PhantomData,
      buffer: RefCell::new(Some(Vec::new())),
      offset: 0
    }
  }

  pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>> {
    let previous = try!(self.get(&key));
    let entry = Entry {
      key: key,
      value: value
    };
    let mut file = self.file.borrow_mut();
    let buf = self.buffer.borrow_mut().take().unwrap();
    let mut encoded = Cursor::new(buf);
    encode_into(&entry, &mut encoded, SizeLimit::Infinite).unwrap();
    let buf = encoded.into_inner();
    let start = self.offset;
    let size = encoded_size(&entry) as usize;
    self.offset = self.offset + size as u64;
    // TODO put buffer back on fail
    try!(file.write_all(&buf[..size]));
    self.keys.insert(entry.key, Location { start: start, size: size });
    *self.buffer.borrow_mut() = Some(buf);
    match previous {
      Some(prev) => Ok(Some(prev)),
      None => Ok(None)
    }
  }

  pub fn get(&self, key: &K) -> Result<Option<V>> {
    let location = self.keys.get(key);
    match location {
      Some(loc) => {
        let mut buffer = self.buffer.borrow_mut();
        let buf = &mut buffer.as_mut().unwrap()[..loc.size];
        let mut file = self.file.borrow_mut();
        try!(file.seek(SeekFrom::Start(loc.start)));
        try!(file.read(buf));
        try!(file.seek(SeekFrom::End(0)));
        let entry: Entry<K, V> = decode(buf).unwrap();
        Ok(Some(entry.value))
      }
      None => Ok(None)
    }
  }

  pub fn remove(&mut self, key: &K) -> Result<Option<V>> {
    let previous = try!(self.get(key));
    match previous {
      Some(prev) => {
        self.keys.remove(key);
        Ok(Some(prev))
      }
      None => Ok(None)
    }
  }

  pub fn keys<'a>(&'a self) -> Keys<'a, K, Location> {
    self.keys.keys()
  }
}

#[test]
fn insert_get() {
  #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug, Clone)]
  struct Test {
    num: u64,
    string: String
  }
  let test = Test {
    num: 42,
    string: String::from("testing")
  };
  let buffer: Cursor<Vec<u8>> = Cursor::new(Vec::new());
  let mut store: Store<Vec<String>, Test, Cursor<Vec<u8>>> = Store::new(buffer);
  store.insert(vec![String::from("foo"), String::from("bar")], test.clone()).unwrap();
  let val = store.get(&vec![String::from("foo"), String::from("bar")]).unwrap().unwrap();
  assert_eq!(test, val);
}

#[test]
fn insert_remove() {
  let buffer: Cursor<Vec<u8>> = Cursor::new(Vec::new());
  let mut store: Store<String, u64, Cursor<Vec<u8>>> = Store::new(buffer);
  store.insert(String::from("foo"), 100).unwrap();
  assert_eq!(store.get(&String::from("foo")).unwrap().unwrap(), 100);
  store.remove(&String::from("foo")).unwrap();
  match store.get(&String::from("foo")).unwrap() {
    None => assert!(true),
    Some(_) => assert!(false)
  }
}

#[test]
fn keys() {
  let buffer: Cursor<Vec<u8>> = Cursor::new(Vec::new());
  let mut store: Store<String, u64, Cursor<Vec<u8>>> = Store::new(buffer);
  store.insert(String::from("foo"), 50).unwrap();
  for key in store.keys() {
    assert_eq!(*key, String::from("foo"));
  }
}<commit_msg>add test to check if seeking is working<commit_after>extern crate bincode;
extern crate rustc_serialize;

use std::collections::HashMap;
use std::collections::hash_map::Keys;
use std::option::Option;
use std::io::*;
use std::marker::PhantomData;
use std::hash::Hash;
use std::cell::RefCell;
use rustc_serialize::{Encodable, Decodable};
use bincode::SizeLimit;
use bincode::rustc_serialize::{encode_into, encoded_size, decode};

#[derive(RustcEncodable, RustcDecodable)]
struct Entry<K, V> {
  key: K,
  value: V
}

pub struct Location {
  start: u64,
  size: usize
}

pub struct Store<K, V, F> {
  file: RefCell<F>,
  keys: HashMap<K, Location>,
  data: PhantomData<V>,
  buffer: RefCell<Option<Vec<u8>>>,
  offset: u64
}

impl<K, V, F> Store<K, V, F>
where K: Eq + Hash + Encodable + Decodable,
      V: Encodable + Decodable,
      F: Read + Write + Seek
{
  pub fn new(target: F) -> Store<K, V, F> {
    Store {
      file: RefCell::new(target),
      keys: HashMap::new(),
      data: PhantomData,
      buffer: RefCell::new(Some(Vec::new())),
      offset: 0
    }
  }

  pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>> {
    let previous = try!(self.get(&key));
    let entry = Entry {
      key: key,
      value: value
    };
    let mut file = self.file.borrow_mut();
    let buf = self.buffer.borrow_mut().take().unwrap();
    let mut encoded = Cursor::new(buf);
    encode_into(&entry, &mut encoded, SizeLimit::Infinite).unwrap();
    let buf = encoded.into_inner();
    let start = self.offset;
    let size = encoded_size(&entry) as usize;
    self.offset = self.offset + size as u64;
    // TODO put buffer back on fail
    try!(file.write_all(&buf[..size]));
    self.keys.insert(entry.key, Location { start: start, size: size });
    *self.buffer.borrow_mut() = Some(buf);
    match previous {
      Some(prev) => Ok(Some(prev)),
      None => Ok(None)
    }
  }

  pub fn get(&self, key: &K) -> Result<Option<V>> {
    let location = self.keys.get(key);
    match location {
      Some(loc) => {
        let mut buffer = self.buffer.borrow_mut();
        let buf = &mut buffer.as_mut().unwrap()[..loc.size];
        let mut file = self.file.borrow_mut();
        try!(file.seek(SeekFrom::Start(loc.start)));
        try!(file.read(buf));
        try!(file.seek(SeekFrom::End(0)));
        let entry: Entry<K, V> = decode(buf).unwrap();
        Ok(Some(entry.value))
      }
      None => Ok(None)
    }
  }

  pub fn remove(&mut self, key: &K) -> Result<Option<V>> {
    let previous = try!(self.get(key));
    match previous {
      Some(prev) => {
        self.keys.remove(key);
        Ok(Some(prev))
      }
      None => Ok(None)
    }
  }

  pub fn keys<'a>(&'a self) -> Keys<'a, K, Location> {
    self.keys.keys()
  }
}

#[test]
fn insert_get() {
  #[derive(RustcEncodable, RustcDecodable, PartialEq, Debug, Clone)]
  struct Test {
    num: u64,
    string: String
  }
  let test = Test {
    num: 42,
    string: String::from("testing")
  };
  let buffer: Cursor<Vec<u8>> = Cursor::new(Vec::new());
  let mut store: Store<Vec<String>, Test, Cursor<Vec<u8>>> = Store::new(buffer);
  store.insert(vec![String::from("foo"), String::from("bar")], test.clone()).unwrap();
  let val = store.get(&vec![String::from("foo"), String::from("bar")]).unwrap().unwrap();
  assert_eq!(test, val);
}

#[test]
fn insert_remove() {
  let buffer: Cursor<Vec<u8>> = Cursor::new(Vec::new());
  let mut store: Store<String, u64, Cursor<Vec<u8>>> = Store::new(buffer);
  store.insert(String::from("foo"), 100).unwrap();
  assert_eq!(store.get(&String::from("foo")).unwrap().unwrap(), 100);
  store.remove(&String::from("foo")).unwrap();
  match store.get(&String::from("foo")).unwrap() {
    None => assert!(true),
    Some(_) => assert!(false)
  }
}

#[test]
fn multiple_insert() {
  let buffer: Cursor<Vec<u8>> = Cursor::new(Vec::new());
  let mut store: Store<String, u64, Cursor<Vec<u8>>> = Store::new(buffer);
  store.insert(String::from("foo"), 100).unwrap();
  store.insert(String::from("bar"), 200).unwrap();
  assert_eq!(store.get(&String::from("bar")).unwrap().unwrap(), 200);
}

#[test]
fn keys() {
  let buffer: Cursor<Vec<u8>> = Cursor::new(Vec::new());
  let mut store: Store<String, u64, Cursor<Vec<u8>>> = Store::new(buffer);
  store.insert(String::from("foo"), 50).unwrap();
  for key in store.keys() {
    assert_eq!(*key, String::from("foo"));
  }
}<|endoftext|>


<commit_before>//! Simple resampling library in pure Rust.
//!
//! # Examples
//!
//! ```ignore
//! extern crate resize;
//! use resize::Pixel::Gray8;
//! use resize::Type::Triangle;
//! let mut src = vec![0;w1*h1];
//! let mut dst = vec![0;w2*h2];
//! let mut resizer = resize::new(w1, h1, w2, h2, Gray8, Triangle);
//! resizer.resize(&src, &mut dst);
//! ```
// Current implementation is based on:
// * https://github.com/sekrit-twc/zimg/tree/master/src/zimg/resize
// * https://github.com/PistonDevelopers/image/blob/master/src/imageops/sample.rs
#![deny(missing_docs)]

use std::f32;

/// Resizing type to use.
pub enum Type {
    /// Point resizing.
    Point,
    /// Box (nearest) resizing.
    Nearest,
    /// Triangle (bilinear) resizing.
    Triangle,
    /// Catmull-Rom (bicubic) resizing.
    Catrom,
    /// Resize using Mitchell-Netravali filter.
    Mitchell,
    /// Resize using sinc-windowed filter with radius of 2.
    Lanczos2,
    /// Sinc-windowed filter with radius of 3.
    Lanczos3,
    /// Resize using custom filter.
    Custom(Filter),
}

/// Resampling filter.
pub struct Filter {
    kernel: Box<Fn(f32) -> f32>,
    support: f32,
}

impl Filter {
    /// Create a new filter.
    ///
    /// # Examples
    ///
    /// ```
    /// use resize::Filter;
    /// fn kernel(x: f32) -> f32 { f32::round(x) }
    /// let filter = Filter::new(Box::new(kernel), 0.5);
    /// ```
    pub fn new(kernel: Box<Fn(f32) -> f32>, support: f32) -> Filter {
        Filter {kernel: kernel, support: support}
    }
}

#[inline]
fn point_kernel(_: f32) -> f32 {
    1.0
}

#[inline]
fn box_kernel(x: f32) -> f32 {
    if x.abs() <= 0.5 { 1.0 } else { 0.0 }
}

#[inline]
fn triangle_kernel(x: f32) -> f32 {
    f32::max(1.0 - x.abs(), 0.0)
}

// Taken from
// https://github.com/PistonDevelopers/image/blob/2921cd7/src/imageops/sample.rs#L68
// Could be optimized for known B and C, see e.g.:
// https://github.com/sekrit-twc/zimg/blob/1a606c0/src/zimg/resize/filter.cpp#L149
#[inline]
fn cubic_bc(b: f32, c: f32, x: f32) -> f32 {
    let a = x.abs();
    let k = if a < 1.0 {
        (12.0 - 9.0 * b - 6.0 * c) * a.powi(3) +
        (-18.0 + 12.0 * b + 6.0 * c) * a.powi(2) +
        (6.0 - 2.0 * b)
    } else if a < 2.0 {
        (-b - 6.0 * c) * a.powi(3) +
        (6.0 * b + 30.0 * c) * a.powi(2) +
        (-12.0 * b - 48.0 * c) * a +
        (8.0 * b + 24.0 * c)
    } else {
        0.0
    };
    k / 6.0
}

#[inline]
fn sinc(x: f32) -> f32 {
    if x == 0.0 {
        1.0
    } else {
        let a = x * f32::consts::PI;
        a.sin() / a
    }
}

#[inline]
fn lanczos(taps: f32, x: f32) -> f32 {
    if x.abs() < taps {
        sinc(x) * sinc(x / taps)
    } else {
        0.0
    }
}

/// Supported pixel formats.
// TODO(Kagami): >8-bit formats.
#[derive(Debug, Clone, Copy)]
pub enum Pixel {
    /// Grayscale, 8-bit.
    Gray8,
    /// RGB, 8-bit per component.
    RGB24,
    /// RGBA, 8-bit per component.
    RGBA,
}

impl Pixel {
    /// Size of one pixel in that format in bytes.
    #[inline]
    pub fn get_size(&self) -> usize {
        match *self {
            Pixel::Gray8 => 1,
            Pixel::RGB24 => 3,
            Pixel::RGBA => 4,
        }
    }

    /// Return number of components of that format.
    #[inline]
    pub fn get_ncomponents(&self) -> usize {
        match *self {
            Pixel::Gray8 => 1,
            Pixel::RGB24 => 3,
            Pixel::RGBA => 4,
        }
    }
}

/// Resampler with preallocated buffers and coeffecients for the given
/// dimensions and filter type.
#[derive(Debug)]
pub struct Resizer {
    // Source/target dimensions.
    w1: usize,
    h1: usize,
    w2: usize,
    h2: usize,
    pix_fmt: Pixel,
    // Temporary/preallocated stuff.
    tmp: Vec<f32>,
    accum: Vec<f32>,
    coeffs_w: Vec<CoeffsLine>,
    coeffs_h: Vec<CoeffsLine>,
}

#[derive(Debug)]
struct CoeffsLine {
    left: usize,
    data: Vec<f32>,
}

impl Resizer {
    /// Create a new resizer instance.
    pub fn new(w1: usize, h1: usize, w2: usize, h2: usize, p: Pixel, t: Type) -> Resizer {
        let filter = match t {
            Type::Point     => Filter::new(Box::new(point_kernel),                      0.0),
            Type::Nearest   => Filter::new(Box::new(box_kernel),                        0.5),
            Type::Triangle  => Filter::new(Box::new(triangle_kernel),                   1.0),
            Type::Catrom    => Filter::new(Box::new(|x| cubic_bc(0.0, 0.5, x)),         2.0),
            Type::Mitchell  => Filter::new(Box::new(|x| cubic_bc(1.0/3.0, 1.0/3.0, x)), 2.0),
            Type::Lanczos2  => Filter::new(Box::new(|x| lanczos(2.0, x)),               2.0),
            Type::Lanczos3  => Filter::new(Box::new(|x| lanczos(3.0, x)),               3.0),
            Type::Custom(f) => f,
        };
        Resizer {
            w1: w1,
            h1: h1,
            w2: w2,
            h2: h2,
            pix_fmt: p,
            tmp: vec![0.0;w1*h2*p.get_size()],
            accum: vec![0.0;p.get_ncomponents()],
            // TODO(Kagami): Use same coeffs if w1 = h1 = w2 = h2?
            coeffs_w: Self::calc_coeffs(w1, w2, &filter),
            coeffs_h: Self::calc_coeffs(h1, h2, &filter),
        }
    }

    fn calc_coeffs(s1: usize, s2: usize, f: &Filter) -> Vec<CoeffsLine> {
        let ratio = s1 as f32 / s2 as f32;
        // Scale the filter when downsampling.
        let filter_scale = if ratio > 1.0 { ratio } else { 1.0 };
        let filter_radius = (f.support * filter_scale).ceil();
        let mut coeffs = Vec::with_capacity(s2);
        for x2 in 0..s2 {
            let x1 = (x2 as f32 + 0.5) * ratio - 0.5;
            let left = (x1 - filter_radius).ceil() as isize;
            let left = Self::clamp(left, 0, s1 as isize - 1) as usize;
            let right = (x1 + filter_radius).floor() as isize;
            let right = Self::clamp(right, 0, s1 as isize - 1) as usize;
            let mut data = Vec::with_capacity(right - left + 1);
            let mut sum = 0.0;
            for i in left..right+1 {
                sum += (f.kernel)((i as f32 - x1) / filter_scale);
            }
            for i in left..right+1 {
                let v = (f.kernel)((i as f32 - x1) / filter_scale);
                data.push(v / sum);
            }
            coeffs.push(CoeffsLine {left: left, data: data});
        }
        coeffs
    }

    #[inline]
    fn clamp<N: PartialOrd>(v: N, min: N, max: N) -> N {
        if v <= min {
            min
        } else if v >= max {
            max
        } else {
            v
        }
    }

    #[inline]
    fn pack_u8(mut v: f32) -> u8 {
        v = v.round();
        v = f32::min(f32::max(v, 0.0), 255.0);
        v as u8
    }

    #[inline]
    fn clear_accum(&mut self) {
        for v in self.accum.iter_mut() {
            *v = 0.0;
        }
    }

    // Resample W1xH1 to W1xH2.
    fn sample_rows(&mut self, src: &[u8]) {
        let ncomp = self.pix_fmt.get_ncomponents();
        let mut offset = 0;
        for x1 in 0..self.w1 {
            for y2 in 0..self.h2 {
                self.clear_accum();
                let ref line = self.coeffs_h[y2];
                for (i, coeff) in line.data.iter().enumerate() {
                    let y0 = line.left + i;
                    let base = (y0 * self.w1 + x1) * ncomp;
                    for n in 0..ncomp {
                        let p = src[base + n] as f32;
                        self.accum[n] += p * coeff;
                    }
                }
                for &v in &self.accum {
                    self.tmp[offset] = v;
                    offset += 1;
                }
            }
        }
    }

    // Resample W1xH2 to W2xH2.
    fn sample_cols(&mut self, dst: &mut [u8]) {
        let ncomp = self.pix_fmt.get_ncomponents();
        let mut offset = 0;
        for y2 in 0..self.h2 {
            for x2 in 0..self.w2 {
                self.clear_accum();
                let ref line = self.coeffs_w[x2];
                for (i, coeff) in line.data.iter().enumerate() {
                    let x0 = line.left + i;
                    let base = (x0 * self.h2 + y2) * ncomp;
                    for n in 0..ncomp {
                        let p = self.tmp[base + n];
                        self.accum[n] += p * coeff;
                    }
                }
                for &v in &self.accum {
                    dst[offset] = Self::pack_u8(v);
                    offset += 1;
                }
            }
        }
    }

    /// Resize `src` image data into `dst`.
    pub fn resize(&mut self, src: &[u8], dst: &mut [u8]) {
        // TODO(Kagami):
        // * Multi-thread
        // * Bound checkings
        // * SIMD
        assert_eq!(src.len(), self.w1 * self.h1 * self.pix_fmt.get_size());
        assert_eq!(dst.len(), self.w2 * self.h2 * self.pix_fmt.get_size());
        self.sample_rows(src);
        self.sample_cols(dst)
    }
}

/// Create a new resizer instance. Alias for `Resizer::new`.
pub fn new(w1: usize, h1: usize, w2: usize, h2: usize, p: Pixel, t: Type) -> Resizer {
    Resizer::new(w1, h1, w2, h2, p, t)
}

/// Resize image data to the new dimension in a single step.
///
/// **NOTE:** If you need to resize to the same dimension multiple times,
/// consider creating an resizer instance since it's faster.
pub fn resize(
    w1: usize, h1: usize, w2: usize, h2: usize,
    p: Pixel, t: Type,
    src: &[u8], dst: &mut [u8],
) {
    Resizer::new(w1, h1, w2, h2, p, t).resize(src, dst)
}
<commit_msg>Fix example filter<commit_after>//! Simple resampling library in pure Rust.
//!
//! # Examples
//!
//! ```ignore
//! extern crate resize;
//! use resize::Pixel::Gray8;
//! use resize::Type::Triangle;
//! let mut src = vec![0;w1*h1];
//! let mut dst = vec![0;w2*h2];
//! let mut resizer = resize::new(w1, h1, w2, h2, Gray8, Triangle);
//! resizer.resize(&src, &mut dst);
//! ```
// Current implementation is based on:
// * https://github.com/sekrit-twc/zimg/tree/master/src/zimg/resize
// * https://github.com/PistonDevelopers/image/blob/master/src/imageops/sample.rs
#![deny(missing_docs)]

use std::f32;

/// Resizing type to use.
pub enum Type {
    /// Point resizing.
    Point,
    /// Box (nearest) resizing.
    Nearest,
    /// Triangle (bilinear) resizing.
    Triangle,
    /// Catmull-Rom (bicubic) resizing.
    Catrom,
    /// Resize using Mitchell-Netravali filter.
    Mitchell,
    /// Resize using sinc-windowed filter with radius of 2.
    Lanczos2,
    /// Sinc-windowed filter with radius of 3.
    Lanczos3,
    /// Resize using custom filter.
    Custom(Filter),
}

/// Resampling filter.
pub struct Filter {
    kernel: Box<Fn(f32) -> f32>,
    support: f32,
}

impl Filter {
    /// Create a new filter.
    ///
    /// # Examples
    ///
    /// ```
    /// use resize::Filter;
    /// fn kernel(x: f32) -> f32 { f32::max(1.0 - x.abs(), 0.0) }
    /// let filter = Filter::new(Box::new(kernel), 1.0);
    /// ```
    pub fn new(kernel: Box<Fn(f32) -> f32>, support: f32) -> Filter {
        Filter {kernel: kernel, support: support}
    }
}

#[inline]
fn point_kernel(_: f32) -> f32 {
    1.0
}

#[inline]
fn box_kernel(x: f32) -> f32 {
    if x.abs() <= 0.5 { 1.0 } else { 0.0 }
}

#[inline]
fn triangle_kernel(x: f32) -> f32 {
    f32::max(1.0 - x.abs(), 0.0)
}

// Taken from
// https://github.com/PistonDevelopers/image/blob/2921cd7/src/imageops/sample.rs#L68
// Could be optimized for known B and C, see e.g.:
// https://github.com/sekrit-twc/zimg/blob/1a606c0/src/zimg/resize/filter.cpp#L149
#[inline]
fn cubic_bc(b: f32, c: f32, x: f32) -> f32 {
    let a = x.abs();
    let k = if a < 1.0 {
        (12.0 - 9.0 * b - 6.0 * c) * a.powi(3) +
        (-18.0 + 12.0 * b + 6.0 * c) * a.powi(2) +
        (6.0 - 2.0 * b)
    } else if a < 2.0 {
        (-b - 6.0 * c) * a.powi(3) +
        (6.0 * b + 30.0 * c) * a.powi(2) +
        (-12.0 * b - 48.0 * c) * a +
        (8.0 * b + 24.0 * c)
    } else {
        0.0
    };
    k / 6.0
}

#[inline]
fn sinc(x: f32) -> f32 {
    if x == 0.0 {
        1.0
    } else {
        let a = x * f32::consts::PI;
        a.sin() / a
    }
}

#[inline]
fn lanczos(taps: f32, x: f32) -> f32 {
    if x.abs() < taps {
        sinc(x) * sinc(x / taps)
    } else {
        0.0
    }
}

/// Supported pixel formats.
// TODO(Kagami): >8-bit formats.
#[derive(Debug, Clone, Copy)]
pub enum Pixel {
    /// Grayscale, 8-bit.
    Gray8,
    /// RGB, 8-bit per component.
    RGB24,
    /// RGBA, 8-bit per component.
    RGBA,
}

impl Pixel {
    /// Size of one pixel in that format in bytes.
    #[inline]
    pub fn get_size(&self) -> usize {
        match *self {
            Pixel::Gray8 => 1,
            Pixel::RGB24 => 3,
            Pixel::RGBA => 4,
        }
    }

    /// Return number of components of that format.
    #[inline]
    pub fn get_ncomponents(&self) -> usize {
        match *self {
            Pixel::Gray8 => 1,
            Pixel::RGB24 => 3,
            Pixel::RGBA => 4,
        }
    }
}

/// Resampler with preallocated buffers and coeffecients for the given
/// dimensions and filter type.
#[derive(Debug)]
pub struct Resizer {
    // Source/target dimensions.
    w1: usize,
    h1: usize,
    w2: usize,
    h2: usize,
    pix_fmt: Pixel,
    // Temporary/preallocated stuff.
    tmp: Vec<f32>,
    accum: Vec<f32>,
    coeffs_w: Vec<CoeffsLine>,
    coeffs_h: Vec<CoeffsLine>,
}

#[derive(Debug)]
struct CoeffsLine {
    left: usize,
    data: Vec<f32>,
}

impl Resizer {
    /// Create a new resizer instance.
    pub fn new(w1: usize, h1: usize, w2: usize, h2: usize, p: Pixel, t: Type) -> Resizer {
        let filter = match t {
            Type::Point     => Filter::new(Box::new(point_kernel),                      0.0),
            Type::Nearest   => Filter::new(Box::new(box_kernel),                        0.5),
            Type::Triangle  => Filter::new(Box::new(triangle_kernel),                   1.0),
            Type::Catrom    => Filter::new(Box::new(|x| cubic_bc(0.0, 0.5, x)),         2.0),
            Type::Mitchell  => Filter::new(Box::new(|x| cubic_bc(1.0/3.0, 1.0/3.0, x)), 2.0),
            Type::Lanczos2  => Filter::new(Box::new(|x| lanczos(2.0, x)),               2.0),
            Type::Lanczos3  => Filter::new(Box::new(|x| lanczos(3.0, x)),               3.0),
            Type::Custom(f) => f,
        };
        Resizer {
            w1: w1,
            h1: h1,
            w2: w2,
            h2: h2,
            pix_fmt: p,
            tmp: vec![0.0;w1*h2*p.get_size()],
            accum: vec![0.0;p.get_ncomponents()],
            // TODO(Kagami): Use same coeffs if w1 = h1 = w2 = h2?
            coeffs_w: Self::calc_coeffs(w1, w2, &filter),
            coeffs_h: Self::calc_coeffs(h1, h2, &filter),
        }
    }

    fn calc_coeffs(s1: usize, s2: usize, f: &Filter) -> Vec<CoeffsLine> {
        let ratio = s1 as f32 / s2 as f32;
        // Scale the filter when downsampling.
        let filter_scale = if ratio > 1.0 { ratio } else { 1.0 };
        let filter_radius = (f.support * filter_scale).ceil();
        let mut coeffs = Vec::with_capacity(s2);
        for x2 in 0..s2 {
            let x1 = (x2 as f32 + 0.5) * ratio - 0.5;
            let left = (x1 - filter_radius).ceil() as isize;
            let left = Self::clamp(left, 0, s1 as isize - 1) as usize;
            let right = (x1 + filter_radius).floor() as isize;
            let right = Self::clamp(right, 0, s1 as isize - 1) as usize;
            let mut data = Vec::with_capacity(right - left + 1);
            let mut sum = 0.0;
            for i in left..right+1 {
                sum += (f.kernel)((i as f32 - x1) / filter_scale);
            }
            for i in left..right+1 {
                let v = (f.kernel)((i as f32 - x1) / filter_scale);
                data.push(v / sum);
            }
            coeffs.push(CoeffsLine {left: left, data: data});
        }
        coeffs
    }

    #[inline]
    fn clamp<N: PartialOrd>(v: N, min: N, max: N) -> N {
        if v <= min {
            min
        } else if v >= max {
            max
        } else {
            v
        }
    }

    #[inline]
    fn pack_u8(mut v: f32) -> u8 {
        v = v.round();
        v = f32::min(f32::max(v, 0.0), 255.0);
        v as u8
    }

    #[inline]
    fn clear_accum(&mut self) {
        for v in self.accum.iter_mut() {
            *v = 0.0;
        }
    }

    // Resample W1xH1 to W1xH2.
    fn sample_rows(&mut self, src: &[u8]) {
        let ncomp = self.pix_fmt.get_ncomponents();
        let mut offset = 0;
        for x1 in 0..self.w1 {
            for y2 in 0..self.h2 {
                self.clear_accum();
                let ref line = self.coeffs_h[y2];
                for (i, coeff) in line.data.iter().enumerate() {
                    let y0 = line.left + i;
                    let base = (y0 * self.w1 + x1) * ncomp;
                    for n in 0..ncomp {
                        let p = src[base + n] as f32;
                        self.accum[n] += p * coeff;
                    }
                }
                for &v in &self.accum {
                    self.tmp[offset] = v;
                    offset += 1;
                }
            }
        }
    }

    // Resample W1xH2 to W2xH2.
    fn sample_cols(&mut self, dst: &mut [u8]) {
        let ncomp = self.pix_fmt.get_ncomponents();
        let mut offset = 0;
        for y2 in 0..self.h2 {
            for x2 in 0..self.w2 {
                self.clear_accum();
                let ref line = self.coeffs_w[x2];
                for (i, coeff) in line.data.iter().enumerate() {
                    let x0 = line.left + i;
                    let base = (x0 * self.h2 + y2) * ncomp;
                    for n in 0..ncomp {
                        let p = self.tmp[base + n];
                        self.accum[n] += p * coeff;
                    }
                }
                for &v in &self.accum {
                    dst[offset] = Self::pack_u8(v);
                    offset += 1;
                }
            }
        }
    }

    /// Resize `src` image data into `dst`.
    pub fn resize(&mut self, src: &[u8], dst: &mut [u8]) {
        // TODO(Kagami):
        // * Multi-thread
        // * Bound checkings
        // * SIMD
        assert_eq!(src.len(), self.w1 * self.h1 * self.pix_fmt.get_size());
        assert_eq!(dst.len(), self.w2 * self.h2 * self.pix_fmt.get_size());
        self.sample_rows(src);
        self.sample_cols(dst)
    }
}

/// Create a new resizer instance. Alias for `Resizer::new`.
pub fn new(w1: usize, h1: usize, w2: usize, h2: usize, p: Pixel, t: Type) -> Resizer {
    Resizer::new(w1, h1, w2, h2, p, t)
}

/// Resize image data to the new dimension in a single step.
///
/// **NOTE:** If you need to resize to the same dimension multiple times,
/// consider creating an resizer instance since it's faster.
pub fn resize(
    w1: usize, h1: usize, w2: usize, h2: usize,
    p: Pixel, t: Type,
    src: &[u8], dst: &mut [u8],
) {
    Resizer::new(w1, h1, w2, h2, p, t).resize(src, dst)
}
<|endoftext|>


<commit_before>#![crate_name = "macaroons"]
#![crate_type = "lib"]

#![feature(core)]
#![feature(collections)]

use std::slice::bytes;

pub mod caveat;
pub use caveat::{Caveat, Predicate};
pub use sodiumoxide::crypto::auth::hmacsha256::{Key, Tag, TAGBYTES};

extern crate sodiumoxide;
use sodiumoxide::crypto::auth::hmacsha256::authenticate;

extern crate "rustc-serialize" as serialize;
use serialize::base64::{self, FromBase64, ToBase64};

// Macaroons personalize the HMAC key using this string
// "macaroons-key-generator" padded to 32-bytes with zeroes
const KEY_GENERATOR: &'static [u8; 32] = b"macaroons-key-generator\0\0\0\0\0\0\0\0\0";

const PACKET_PREFIX_LENGTH: usize = 4;
const MAX_PACKET_LENGTH:    usize = 65535;

pub struct Token {
  pub location:   Vec<u8>,
  pub identifier: Vec<u8>,
  pub caveats:    Vec<Caveat>,
  pub tag:        Tag
}

struct Packet {
  pub field: Vec<u8>,
  pub value: Vec<u8>
}

impl Token {
  pub fn new(key: Vec<u8>, identifier: Vec<u8>, location: Vec<u8>) -> Token {
    let Tag(personalized_key) = authenticate(&key, &Key(*KEY_GENERATOR));
    let tag = authenticate(&identifier, &Key(personalized_key));

    Token {
      location:   location,
      identifier: identifier,
      caveats:    Vec::new(),
      tag:        tag
    }
  }

  pub fn deserialize(macaroon: Vec<u8>) -> Result<Token, &'static str> {
    let mut location:   Option<Vec<u8>> = None;
    let mut identifier: Option<Vec<u8>> = None;
    let mut caveats:    Vec<Caveat>     = Vec::new();
    let mut tag:        Option<Tag>     = None;

    let token_data = match macaroon.as_slice().from_base64() {
      Ok(bytes) => bytes,
      _         => return Err("couldn't parse base64")
    };

    let mut index: usize = 0;

    while index < token_data.len() {
      let (packet, packet_length) = match Token::depacketize(&token_data, index) {
        Ok((p, t))  => (p, t),
        Err(reason) => return Err(reason)
      };

      index += packet_length;

      match packet.field.as_slice() {
        b"location"   => location   = Some(packet.value),
        b"identifier" => identifier = Some(packet.value),
        b"cid"        => caveats.push(Caveat::new(Predicate(packet.value))),
        b"signature"  => {
          if packet.value.len() != TAGBYTES {
            return Err("invalid signature length")
          }

          let mut signature_bytes = [0u8; TAGBYTES];
          bytes::copy_memory(&mut signature_bytes, &packet.value[..TAGBYTES]);

          tag = Some(Tag(signature_bytes))
        },
        _ => return Err("unrecognized packet type")
      }
    }

    if location   == None { return Err("no 'location' found"); }
    if identifier == None { return Err("no 'identifier' found"); }
    if tag        == None { return Err("no 'signature' found"); }

    let token = Token {
      location:   location.unwrap(),
      identifier: identifier.unwrap(),
      caveats:    caveats,
      tag:        tag.unwrap()
    };

    Ok(token)
  }

  fn depacketize(data: &Vec<u8>, index: usize) -> Result<(Packet, usize), &'static str> {
    // TODO: parse this length without involving any UTF-8 conversions
    let length_str = match std::str::from_utf8(&data[index .. index + PACKET_PREFIX_LENGTH]) {
      Ok(string) => string,
      _          => return Err("couldn't stringify packet length")
    };

    let packet_length: usize = match std::num::from_str_radix(length_str, 16) {
      Ok(length) => length,
      _          => return Err("couldn't parse packet length")
    };

    let mut packet_bytes = data[index + PACKET_PREFIX_LENGTH .. index + packet_length].to_vec();

    let pos = match packet_bytes.iter().position(|&byte| byte == b' ') {
      Some(i) => i,
      None    => return Err("malformed packet")
    };

    let mut value = packet_bytes.split_off(pos);
    value.remove(0);

    match value.pop().unwrap() {
      b'\n' => (),
      _     => return Err("packet not newline terminated")
    }

    let packet = Packet { field: packet_bytes, value: value };
    Ok((packet, packet_length))
  }

  pub fn add_caveat(&self, caveat: Caveat) -> Token {
    let Tag(key_bytes) = self.tag;
    let Predicate(predicate_bytes) = caveat.predicate.clone();
    let tag = authenticate(&predicate_bytes, &Key(key_bytes));

    let mut new_caveats = self.caveats.to_vec();
    new_caveats.push(caveat);

    Token {
      identifier: self.identifier.clone(),
      location:   self.location.clone(),
      caveats:    new_caveats,
      tag:        tag
    }
  }

  pub fn serialize(&self) -> Vec<u8> {
    // TODO: estimate capacity and use Vec::with_capacity
    let mut result: Vec<u8> = Vec::new();

    Token::packetize(&mut result, "location",   &self.location);
    Token::packetize(&mut result, "identifier", &self.identifier);

    for caveat in self.caveats.iter() {
      let Predicate(predicate_bytes) = caveat.predicate.clone();
      Token::packetize(&mut result, "cid", &predicate_bytes);
    }

    let Tag(signature_bytes) = self.tag;
    let mut signature_vec = Vec::new();
    signature_vec.push_all(&signature_bytes);

    Token::packetize(&mut result, "signature", &signature_vec);

    result.to_base64(base64::URL_SAFE).into_bytes()
  }

  fn packetize(result: &mut Vec<u8>, field: &str, value: &Vec<u8>) {
    let field_bytes: Vec<u8> = String::from_str(field).into_bytes();
    let packet_length = PACKET_PREFIX_LENGTH + field_bytes.len() + value.len() + 2;

    if packet_length > MAX_PACKET_LENGTH {
      panic!("packet too large to serialize");
    }

    let mut pkt_line = format!("{:04x}{} ", packet_length, field).into_bytes();
    result.append(&mut pkt_line);
    result.append(&mut value.clone());
    result.push('\n' as u8);
  }
}
<commit_msg>Move packet length into Packet<commit_after>#![crate_name = "macaroons"]
#![crate_type = "lib"]

#![feature(core)]
#![feature(collections)]

use std::slice::bytes;

pub mod caveat;
pub use caveat::{Caveat, Predicate};
pub use sodiumoxide::crypto::auth::hmacsha256::{Key, Tag, TAGBYTES};

extern crate sodiumoxide;
use sodiumoxide::crypto::auth::hmacsha256::authenticate;

extern crate "rustc-serialize" as serialize;
use serialize::base64::{self, FromBase64, ToBase64};

// Macaroons personalize the HMAC key using this string
// "macaroons-key-generator" padded to 32-bytes with zeroes
const KEY_GENERATOR: &'static [u8; 32] = b"macaroons-key-generator\0\0\0\0\0\0\0\0\0";

const PACKET_PREFIX_LENGTH: usize = 4;
const MAX_PACKET_LENGTH:    usize = 65535;

pub struct Token {
  pub location:   Vec<u8>,
  pub identifier: Vec<u8>,
  pub caveats:    Vec<Caveat>,
  pub tag:        Tag
}

struct Packet {
  pub id:     Vec<u8>,
  pub value:  Vec<u8>,
  pub length: usize
}

impl Token {
  pub fn new(key: Vec<u8>, identifier: Vec<u8>, location: Vec<u8>) -> Token {
    let Tag(personalized_key) = authenticate(&key, &Key(*KEY_GENERATOR));
    let tag = authenticate(&identifier, &Key(personalized_key));

    Token {
      location:   location,
      identifier: identifier,
      caveats:    Vec::new(),
      tag:        tag
    }
  }

  pub fn deserialize(macaroon: Vec<u8>) -> Result<Token, &'static str> {
    let mut location:   Option<Vec<u8>> = None;
    let mut identifier: Option<Vec<u8>> = None;
    let mut caveats:    Vec<Caveat>     = Vec::new();
    let mut tag:        Option<Tag>     = None;

    let token_data = match macaroon.as_slice().from_base64() {
      Ok(bytes) => bytes,
      _         => return Err("couldn't parse base64")
    };

    let mut index: usize = 0;

    while index < token_data.len() {
      let packet = match Token::depacketize(&token_data, index) {
        Ok(p)       => p,
        Err(reason) => return Err(reason)
      };

      index += packet.length;

      match packet.id.as_slice() {
        b"location"   => location   = Some(packet.value),
        b"identifier" => identifier = Some(packet.value),
        b"cid"        => caveats.push(Caveat::new(Predicate(packet.value))),
        b"signature"  => {
          if packet.value.len() != TAGBYTES {
            return Err("invalid signature length")
          }

          let mut signature_bytes = [0u8; TAGBYTES];
          bytes::copy_memory(&mut signature_bytes, &packet.value[..TAGBYTES]);

          tag = Some(Tag(signature_bytes))
        },
        _ => return Err("unrecognized packet type")
      }
    }

    if location   == None { return Err("no 'location' found"); }
    if identifier == None { return Err("no 'identifier' found"); }
    if tag        == None { return Err("no 'signature' found"); }

    let token = Token {
      location:   location.unwrap(),
      identifier: identifier.unwrap(),
      caveats:    caveats,
      tag:        tag.unwrap()
    };

    Ok(token)
  }

  fn depacketize(data: &Vec<u8>, index: usize) -> Result<Packet, &'static str> {
    // TODO: parse this length without involving any UTF-8 conversions
    let length_str = match std::str::from_utf8(&data[index .. index + PACKET_PREFIX_LENGTH]) {
      Ok(string) => string,
      _          => return Err("couldn't stringify packet length")
    };

    let packet_length: usize = match std::num::from_str_radix(length_str, 16) {
      Ok(length) => length,
      _          => return Err("couldn't parse packet length")
    };

    let mut packet_bytes = data[index + PACKET_PREFIX_LENGTH .. index + packet_length].to_vec();

    let pos = match packet_bytes.iter().position(|&byte| byte == b' ') {
      Some(i) => i,
      None    => return Err("malformed packet")
    };

    let mut value = packet_bytes.split_off(pos);
    value.remove(0);

    match value.pop().unwrap() {
      b'\n' => (),
      _     => return Err("packet not newline terminated")
    }

    Ok(Packet { id: packet_bytes, value: value, length: packet_length })
  }

  pub fn add_caveat(&self, caveat: Caveat) -> Token {
    let Tag(key_bytes) = self.tag;
    let Predicate(predicate_bytes) = caveat.predicate.clone();
    let tag = authenticate(&predicate_bytes, &Key(key_bytes));

    let mut new_caveats = self.caveats.to_vec();
    new_caveats.push(caveat);

    Token {
      identifier: self.identifier.clone(),
      location:   self.location.clone(),
      caveats:    new_caveats,
      tag:        tag
    }
  }

  pub fn serialize(&self) -> Vec<u8> {
    // TODO: estimate capacity and use Vec::with_capacity
    let mut result: Vec<u8> = Vec::new();

    Token::packetize(&mut result, "location",   &self.location);
    Token::packetize(&mut result, "identifier", &self.identifier);

    for caveat in self.caveats.iter() {
      let Predicate(predicate_bytes) = caveat.predicate.clone();
      Token::packetize(&mut result, "cid", &predicate_bytes);
    }

    let Tag(signature_bytes) = self.tag;
    let mut signature_vec = Vec::new();
    signature_vec.push_all(&signature_bytes);

    Token::packetize(&mut result, "signature", &signature_vec);

    result.to_base64(base64::URL_SAFE).into_bytes()
  }

  fn packetize(result: &mut Vec<u8>, field: &str, value: &Vec<u8>) {
    let field_bytes: Vec<u8> = String::from_str(field).into_bytes();
    let packet_length = PACKET_PREFIX_LENGTH + field_bytes.len() + value.len() + 2;

    if packet_length > MAX_PACKET_LENGTH {
      panic!("packet too large to serialize");
    }

    let mut pkt_line = format!("{:04x}{} ", packet_length, field).into_bytes();
    result.append(&mut pkt_line);
    result.append(&mut value.clone());
    result.push('\n' as u8);
  }
}
<|endoftext|>


<commit_before>#![feature(plugin_registrar, quote, rustc_private, custom_attribute)]

extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::registry::Registry;
use syntax::ast::{Attribute, Block, Expr, ExprKind, Ident, Item, ItemKind, Mac,
                  MetaItem, Constness};
use syntax::fold::{self, Folder};
use syntax::ptr::P;
use syntax::codemap::{DUMMY_SP, Span, Spanned};
use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension};
use syntax::ext::build::AstBuilder;
use syntax::feature_gate::AttributeType;
use syntax::symbol::Symbol;
use syntax::util::small_vector::SmallVector;

pub fn insert_flame_guard(cx: &mut ExtCtxt, _span: Span, _mi: &MetaItem,
                          a: Annotatable) -> Annotatable {
    match a {
        Annotatable::Item(i) => Annotatable::Item(
            Flamer { cx: cx, ident: i.ident }.fold_item(i).expect_one("expected exactly one item")),
        Annotatable::TraitItem(i) => Annotatable::TraitItem(
            i.map(|i| Flamer { cx: cx, ident: i.ident }.fold_trait_item(i).expect_one("expected exactly one item"))),
        Annotatable::ImplItem(i) => Annotatable::ImplItem(
            i.map(|i| Flamer { cx: cx, ident: i.ident }.fold_impl_item(i).expect_one("expected exactly one item"))),
    }
}

struct Flamer<'a, 'cx: 'a> {
    ident: Ident,
    cx: &'a mut ExtCtxt<'cx>,
}

impl<'a, 'cx> Folder for Flamer<'a, 'cx> {
    fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
        if let ItemKind::Mac(_) = item.node {
            let expanded = self.cx.expander().fold_item(item);
            expanded.into_iter()
                    .flat_map(|i| fold::noop_fold_item(i, self).into_iter())
                    .collect()
        } else {
            fold::noop_fold_item(item, self)
        }
    }

    fn fold_item_simple(&mut self, i: Item) -> Item {
        fn is_flame_annotation(attr: &Attribute) -> bool {
            attr.name().map_or(false, |name|
                    name == "flame" || name == "noflame")
        }
        // don't double-flame nested annotations
        if i.attrs.iter().any(is_flame_annotation) { return i; }

        // don't flame constant functions
        if let ItemKind::Fn(_, _, Spanned{ node: Constness::Const, .. }, ..) = i.node {
            return i;
        }

        if let ItemKind::Mac(_) = i.node {
            return i;
        } else {
            self.ident = i.ident; // update in case of nested items
            fold::noop_fold_item_simple(i, self)
        }
    }

    fn fold_block(&mut self, block: P<Block>) -> P<Block> {
        block.map(|block| {
            let name = self.cx.expr_str(DUMMY_SP, self.ident.name);
            quote_block!(self.cx, {
                let _name = ::flame::start_guard($name);
                $block
            }).into_inner()
        })
    }

    fn fold_expr(&mut self, expr: P<Expr>) -> P<Expr> {
        if let ExprKind::Mac(_) = expr.node {
            self.cx.expander().fold_expr(expr)
                              .map(|e| fold::noop_fold_expr(e, self))
        } else {
            expr
        }
    }

    fn fold_mac(&mut self, mac: Mac) -> Mac {
        mac
    }
}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(Symbol::intern("flame"),
        SyntaxExtension::MultiModifier(Box::new(insert_flame_guard)));
    reg.register_attribute(String::from("noflame"), AttributeType::Whitelisted);
}
<commit_msg>Rustup<commit_after>#![feature(plugin_registrar, quote, rustc_private, custom_attribute)]

extern crate rustc_plugin;
extern crate syntax;

use rustc_plugin::registry::Registry;
use syntax::ast::{Attribute, Block, Expr, ExprKind, Ident, Item, ItemKind, Mac,
                  MetaItem, Constness};
use syntax::fold::{self, Folder};
use syntax::ptr::P;
use syntax::codemap::{DUMMY_SP, Span, Spanned};
use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension};
use syntax::ext::build::AstBuilder;
use syntax::feature_gate::AttributeType;
use syntax::symbol::Symbol;
use syntax::util::small_vector::SmallVector;

pub fn insert_flame_guard(cx: &mut ExtCtxt, _span: Span, _mi: &MetaItem,
                          a: Annotatable) -> Annotatable {
    match a {
        Annotatable::Item(i) => Annotatable::Item(
            Flamer { cx: cx, ident: i.ident }.fold_item(i).expect_one("expected exactly one item")),
        Annotatable::TraitItem(i) => Annotatable::TraitItem(
            i.map(|i| Flamer { cx, ident: i.ident }.fold_trait_item(i).expect_one("expected exactly one item"))),
        Annotatable::ImplItem(i) => Annotatable::ImplItem(
            i.map(|i| Flamer { cx, ident: i.ident }.fold_impl_item(i).expect_one("expected exactly one item"))),
        a => a
    }
}

struct Flamer<'a, 'cx: 'a> {
    ident: Ident,
    cx: &'a mut ExtCtxt<'cx>,
}

impl<'a, 'cx> Folder for Flamer<'a, 'cx> {
    fn fold_item(&mut self, item: P<Item>) -> SmallVector<P<Item>> {
        if let ItemKind::Mac(_) = item.node {
            let expanded = self.cx.expander().fold_item(item);
            expanded.into_iter()
                    .flat_map(|i| fold::noop_fold_item(i, self).into_iter())
                    .collect()
        } else {
            fold::noop_fold_item(item, self)
        }
    }

    fn fold_item_simple(&mut self, i: Item) -> Item {
        fn is_flame_annotation(attr: &Attribute) -> bool {
            attr.name().map_or(false, |name|
                    name == "flame" || name == "noflame")
        }
        // don't double-flame nested annotations
        if i.attrs.iter().any(is_flame_annotation) { return i; }

        // don't flame constant functions
        if let ItemKind::Fn(_, _, Spanned{ node: Constness::Const, .. }, ..) = i.node {
            return i;
        }

        if let ItemKind::Mac(_) = i.node {
            return i;
        } else {
            self.ident = i.ident; // update in case of nested items
            fold::noop_fold_item_simple(i, self)
        }
    }

    fn fold_block(&mut self, block: P<Block>) -> P<Block> {
        block.map(|block| {
            let name = self.cx.expr_str(DUMMY_SP, self.ident.name);
            quote_block!(self.cx, {
                let _name = ::flame::start_guard($name);
                $block
            }).into_inner()
        })
    }

    fn fold_expr(&mut self, expr: P<Expr>) -> P<Expr> {
        if let ExprKind::Mac(_) = expr.node {
            self.cx.expander().fold_expr(expr)
                              .map(|e| fold::noop_fold_expr(e, self))
        } else {
            expr
        }
    }

    fn fold_mac(&mut self, mac: Mac) -> Mac {
        mac
    }
}

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(Symbol::intern("flame"),
        SyntaxExtension::MultiModifier(Box::new(insert_flame_guard)));
    reg.register_attribute(String::from("noflame"), AttributeType::Whitelisted);
}
<|endoftext|>


<commit_before>mod create;
mod thompson_nfa;

pub use self::create::*;
pub use self::thompson_nfa::*;

#[cfg(test)]
mod tests {
    use self::create;

    fn compile_regexp_test() {
        let regexp = create::regexp_from_string("abc");
        let insts = super::thompson_nfa::compile_regexp(regexp);
    }
}
<commit_msg>Added thompson_nfa result tests<commit_after>mod create;
mod thompson_nfa;
mod matching;

pub use self::create::*;
pub use self::thompson_nfa::*;
pub use self::matching::*;

#[cfg(test)]
mod tests {
    use super::create::*;
    use super::thompson_nfa::*;
    use super::matching::*;

    #[test]
    fn compile_regexp_test() {
        // let regexp = create::regexp_from_string("abc").unwrap();
        // let insts = super::thompson_nfa::compile_regexp(regexp);
    }

    #[test]
    fn thompson_vm_match_tests() {
        let test_cases = vec![
            // (regexp, input, extected result)
            ("a", "a", true),
            ("a", "b", false),
            ("aa", "aa", true),
            ("aa", "a", false),
            // Optional tests
            ("a?b", "ab", true),
            ("a?b", "b", true),
            // Repeated tests
            ("a+b", "aab", true),
            ("a+b", "b", false),
            // OptionalRepeated tests
            ("a*b", "aab", true),
            ("a*b", "b", true),
            // Multi-operator tests
            ("a+b*c", "aac", true),
            ("a+b*c", "aabbc", true),
            ("a+b*c", "aabb", false),
            ("(ab)+cd", "ababcd", true),
            ("colou?r", "color", true),
            ("colou?r", "colour", true),
        ];

        println!("");

        for (i, test_case) in test_cases.iter().enumerate() {
            let regexp = regexp_from_string(test_case.0).unwrap();
            let input = test_case.1;
            let expected_result = test_case.2;

            let insts = compile_regexp(&regexp);

            let result = thompson_vm(&insts, input);
            if result != expected_result {
                let error_message = format!(
                    "\t=== Regexp:\t\t\"{}\" > {:?}\n\
                     \t=== Compiled:\t\t{:?}\n\
                     \t=== Input:\t\t{}\n\
                     \t=== Expected Result:\t{}\n\
                     \t=== Actual Result:\t{}\n",
                    test_case.0, regexp,
                    insts,
                    input,
                    expected_result,
                    result);
                panic!("Unexpected Regexp match result:\n{}", error_message);
            }
        }
    }

    #[test]
    fn matching_test() {
        // let regexp = regexp_from_string("a+q?c?").unwrap();
        // let string = "aqab";
        // let expected_match = "aq";
        // let test_cases = vec![
        //     // (regexp, input, expected output)
        //     ("a", "a", "a"),
        //     ("a+", "aa", "aa"),
        //     ("a?", "ab", "a"),
        //     ("a+", "aba", "a"),
        //     ("a+b?", "aaab", "aaab"),
        //     ("b?", "a", ""),
        //     ("b?a+c", "baaac", "baaac"),
        //     ("b?a+c", "aac", "aac")
        // ];
        // for test_case in test_cases {
        //     let regexp = regexp_from_string(test_case.0).unwrap();
        //     let input = test_case.1;
        //     let expected_match = test_case.2;
        //     match first_match_anchored_start(&regexp, input) {
        //         Some(matched_text) => if matched_text != expected_match {
        //             panic!("\n\tBad regexp match for regexp {:?}: \
        //                     matched_text({}) != expected_match({})",
        //                    regexp, matched_text, expected_match)
        //         },
        //         None => panic!("Regexp({}, {:?}) found no match on \"{}\" \
        //                         when \"{}\" was expected",
        //                        test_case.0, regexp, test_case.1, test_case.2)
        //     }
        // }
    }

    #[test]
    fn instruction_generation() {
        use Inst::*;
        let con_insts = compile_regexp(&regexp_from_string("abc").unwrap());
        let alt_insts = compile_regexp(&regexp_from_string("a|b|c").unwrap());
        let opt_insts = compile_regexp(&regexp_from_string("a?(bc)?").unwrap());
        let rep_insts = compile_regexp(&regexp_from_string("a+(bc)+").unwrap());
        let oprep_insts = compile_regexp(&regexp_from_string("a*(bc)*").unwrap());

        assert_eq!(con_insts, vec![Char('a'), Char('b'), Char('c'), Match]);
        assert_eq!(alt_insts, vec![Char('a'), Jump(5),
                                   Char('b'), Jump(5),
                                   Char('c'), Match]);
        assert_eq!(opt_insts, vec![Split(1, 2), Char('a'),
                                   Split(3, 5),
                                   Char('b'), Char('c'),
                                   Match]);
        assert_eq!(rep_insts, vec![Char('a'), Split(0, 2),
                                   Char('b'), Char('c'), Split(2, 5),
                                   Match]);
        assert_eq!(oprep_insts, vec![Split(1, 3), Char('a'), Jump(0),
                                     Split(4, 7), Char('b'), Char('c'), Jump(3),
                                     Match])
    }
}

<|endoftext|>