<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

register_long_diagnostics! {

E0445: r##"
A private trait was used on a public type parameter bound. Erroneous code
examples:

```compile_fail
trait Foo {
    fn dummy(&self) { }
}

pub trait Bar : Foo {} // error: private trait in public interface
pub struct Bar2<T: Foo>(pub T); // same error
pub fn foo<T: Foo> (t: T) {} // same error
```

To solve this error, please ensure that the trait is also public. The trait
can be made inaccessible if necessary by placing it into a private inner module,
but it still has to be marked with `pub`. Example:

```ignore
pub trait Foo { // we set the Foo trait public
    fn dummy(&self) { }
}

pub trait Bar : Foo {} // ok!
pub struct Bar2<T: Foo>(pub T); // ok!
pub fn foo<T: Foo> (t: T) {} // ok!
```
"##,

E0446: r##"
A private type was used in a public type signature. Erroneous code example:

```compile_fail
mod Foo {
    struct Bar(u32);

    pub fn bar() -> Bar { // error: private type in public interface
        Bar(0)
    }
}
```

To solve this error, please ensure that the type is also public. The type
can be made inaccessible if necessary by placing it into a private inner module,
but it still has to be marked with `pub`.
Example:

```
mod Foo {
    pub struct Bar(u32); // we set the Bar type public

    pub fn bar() -> Bar { // ok!
        Bar(0)
    }
}
```
"##,

E0447: r##"
The `pub` keyword was used inside a function. Erroneous code example:

```compile_fail
fn foo() {
    pub struct Bar; // error: visibility has no effect inside functions
}
```

Since we cannot access items defined inside a function, the visibility of its
items does not impact outer code. So using the `pub` keyword in this context
is invalid.
"##,

E0448: r##"
The `pub` keyword was used inside a public enum. Erroneous code example:

```compile_fail
pub enum Foo {
    pub Bar, // error: unnecessary `pub` visibility
}
```

Since the enum is already public, adding `pub` on one its elements is
unnecessary. Example:

```compile_fail
enum Foo {
    pub Bar, // not ok!
}
```

This is the correct syntax:

```ignore
pub enum Foo {
    Bar, // ok!
}
```
"##,

E0449: r##"
A visibility qualifier was used when it was unnecessary. Erroneous code
examples:

```compile_fail
struct Bar;

trait Foo {
    fn foo();
}

pub impl Bar {} // error: unnecessary visibility qualifier

pub impl Foo for Bar { // error: unnecessary visibility qualifier
    pub fn foo() {} // error: unnecessary visibility qualifier
}
```

To fix this error, please remove the visibility qualifier when it is not
required. Example:

```ignore
struct Bar;

trait Foo {
    fn foo();
}

// Directly implemented methods share the visibility of the type itself,
// so `pub` is unnecessary here
impl Bar {}

// Trait methods share the visibility of the trait, so `pub` is
// unnecessary in either case
pub impl Foo for Bar {
    pub fn foo() {}
}
```
"##,

E0450: r##"
A tuple constructor was invoked while some of its fields are private. Erroneous
code example:

```compile_fail
mod Bar {
    pub struct Foo(isize);
}

let f = Bar::Foo(0); // error: cannot invoke tuple struct constructor with
                     //        private fields
```

To solve this issue, please ensure that all of the fields of the tuple struct
are public. Alternatively, provide a new() method to the tuple struct to
construct it from a given inner value. Example:

```
mod Bar {
    pub struct Foo(pub isize); // we set its field to public
}

let f = Bar::Foo(0); // ok!

// or:
mod bar {
    pub struct Foo(isize);

    impl Foo {
        pub fn new(x: isize) -> Foo {
            Foo(x)
        }
    }
}

let f = bar::Foo::new(1);
```
"##,

E0451: r##"
A struct constructor with private fields was invoked. Erroneous code example:

```compile_fail
mod Bar {
    pub struct Foo {
        pub a: isize,
        b: isize,
    }
}

let f = Bar::Foo{ a: 0, b: 0 }; // error: field `b` of struct `Bar::Foo`
                                //        is private
```

To fix this error, please ensure that all the fields of the struct, or
implement a function for easy instantiation. Examples:

```
mod Bar {
    pub struct Foo {
        pub a: isize,
        pub b: isize, // we set `b` field public
    }
}

let f = Bar::Foo{ a: 0, b: 0 }; // ok!
```

Or:

```
mod Bar {
    pub struct Foo {
        pub a: isize,
        b: isize, // still private
    }

    impl Foo {
        pub fn new() -> Foo { // we create a method to instantiate `Foo`
            Foo { a: 0, b: 0 }
        }
    }
}

let f = Bar::Foo::new(); // ok!
```
"##,

}
<commit_msg>Fix sentence in E0451 diagnostic.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

register_long_diagnostics! {

E0445: r##"
A private trait was used on a public type parameter bound. Erroneous code
examples:

```compile_fail
trait Foo {
    fn dummy(&self) { }
}

pub trait Bar : Foo {} // error: private trait in public interface
pub struct Bar2<T: Foo>(pub T); // same error
pub fn foo<T: Foo> (t: T) {} // same error
```

To solve this error, please ensure that the trait is also public. The trait
can be made inaccessible if necessary by placing it into a private inner module,
but it still has to be marked with `pub`. Example:

```ignore
pub trait Foo { // we set the Foo trait public
    fn dummy(&self) { }
}

pub trait Bar : Foo {} // ok!
pub struct Bar2<T: Foo>(pub T); // ok!
pub fn foo<T: Foo> (t: T) {} // ok!
```
"##,

E0446: r##"
A private type was used in a public type signature. Erroneous code example:

```compile_fail
mod Foo {
    struct Bar(u32);

    pub fn bar() -> Bar { // error: private type in public interface
        Bar(0)
    }
}
```

To solve this error, please ensure that the type is also public. The type
can be made inaccessible if necessary by placing it into a private inner module,
but it still has to be marked with `pub`.
Example:

```
mod Foo {
    pub struct Bar(u32); // we set the Bar type public

    pub fn bar() -> Bar { // ok!
        Bar(0)
    }
}
```
"##,

E0447: r##"
The `pub` keyword was used inside a function. Erroneous code example:

```compile_fail
fn foo() {
    pub struct Bar; // error: visibility has no effect inside functions
}
```

Since we cannot access items defined inside a function, the visibility of its
items does not impact outer code. So using the `pub` keyword in this context
is invalid.
"##,

E0448: r##"
The `pub` keyword was used inside a public enum. Erroneous code example:

```compile_fail
pub enum Foo {
    pub Bar, // error: unnecessary `pub` visibility
}
```

Since the enum is already public, adding `pub` on one its elements is
unnecessary. Example:

```compile_fail
enum Foo {
    pub Bar, // not ok!
}
```

This is the correct syntax:

```ignore
pub enum Foo {
    Bar, // ok!
}
```
"##,

E0449: r##"
A visibility qualifier was used when it was unnecessary. Erroneous code
examples:

```compile_fail
struct Bar;

trait Foo {
    fn foo();
}

pub impl Bar {} // error: unnecessary visibility qualifier

pub impl Foo for Bar { // error: unnecessary visibility qualifier
    pub fn foo() {} // error: unnecessary visibility qualifier
}
```

To fix this error, please remove the visibility qualifier when it is not
required. Example:

```ignore
struct Bar;

trait Foo {
    fn foo();
}

// Directly implemented methods share the visibility of the type itself,
// so `pub` is unnecessary here
impl Bar {}

// Trait methods share the visibility of the trait, so `pub` is
// unnecessary in either case
pub impl Foo for Bar {
    pub fn foo() {}
}
```
"##,

E0450: r##"
A tuple constructor was invoked while some of its fields are private. Erroneous
code example:

```compile_fail
mod Bar {
    pub struct Foo(isize);
}

let f = Bar::Foo(0); // error: cannot invoke tuple struct constructor with
                     //        private fields
```

To solve this issue, please ensure that all of the fields of the tuple struct
are public. Alternatively, provide a new() method to the tuple struct to
construct it from a given inner value. Example:

```
mod Bar {
    pub struct Foo(pub isize); // we set its field to public
}

let f = Bar::Foo(0); // ok!

// or:
mod bar {
    pub struct Foo(isize);

    impl Foo {
        pub fn new(x: isize) -> Foo {
            Foo(x)
        }
    }
}

let f = bar::Foo::new(1);
```
"##,

E0451: r##"
A struct constructor with private fields was invoked. Erroneous code example:

```compile_fail
mod Bar {
    pub struct Foo {
        pub a: isize,
        b: isize,
    }
}

let f = Bar::Foo{ a: 0, b: 0 }; // error: field `b` of struct `Bar::Foo`
                                //        is private
```

To fix this error, please ensure that all the fields of the struct are public,
or implement a function for easy instantiation. Examples:

```
mod Bar {
    pub struct Foo {
        pub a: isize,
        pub b: isize, // we set `b` field public
    }
}

let f = Bar::Foo{ a: 0, b: 0 }; // ok!
```

Or:

```
mod Bar {
    pub struct Foo {
        pub a: isize,
        b: isize, // still private
    }

    impl Foo {
        pub fn new() -> Foo { // we create a method to instantiate `Foo`
            Foo { a: 0, b: 0 }
        }
    }
}

let f = Bar::Foo::new(); // ok!
```
"##,

}
<|endoftext|>


<commit_before>use ini::Ini;
use std::path::PathBuf;
use std::env;

#[derive(Clone,Debug)]
pub struct Credentials {
    pub key: Option<String>,
    pub secret: Option<String>,
    path: String,
    profile: String,
}

impl<'a> Credentials {
    pub fn new() -> Credentials {
        Credentials{
            key: None,
            secret: None,
            path: get_profile_path(),
            profile: get_default_profile(),
        }
    }

    pub fn path(mut self, path: &str) -> Credentials {
        self.path = get_absolute_path(path);
        self
    }

    pub fn profile(mut self, profile: &str) -> Credentials {
        self.profile = String::from(profile);
        self
    }

    pub fn load(mut self) -> Credentials {
        let mut conf = Ini::load_from_file(&self.path).unwrap();
        conf.begin_section(&self.profile);
        let key = conf.get("aws_access_key_id").unwrap();
        let secret = conf.get("aws_secret_access_key").unwrap();

        self.key = Some(key.to_string());
        self.secret = Some(secret.to_string());
        self
    }
}

fn get_default_profile() -> String {
    match env::var("AWS_PROFILE") {
        Err(_) => "default".to_string(),
        Ok(s) => s.to_string(),
    }
}

fn get_profile_path() -> String {
    let home = match env::var("HOME") {
        // hell if i know what not having home set means
        Err(_) => "/root".to_string(),
        Ok(s) => s,
    };
    let mut p = PathBuf::from(&home);
    p.push(".aws");
    p.push("credentials");
    p.to_str().unwrap().to_string()
}

fn get_absolute_path(val: &str) -> String {
    let mut p = PathBuf::from(val);
    if !p.is_absolute() {
        p = env::current_dir().unwrap();
        p.push(val);
    }
    p.to_str().unwrap().to_string()
}

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

    #[test]
    fn test_defaults() {
        let cred = Credentials::new().path("/my/credentials/file");
        assert_eq!(cred.path, "/my/credentials/file")
    }

    #[test]
    fn test_profile() {
        let cred = Credentials::new().profile("new");
        assert_eq!(cred.profile, "new")
    }

    #[test]
    fn test_load_default() {
        // the path is relative from where cargo is running, so the root of the project
        let cred = Credentials::new().path("fixtures/credentials.ini").load();
        assert_eq!(cred.key.unwrap(), "12345")
    }

    #[test]
    fn test_load_specific() {
        let cred = Credentials::new().path("fixtures/credentials.ini").profile("first").load();
        assert_eq!(cred.key.unwrap(), "zxspectrum")
    }
}
<commit_msg>Update to new rust-ini api<commit_after>use ini::Ini;
use std::path::PathBuf;
use std::env;

#[derive(Clone,Debug)]
pub struct Credentials {
    pub key: Option<String>,
    pub secret: Option<String>,
    path: String,
    profile: String,
}

impl<'a> Credentials {
    pub fn new() -> Credentials {
        Credentials{
            key: None,
            secret: None,
            path: get_profile_path(),
            profile: get_default_profile(),
        }
    }

    pub fn path(mut self, path: &str) -> Credentials {
        self.path = get_absolute_path(path);
        self
    }

    pub fn profile(mut self, profile: &str) -> Credentials {
        self.profile = String::from(profile);
        self
    }

    pub fn load(mut self) -> Credentials {
        let conf = Ini::load_from_file(&self.path).unwrap();
        let section = conf.section(Some(&self.profile)).unwrap();
        let key = section.get("aws_access_key_id").unwrap();
        let secret = section.get("aws_secret_access_key").unwrap();

        self.key = Some(key.to_string());
        self.secret = Some(secret.to_string());
        self
    }
}

fn get_default_profile() -> String {
    match env::var("AWS_PROFILE") {
        Err(_) => "default".to_string(),
        Ok(s) => s.to_string(),
    }
}

fn get_profile_path() -> String {
    let home = match env::var("HOME") {
        // hell if i know what not having home set means
        Err(_) => "/root".to_string(),
        Ok(s) => s,
    };
    let mut p = PathBuf::from(&home);
    p.push(".aws");
    p.push("credentials");
    p.to_str().unwrap().to_string()
}

fn get_absolute_path(val: &str) -> String {
    let mut p = PathBuf::from(val);
    if !p.is_absolute() {
        p = env::current_dir().unwrap();
        p.push(val);
    }
    p.to_str().unwrap().to_string()
}

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

    #[test]
    fn test_defaults() {
        let cred = Credentials::new().path("/my/credentials/file");
        assert_eq!(cred.path, "/my/credentials/file")
    }

    #[test]
    fn test_profile() {
        let cred = Credentials::new().profile("new");
        assert_eq!(cred.profile, "new")
    }

    #[test]
    fn test_load_default() {
        // the path is relative from where cargo is running, so the root of the project
        let cred = Credentials::new().path("fixtures/credentials.ini").load();
        assert_eq!(cred.key.unwrap(), "12345")
    }

    #[test]
    fn test_load_specific() {
        let cred = Credentials::new().path("fixtures/credentials.ini").profile("first").load();
        assert_eq!(cred.key.unwrap(), "zxspectrum")
    }
}
<|endoftext|>


<commit_before>// vim: tw=80
use super::*;

use crate::{
    mock_function::MockFunction,
    mockable_item::{MockableItem, MockableModule}
};

/// A Mock item
pub(crate) enum MockItem {
    Module(MockItemModule),
    Struct(MockItemStruct)
}

impl From<MockableItem> for MockItem {
    fn from(mockable: MockableItem) -> MockItem {
        match mockable {
            MockableItem::Struct(s) => MockItem::Struct(
                MockItemStruct::from(s)
            ),
            MockableItem::Module(mod_) => MockItem::Module(
                MockItemModule::from(mod_)
            )
        }
    }
}

impl ToTokens for MockItem {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        match self {
            MockItem::Module(mod_) => mod_.to_tokens(tokens),
            MockItem::Struct(s) => s.to_tokens(tokens)
        }
    }
}

enum MockItemContent {
    Fn(MockFunction),
    Tokens(TokenStream)
}

pub(crate) struct MockItemModule {
    vis: Visibility,
    mock_ident: Ident,
    orig_ident: Option<Ident>,
    content: Vec<MockItemContent>
}

fn mock_fn(item_fn: ItemFn) -> ItemMod {
    let ident = format_ident!("__{}", item_fn.sig.ident);
    unimplemented!("5")
}

/// Generate a whole mod module from the mockable sort
impl From<MockableModule> for ItemMod {
    fn from(mod_: MockableModule) -> ItemMod {
        let attrs = Vec::new();
        let vis = mod_.vis;
        let mod_token = mod_.mod_token;
        let ident = mod_.mock_ident;
        let semi = None;
        let brace = token::Brace::default();

        let mut contents = Vec::<Item>::new();
        contents.push(Item::Verbatim(quote!(use super::T;)));   // TODO
        for item in mod_.content.into_iter() {
            match item {
                Item::Fn(item_fn) => {
                    contents.push(
                        Item::Verbatim(quote!(#[allow(missing_docs)]))
                    );
                    contents.push(Item::Mod(mock_fn(item_fn)));
                },
                _ => {
                    compile_error(item.span(),
                        "Unsupported item type when mocking modules");
                }
            }
        }

        let content = Some((brace, contents));
        ItemMod {
            attrs,
            vis,
            mod_token,
            ident,
            content,
            semi
        }
    }
}

impl From<MockableModule> for MockItemModule {
    fn from(mod_: MockableModule) -> MockItemModule {
        let mock_ident = mod_.mock_ident.clone();
        let orig_ident = mod_.orig_ident;
        let content = mod_.content.into_iter().filter_map(|item| {
            let span = item.span();
            match item {
                Item::ExternCrate(_) | Item::Impl(_) =>
                {
                    // Ignore
                    None
                },
                Item::Static(is) => {
                    Some(MockItemContent::Tokens(is.into_token_stream()))
                },
                Item::Const(ic) => {
                    Some(MockItemContent::Tokens(ic.into_token_stream()))
                },
                Item::Fn(f) => {
                    let mf = mock_function::Builder::new(&f.sig, &f.vis)
                        .attrs(&f.attrs)
                        .parent(&mock_ident)
                        .levels(1)
                        .call_levels(1)
                        .build();
                    Some(MockItemContent::Fn(mf))
                },
                Item::Mod(_) | Item::ForeignMod(_)
                    | Item::Struct(_) | Item::Enum(_)
                    | Item::Union(_) | Item::Trait(_) =>
                {
                    compile_error(span,
                        "Mockall does not yet support deriving nested mocks");
                    None
                },
                Item::Type(ty) => {
                    Some(MockItemContent::Tokens(ty.into_token_stream()))
                },
                Item::TraitAlias(ta) => {
                    Some(MockItemContent::Tokens(ta.into_token_stream()))
                },
                Item::Use(u) => {
                    Some(MockItemContent::Tokens(u.into_token_stream()))
                },
                _ => {
                    compile_error(span, "Unsupported item");
                    None
                }
            }
        }).collect::<Vec<_>>();

        MockItemModule {
            vis: mod_.vis,
            mock_ident: mod_.mock_ident,
            orig_ident,
            content
        }
    }
}

impl ToTokens for MockItemModule {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let mut body = TokenStream::new();
        let mut cp_body = TokenStream::new();
        let modname = &self.mock_ident;

        for item in self.content.iter() {
            match item {
                MockItemContent::Tokens(ts) => ts.to_tokens(&mut body),
                MockItemContent::Fn(f) => {
                    let call = f.call();
                    let ctx_fn = f.context_fn();
                    let priv_mod = f.priv_module();
                    quote!(
                        #priv_mod
                        #call
                        #ctx_fn
                    ).to_tokens(&mut body);
                    f.checkpoint().to_tokens(&mut cp_body);
                },
            }
        }

        quote!(
            /// Verify that all current expectations for this function are
            /// satisfied and clear them.
            pub fn checkpoint() { #cp_body }
        ).to_tokens(&mut body);
        let docstr = {
            let inner_ds = if let Some(ident) = &self.orig_ident {
                format!("Mock version of the `{}` module", ident)
            } else {
                format!("TODO: write doc string")
            };
            quote!( #[doc = #inner_ds])
        };
        quote!(
            #docstr
            pub mod #modname { #body }
        ).to_tokens(tokens);
    }
}
<commit_msg>Slight fixes to formatting of mocks of foreign functions<commit_after>// vim: tw=80
use super::*;

use crate::{
    mock_function::MockFunction,
    mockable_item::{MockableItem, MockableModule}
};

/// A Mock item
pub(crate) enum MockItem {
    Module(MockItemModule),
    Struct(MockItemStruct)
}

impl From<MockableItem> for MockItem {
    fn from(mockable: MockableItem) -> MockItem {
        match mockable {
            MockableItem::Struct(s) => MockItem::Struct(
                MockItemStruct::from(s)
            ),
            MockableItem::Module(mod_) => MockItem::Module(
                MockItemModule::from(mod_)
            )
        }
    }
}

impl ToTokens for MockItem {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        match self {
            MockItem::Module(mod_) => mod_.to_tokens(tokens),
            MockItem::Struct(s) => s.to_tokens(tokens)
        }
    }
}

enum MockItemContent {
    Fn(MockFunction),
    Tokens(TokenStream)
}

pub(crate) struct MockItemModule {
    vis: Visibility,
    mock_ident: Ident,
    orig_ident: Option<Ident>,
    content: Vec<MockItemContent>
}

fn mock_fn(item_fn: ItemFn) -> ItemMod {
    let ident = format_ident!("__{}", item_fn.sig.ident);
    unimplemented!("5")
}

/// Generate a whole mod module from the mockable sort
impl From<MockableModule> for ItemMod {
    fn from(mod_: MockableModule) -> ItemMod {
        let attrs = Vec::new();
        let vis = mod_.vis;
        let mod_token = mod_.mod_token;
        let ident = mod_.mock_ident;
        let semi = None;
        let brace = token::Brace::default();

        let mut contents = Vec::<Item>::new();
        contents.push(Item::Verbatim(quote!(use super::T;)));   // TODO
        for item in mod_.content.into_iter() {
            match item {
                Item::Fn(item_fn) => {
                    contents.push(
                        Item::Verbatim(quote!(#[allow(missing_docs)]))
                    );
                    contents.push(Item::Mod(mock_fn(item_fn)));
                },
                _ => {
                    compile_error(item.span(),
                        "Unsupported item type when mocking modules");
                }
            }
        }

        let content = Some((brace, contents));
        ItemMod {
            attrs,
            vis,
            mod_token,
            ident,
            content,
            semi
        }
    }
}

impl From<MockableModule> for MockItemModule {
    fn from(mod_: MockableModule) -> MockItemModule {
        let mock_ident = mod_.mock_ident.clone();
        let orig_ident = mod_.orig_ident;
        let content = mod_.content.into_iter().filter_map(|item| {
            let span = item.span();
            match item {
                Item::ExternCrate(_) | Item::Impl(_) =>
                {
                    // Ignore
                    None
                },
                Item::Static(is) => {
                    Some(MockItemContent::Tokens(is.into_token_stream()))
                },
                Item::Const(ic) => {
                    Some(MockItemContent::Tokens(ic.into_token_stream()))
                },
                Item::Fn(f) => {
                    let mf = mock_function::Builder::new(&f.sig, &f.vis)
                        .attrs(&f.attrs)
                        .parent(&mock_ident)
                        .levels(1)
                        .call_levels(1)
                        .build();
                    Some(MockItemContent::Fn(mf))
                },
                Item::Mod(_) | Item::ForeignMod(_)
                    | Item::Struct(_) | Item::Enum(_)
                    | Item::Union(_) | Item::Trait(_) =>
                {
                    compile_error(span,
                        "Mockall does not yet support deriving nested mocks");
                    None
                },
                Item::Type(ty) => {
                    Some(MockItemContent::Tokens(ty.into_token_stream()))
                },
                Item::TraitAlias(ta) => {
                    Some(MockItemContent::Tokens(ta.into_token_stream()))
                },
                Item::Use(u) => {
                    Some(MockItemContent::Tokens(u.into_token_stream()))
                },
                _ => {
                    compile_error(span, "Unsupported item");
                    None
                }
            }
        }).collect::<Vec<_>>();

        MockItemModule {
            vis: mod_.vis,
            mock_ident: mod_.mock_ident,
            orig_ident,
            content
        }
    }
}

impl ToTokens for MockItemModule {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let mut body = TokenStream::new();
        let mut cp_body = TokenStream::new();
        let modname = &self.mock_ident;

        for item in self.content.iter() {
            match item {
                MockItemContent::Tokens(ts) => ts.to_tokens(&mut body),
                MockItemContent::Fn(f) => {
                    let call = f.call();
                    let ctx_fn = f.context_fn();
                    let priv_mod = f.priv_module();
                    quote!(
                        #priv_mod
                        #call
                        #ctx_fn
                    ).to_tokens(&mut body);
                    f.checkpoint().to_tokens(&mut cp_body);
                },
            }
        }

        quote!(
            /// Verify that all current expectations for this function are
            /// satisfied and clear them.
            pub fn checkpoint() { #cp_body }
        ).to_tokens(&mut body);
        let docstr = {
            if let Some(ident) = &self.orig_ident {
                let inner = format!("Mock version of the `{}` module", ident);
                quote!( #[doc = #inner])
            } else {
                // TODO: write doc string
                quote!(#[allow(missing_docs)])
            }
        };
        quote!(
            #docstr
            pub mod #modname {
                #body
        }).to_tokens(tokens);
    }
}
<|endoftext|>


<commit_before>
//! Glyph caching

use error::Error;
use freetype::ffi;
use freetype;
use freetype::error::Error::MissingFontField;
use Texture;
use std::collections::HashMap;
use std::collections::hash_map::{Occupied, Vacant};

pub type FontSize = u32;

/// Holds rendered character data.
pub struct Character {
    /// The offset of character to the left.
    pub offset: [f64, ..2],
    /// The size of character, including space.
    pub size: [f64, ..2],
    /// The texture of the character.
    pub texture: Texture,
}

impl Character {
    /// The left offset.
    pub fn left(&self) -> f64 {
        self.offset[0]
    }

    /// The top offset.
    pub fn top(&self) -> f64 {
        self.offset[1]
    }

    /// Gets width of character, including space to the next one.
    pub fn width(&self) -> f64 {
        self.size[0]
    }

    /// Sets height of character, including space to the next one.
    pub fn height(&self) -> f64 {
        self.size[1]
    }
}

/// A struct used for caching rendered font.
pub struct GlyphCache {
    /// The font face.
    pub face: freetype::Face,
    data: HashMap<FontSize, HashMap<char, Character>>,
}

impl GlyphCache {

    /// Constructor for a GlyphCache.
    pub fn new(font: &Path) -> Result<GlyphCache, Error> {
        let freetype = match freetype::Library::init() {
            Ok(freetype) => freetype,
            Err(why) => return Err(Error::FreetypeError(why)),
        };
        let font_str = match font.as_str() {
            Some(font_str) => font_str,
            None => return Err(Error::FreetypeError(MissingFontField)),
        };
        let face = match freetype.new_face(font_str, 0) {
            Ok(face) => face,
            Err(why) => return Err(Error::FreetypeError(why)),
        };
        Ok(GlyphCache {
            face: face,
            data: HashMap::new(),
        })
    }

    /// Return a reference to a `Character`. If there is not yet a `Character` for
    /// the given `FontSize` and `char`, load the `Character`.
    pub fn get_character(&mut self, size: FontSize, ch: char) -> &Character {
        match {
            match self.data.entry(size) {
                Vacant(entry) => entry.set(HashMap::new()),
                Occupied(entry) => entry.into_mut(),
            }
        }.contains_key(&ch) {
            true => &self.data[size][ch],
            false => { self.load_character(size, ch); &self.data[size][ch] }
        }
    }

    /// Load a `Character` from a given `FontSize` and `char`.
    fn load_character(&mut self, size: FontSize, ch: char) {
        self.face.set_pixel_sizes(0, size).unwrap();
        self.face.load_char(ch as ffi::FT_ULong, freetype::face::DEFAULT).unwrap();
        let glyph = self.face.glyph().get_glyph().unwrap();
        let bitmap_glyph = glyph.to_bitmap(freetype::render_mode::RenderMode::Normal, None)
            .unwrap();
        let bitmap = bitmap_glyph.bitmap();
        let texture = Texture::from_memory_alpha(bitmap.buffer(),
                                                 bitmap.width() as u32,
                                                 bitmap.rows() as u32).unwrap();
        let glyph_size = glyph.advance();
        self.data[size].insert(ch, Character {
            offset: [
                    bitmap_glyph.left() as f64,
                    bitmap_glyph.top() as f64
                ],
            size: [
                    (glyph_size.x >> 16) as f64,
                    (glyph_size.y >> 16) as f64
                ],
            texture: texture,
        });
    }

}
<commit_msg>Use type alias to `Character` in graphics<commit_after>
//! Glyph caching

use error::Error;
use freetype::ffi;
use freetype;
use freetype::error::Error::MissingFontField;
use std::collections::HashMap;
use std::collections::hash_map::{Occupied, Vacant};
use graphics;

use Texture;

pub type FontSize = u32;

pub type Character = graphics::character::Character<Texture>;

/// A struct used for caching rendered font.
pub struct GlyphCache {
    /// The font face.
    pub face: freetype::Face,
    data: HashMap<FontSize, HashMap<char, Character>>,
}

impl GlyphCache {

    /// Constructor for a GlyphCache.
    pub fn new(font: &Path) -> Result<GlyphCache, Error> {
        let freetype = match freetype::Library::init() {
            Ok(freetype) => freetype,
            Err(why) => return Err(Error::FreetypeError(why)),
        };
        let font_str = match font.as_str() {
            Some(font_str) => font_str,
            None => return Err(Error::FreetypeError(MissingFontField)),
        };
        let face = match freetype.new_face(font_str, 0) {
            Ok(face) => face,
            Err(why) => return Err(Error::FreetypeError(why)),
        };
        Ok(GlyphCache {
            face: face,
            data: HashMap::new(),
        })
    }

    /// Return a reference to a `Character`. If there is not yet a `Character` for
    /// the given `FontSize` and `char`, load the `Character`.
    pub fn get_character(&mut self, size: FontSize, ch: char) -> &Character {
        match {
            match self.data.entry(size) {
                Vacant(entry) => entry.set(HashMap::new()),
                Occupied(entry) => entry.into_mut(),
            }
        }.contains_key(&ch) {
            true => &self.data[size][ch],
            false => { self.load_character(size, ch); &self.data[size][ch] }
        }
    }

    /// Load a `Character` from a given `FontSize` and `char`.
    fn load_character(&mut self, size: FontSize, ch: char) {
        self.face.set_pixel_sizes(0, size).unwrap();
        self.face.load_char(ch as ffi::FT_ULong, freetype::face::DEFAULT).unwrap();
        let glyph = self.face.glyph().get_glyph().unwrap();
        let bitmap_glyph = glyph.to_bitmap(freetype::render_mode::RenderMode::Normal, None)
            .unwrap();
        let bitmap = bitmap_glyph.bitmap();
        let texture = Texture::from_memory_alpha(bitmap.buffer(),
                                                 bitmap.width() as u32,
                                                 bitmap.rows() as u32).unwrap();
        let glyph_size = glyph.advance();
        self.data[size].insert(ch, Character {
            offset: [
                    bitmap_glyph.left() as f64,
                    bitmap_glyph.top() as f64
                ],
            size: [
                    (glyph_size.x >> 16) as f64,
                    (glyph_size.y >> 16) as f64
                ],
            texture: texture,
        });
    }

}
<|endoftext|>


<commit_before>extern crate thunderdome;

#[cfg(test)]
mod traversal_tests {

    use thunderdome::graph::*;
    use thunderdome::path::Element;

    fn simple_graph() -> Box<Graph> {
        let mut g = Graph::new();
        let mut jon = g.add_vertex();
		let mut blake = g.add_vertex();
		let mut caleb = g.add_vertex();
		let mut mike = g.add_vertex();

		jon.add_edge(&mut blake, "friend");
		jon.add_edge(&mut caleb, "friend");
		blake.add_edge(&mut caleb, "friend");
		blake.add_edge(&mut jon, "tried_to_murder");

		jon.add_edge(&mut mike, "enemy");
        g
    }

    #[test]
    fn test_get_vertex() {
        let mut g = Graph::new();
        let vertex = g.add_vertex();
        let v = g.get(1).unwrap();
        assert_eq!(v.id, 1);
    }

    #[test]
    fn test_graph_query_off_vertex() {
        let mut g = Graph::new();
        let vertex = g.add_vertex();
        let query = g.v(1);
    }

    #[test]
    fn test_traversal_map() {
        let mut g = Graph::new();
        let mut vertex = g.add_vertex();
		let mut vertex2 = g.add_vertex();
		vertex.add_edge(&mut vertex2, "test");

        let result = g.v(1).outV(&["test"]);

		assert_eq!(result.paths.len(), 1);

        let result2 = g.v(1).outV(&["likes"]);
		assert_eq!(result2.paths.len(), 0);
    }

	#[test]
	fn test_vertex_outv() {
		let mut g = Graph::new();
		let mut vertex = g.add_vertex();
		let mut vertex2 = g.add_vertex();

		vertex.add_edge(&mut vertex2, "test");

		let result = vertex.outV(&["test"]);
		assert_eq!(1, result.len());

		// add another edge, check length
		let mut vertex3 = g.add_vertex();
		vertex.add_edge(&mut vertex3, "test");

		let result = vertex.outV(&["test"]);
		assert_eq!(2, result.len());

		let result = g.v(1).outV(&["test"]);

	}

    #[test]
    fn test_real_out_vertex_execution() {
        let mut g = simple_graph();

        let result: GraphQueryResult = g.execute("g.v(1)").unwrap();
        // tree should have a root, then a single child
        let x = result.tree.children.unwrap();
        assert!(x.len() == 1);

        let result = g.execute("g.v(1).outV('friend')").unwrap();
    }

}
<commit_msg>test showing we get the right vertex back<commit_after>extern crate thunderdome;

#[cfg(test)]
mod traversal_tests {

    use thunderdome::graph::*;
    use thunderdome::path::Element;

    fn simple_graph() -> Box<Graph> {
        let mut g = Graph::new();
        let mut jon = g.add_vertex();
		let mut blake = g.add_vertex();
		let mut caleb = g.add_vertex();
		let mut mike = g.add_vertex();

		jon.add_edge(&mut blake, "friend");
		jon.add_edge(&mut caleb, "friend");
		blake.add_edge(&mut caleb, "friend");
		blake.add_edge(&mut jon, "tried_to_murder");

		jon.add_edge(&mut mike, "enemy");
        g
    }

    #[test]
    fn test_get_vertex() {
        let mut g = Graph::new();
        let vertex = g.add_vertex();
        let v = g.get(1).unwrap();
        assert_eq!(v.id, 1);
    }

    #[test]
    fn test_graph_query_off_vertex() {
        let mut g = Graph::new();
        let vertex = g.add_vertex();
        let query = g.v(1);
    }

    #[test]
    fn test_traversal_map() {
        let mut g = Graph::new();
        let mut vertex = g.add_vertex();
		let mut vertex2 = g.add_vertex();
		vertex.add_edge(&mut vertex2, "test");

        let result = g.v(1).outV(&["test"]);

		assert_eq!(result.paths.len(), 1);

        let result2 = g.v(1).outV(&["likes"]);
		assert_eq!(result2.paths.len(), 0);
    }

	#[test]
	fn test_vertex_outv() {
		let mut g = Graph::new();
		let mut vertex = g.add_vertex();
		let mut vertex2 = g.add_vertex();

		vertex.add_edge(&mut vertex2, "test");

		let result = vertex.outV(&["test"]);
		assert_eq!(1, result.len());

		// add another edge, check length
		let mut vertex3 = g.add_vertex();
		vertex.add_edge(&mut vertex3, "test");

		let result = vertex.outV(&["test"]);
		assert_eq!(2, result.len());

		let result = g.v(1).outV(&["test"]);

	}

    #[test]
    fn test_real_out_vertex_execution() {
        let mut g = simple_graph();

        let result: GraphQueryResult = g.execute("g.v(1)").unwrap();
        // tree should have a root, then a single child
        let x = result.tree.children.unwrap();
        assert!(x.len() == 1);

        let result = g.execute("g.v(1).outV('friend')").unwrap();

        let x = result.tree.children.unwrap();
        // should have a single child - the 1
        assert_eq!(x.len(), 1);
        let ref e = x.get(0).unwrap().element;
        match *e {
            Element::Vertex(vertex) =>
                assert_eq!(vertex.id, 1),
            _ =>
                panic!("WRONG")
        };
        // assert_eq!(x.element, Element::Vertex);
        // let friends = x.children.unwrap();

    }

}
<|endoftext|>


<commit_before>//! HTTP Request message related code.
use std::{str, fmt};
use std::collections::HashMap;
use bytes::BytesMut;
use futures::{Async, Future, Stream, Poll};
use url::form_urlencoded;
use http::{header, Method, Version, HeaderMap, Extensions};

use {Cookie, CookieParseError};
use {HttpRange, HttpRangeParseError};
use error::ParseError;
use recognizer::Params;
use payload::{Payload, PayloadError};
use multipart::{Multipart, MultipartError};

/// An HTTP Request
pub struct HttpRequest {
    version: Version,
    method: Method,
    path: String,
    query: String,
    headers: HeaderMap,
    params: Params,
    cookies: Vec<Cookie<'static>>,
    extensions: Extensions,
}

impl HttpRequest {
    /// Construct a new Request.
    #[inline]
    pub fn new(method: Method, path: String,
               version: Version, headers: HeaderMap, query: String) -> Self
    {
        HttpRequest {
            method: method,
            path: path,
            query: query,
            version: version,
            headers: headers,
            params: Params::empty(),
            cookies: Vec::new(),
            extensions: Extensions::new(),
        }
    }

    pub(crate) fn for_error() -> HttpRequest {
        HttpRequest {
            method: Method::GET,
            path: String::new(),
            query: String::new(),
            version: Version::HTTP_11,
            headers: HeaderMap::new(),
            params: Params::empty(),
            cookies: Vec::new(),
            extensions: Extensions::new(),
        }
    }

    /// Protocol extensions.
    #[inline]
    pub fn extensions(&mut self) -> &mut Extensions {
        &mut self.extensions
    }

    /// Read the Request method.
    #[inline]
    pub fn method(&self) -> &Method { &self.method }

    /// Read the Request Version.
    pub fn version(&self) -> Version {
        self.version
    }

    /// Read the Request Headers.
    pub fn headers(&self) -> &HeaderMap {
        &self.headers
    }

    /// The target path of this Request.
    #[inline]
    pub fn path(&self) -> &str {
        &self.path
    }

    /// Return a new iterator that yields pairs of `Cow<str>` for query parameters
    #[inline]
    pub fn query(&self) -> HashMap<String, String> {
        let mut q: HashMap<String, String> = HashMap::new();
        for (key, val) in form_urlencoded::parse(self.query.as_ref()) {
            q.insert(key.to_string(), val.to_string());
        }
        q
    }

    /// The query string in the URL.
    ///
    /// E.g., id=10
    #[inline]
    pub fn query_string(&self) -> &str {
        &self.query
    }

    /// Return request cookies.
    pub fn cookies(&self) -> &Vec<Cookie<'static>> {
        &self.cookies
    }

    /// Return request cookie.
    pub fn cookie(&self, name: &str) -> Option<&Cookie> {
        for cookie in &self.cookies {
            if cookie.name() == name {
                return Some(cookie)
            }
        }
        None
    }

    /// Load cookies
    pub fn load_cookies(&mut self) -> Result<&Vec<Cookie>, CookieParseError>
    {
        if let Some(val) = self.headers.get(header::COOKIE) {
            let s = str::from_utf8(val.as_bytes())
                .map_err(CookieParseError::from)?;
            for cookie in s.split("; ") {
                self.cookies.push(Cookie::parse_encoded(cookie)?.into_owned());
            }
        }
        Ok(&self.cookies)
    }

    /// Get a reference to the Params object.
    /// Params is a container for url parameters.
    /// Route supports glob patterns: * for a single wildcard segment and :param
    /// for matching storing that segment of the request url in the Params object.
    #[inline]
    pub fn match_info(&self) -> &Params { &self.params }

    /// Set request Params.
    pub fn set_match_info(&mut self, params: Params) {
        self.params = params;
    }

    /// Checks if a connection should be kept alive.
    pub fn keep_alive(&self) -> bool {
        if let Some(conn) = self.headers.get(header::CONNECTION) {
            if let Ok(conn) = conn.to_str() {
                if self.version == Version::HTTP_10 && conn.contains("keep-alive") {
                    true
                } else {
                    self.version == Version::HTTP_11 &&
                        !(conn.contains("close") || conn.contains("upgrade"))
                }
            } else {
                false
            }
        } else {
            self.version != Version::HTTP_10
        }
    }

    /// Read the request content type
    pub fn content_type(&self) -> &str {
        if let Some(content_type) = self.headers.get(header::CONTENT_TYPE) {
            if let Ok(content_type) = content_type.to_str() {
                return content_type
            }
        }
        ""
    }

    /// Check if request requires connection upgrade
    pub(crate) fn upgrade(&self) -> bool {
        if let Some(conn) = self.headers().get(header::CONNECTION) {
            if let Ok(s) = conn.to_str() {
                return s.to_lowercase().contains("upgrade")
            }
        }
        self.method == Method::CONNECT
    }

    /// Check if request has chunked transfer encoding
    pub fn chunked(&self) -> Result<bool, ParseError> {
        if let Some(encodings) = self.headers().get(header::TRANSFER_ENCODING) {
            if let Ok(s) = encodings.to_str() {
                Ok(s.to_lowercase().contains("chunked"))
            } else {
                Err(ParseError::Header)
            }
        } else {
            Ok(false)
        }
    }

    /// Parses Range HTTP header string as per RFC 2616.
    /// `size` is full size of response (file).
    pub fn range(&self, size: u64) -> Result<Vec<HttpRange>, HttpRangeParseError> {
        if let Some(range) = self.headers().get(header::RANGE) {
            HttpRange::parse(unsafe{str::from_utf8_unchecked(range.as_bytes())}, size)
        } else {
            Ok(Vec::new())
        }
    }

    /// Return stream to process BODY as multipart.
    ///
    /// Content-type: multipart/form-data;
    pub fn multipart(&self, payload: Payload) -> Result<Multipart, MultipartError> {
        Ok(Multipart::new(Multipart::boundary(&self.headers)?, payload))
    }

    /// Parse `application/x-www-form-urlencoded` encoded body.
    /// Return `UrlEncoded` future. It resolves to a `HashMap<String, String>` which
    /// contains decoded parameters.
    ///
    /// Returns error:
    ///
    /// * content type is not `application/x-www-form-urlencoded`
    /// * transfer encoding is `chunked`.
    /// * content-length is greater than 256k
    pub fn urlencoded(&self, payload: Payload) -> Result<UrlEncoded, Payload> {
        if let Ok(chunked) = self.chunked() {
            if chunked {
                return Err(payload)
            }
        }

        if let Some(len) = self.headers().get(header::CONTENT_LENGTH) {
            if let Ok(s) = len.to_str() {
                if let Ok(len) = s.parse::<u64>() {
                    if len > 262_144 {
                        return Err(payload)
                    }
                } else {
                    return Err(payload)
                }
            } else {
                return Err(payload)
            }
        }

        if let Some(content_type) = self.headers().get(header::CONTENT_TYPE) {
            if let Ok(content_type) = content_type.to_str() {
                if content_type.to_lowercase() == "application/x-www-form-urlencoded" {
                    return Ok(UrlEncoded{pl: payload, body: BytesMut::new()})
                }
            }
        }

        Err(payload)
    }
}

impl fmt::Debug for HttpRequest {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let res = write!(f, "\nHttpRequest {:?} {}:{}\n",
                         self.version, self.method, self.path);
        if !self.query_string().is_empty() {
            let _ = write!(f, "  query: ?{:?}\n", self.query_string());
        }
        if !self.params.is_empty() {
            let _ = write!(f, "  params: {:?}\n", self.params);
        }
        let _ = write!(f, "  headers:\n");
        for key in self.headers.keys() {
            let vals: Vec<_> = self.headers.get_all(key).iter().collect();
            if vals.len() > 1 {
                let _ = write!(f, "    {:?}: {:?}\n", key, vals);
            } else {
                let _ = write!(f, "    {:?}: {:?}\n", key, vals[0]);
            }
        }
        res
    }
}

/// Future that resolves to a parsed urlencoded values.
pub struct UrlEncoded {
    pl: Payload,
    body: BytesMut,
}

impl Future for UrlEncoded {
    type Item = HashMap<String, String>;
    type Error = PayloadError;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        loop {
            return match self.pl.poll() {
                Ok(Async::NotReady) => Ok(Async::NotReady),
                Ok(Async::Ready(None)) => {
                    let mut m = HashMap::new();
                    for (k, v) in form_urlencoded::parse(&self.body) {
                        m.insert(k.into(), v.into());
                    }
                    Ok(Async::Ready(m))
                },
                Ok(Async::Ready(Some(item))) => {
                    self.body.extend(item.0);
                    continue
                },
                Err(err) => Err(err),
            }
        }
    }
}

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

    #[test]
    fn test_urlencoded_error() {
        let mut headers = HeaderMap::new();
        headers.insert(header::TRANSFER_ENCODING,
                       header::HeaderValue::from_static("chunked"));
        let req = HttpRequest::new(
            Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new());

        let (_, payload) = Payload::new(false);
        assert!(req.urlencoded(payload).is_err());

        let mut headers = HeaderMap::new();
        headers.insert(header::CONTENT_TYPE,
                       header::HeaderValue::from_static("application/x-www-form-urlencoded"));
        headers.insert(header::CONTENT_LENGTH,
                       header::HeaderValue::from_static("xxxx"));
        let req = HttpRequest::new(
            Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new());

        let (_, payload) = Payload::new(false);
        assert!(req.urlencoded(payload).is_err());

        let mut headers = HeaderMap::new();
        headers.insert(header::CONTENT_TYPE,
                       header::HeaderValue::from_static("application/x-www-form-urlencoded"));
        headers.insert(header::CONTENT_LENGTH,
                       header::HeaderValue::from_static("1000000"));
        let req = HttpRequest::new(
            Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new());

        let (_, payload) = Payload::new(false);
        assert!(req.urlencoded(payload).is_err());

        let mut headers = HeaderMap::new();
        headers.insert(header::CONTENT_TYPE,
                       header::HeaderValue::from_static("text/plain"));
        headers.insert(header::CONTENT_LENGTH,
                       header::HeaderValue::from_static("10"));
        let req = HttpRequest::new(
            Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new());

        let (_, payload) = Payload::new(false);
        assert!(req.urlencoded(payload).is_err());
    }

}
<commit_msg>store cookies load state<commit_after>//! HTTP Request message related code.
use std::{str, fmt};
use std::collections::HashMap;
use bytes::BytesMut;
use futures::{Async, Future, Stream, Poll};
use url::form_urlencoded;
use http::{header, Method, Version, HeaderMap, Extensions};

use {Cookie, CookieParseError};
use {HttpRange, HttpRangeParseError};
use error::ParseError;
use recognizer::Params;
use payload::{Payload, PayloadError};
use multipart::{Multipart, MultipartError};

/// An HTTP Request
pub struct HttpRequest {
    version: Version,
    method: Method,
    path: String,
    query: String,
    headers: HeaderMap,
    params: Params,
    cookies: Vec<Cookie<'static>>,
    cookies_loaded: bool,
    extensions: Extensions,
}

impl HttpRequest {
    /// Construct a new Request.
    #[inline]
    pub fn new(method: Method, path: String,
               version: Version, headers: HeaderMap, query: String) -> Self
    {
        HttpRequest {
            method: method,
            path: path,
            query: query,
            version: version,
            headers: headers,
            params: Params::empty(),
            cookies: Vec::new(),
            cookies_loaded: false,
            extensions: Extensions::new(),
        }
    }

    pub(crate) fn for_error() -> HttpRequest {
        HttpRequest {
            method: Method::GET,
            path: String::new(),
            query: String::new(),
            version: Version::HTTP_11,
            headers: HeaderMap::new(),
            params: Params::empty(),
            cookies: Vec::new(),
            cookies_loaded: false,
            extensions: Extensions::new(),
        }
    }

    /// Protocol extensions.
    #[inline]
    pub fn extensions(&mut self) -> &mut Extensions {
        &mut self.extensions
    }

    /// Read the Request method.
    #[inline]
    pub fn method(&self) -> &Method { &self.method }

    /// Read the Request Version.
    pub fn version(&self) -> Version {
        self.version
    }

    /// Read the Request Headers.
    pub fn headers(&self) -> &HeaderMap {
        &self.headers
    }

    /// The target path of this Request.
    #[inline]
    pub fn path(&self) -> &str {
        &self.path
    }

    /// Return a new iterator that yields pairs of `Cow<str>` for query parameters
    #[inline]
    pub fn query(&self) -> HashMap<String, String> {
        let mut q: HashMap<String, String> = HashMap::new();
        for (key, val) in form_urlencoded::parse(self.query.as_ref()) {
            q.insert(key.to_string(), val.to_string());
        }
        q
    }

    /// The query string in the URL.
    ///
    /// E.g., id=10
    #[inline]
    pub fn query_string(&self) -> &str {
        &self.query
    }

    /// Return request cookies.
    pub fn cookies(&self) -> &Vec<Cookie<'static>> {
        &self.cookies
    }

    /// Return request cookie.
    pub fn cookie(&self, name: &str) -> Option<&Cookie> {
        for cookie in &self.cookies {
            if cookie.name() == name {
                return Some(cookie)
            }
        }
        None
    }

    /// Load cookies
    pub fn load_cookies(&mut self) -> Result<&Vec<Cookie>, CookieParseError>
    {
        if !self.cookies_loaded {
            self.cookies_loaded = true;
            if let Some(val) = self.headers.get(header::COOKIE) {
                let s = str::from_utf8(val.as_bytes())
                    .map_err(CookieParseError::from)?;
                for cookie in s.split("; ") {
                    self.cookies.push(Cookie::parse_encoded(cookie)?.into_owned());
                }
            }
        }
        Ok(&self.cookies)
    }

    /// Get a reference to the Params object.
    /// Params is a container for url parameters.
    /// Route supports glob patterns: * for a single wildcard segment and :param
    /// for matching storing that segment of the request url in the Params object.
    #[inline]
    pub fn match_info(&self) -> &Params { &self.params }

    /// Set request Params.
    pub fn set_match_info(&mut self, params: Params) {
        self.params = params;
    }

    /// Checks if a connection should be kept alive.
    pub fn keep_alive(&self) -> bool {
        if let Some(conn) = self.headers.get(header::CONNECTION) {
            if let Ok(conn) = conn.to_str() {
                if self.version == Version::HTTP_10 && conn.contains("keep-alive") {
                    true
                } else {
                    self.version == Version::HTTP_11 &&
                        !(conn.contains("close") || conn.contains("upgrade"))
                }
            } else {
                false
            }
        } else {
            self.version != Version::HTTP_10
        }
    }

    /// Read the request content type
    pub fn content_type(&self) -> &str {
        if let Some(content_type) = self.headers.get(header::CONTENT_TYPE) {
            if let Ok(content_type) = content_type.to_str() {
                return content_type
            }
        }
        ""
    }

    /// Check if request requires connection upgrade
    pub(crate) fn upgrade(&self) -> bool {
        if let Some(conn) = self.headers().get(header::CONNECTION) {
            if let Ok(s) = conn.to_str() {
                return s.to_lowercase().contains("upgrade")
            }
        }
        self.method == Method::CONNECT
    }

    /// Check if request has chunked transfer encoding
    pub fn chunked(&self) -> Result<bool, ParseError> {
        if let Some(encodings) = self.headers().get(header::TRANSFER_ENCODING) {
            if let Ok(s) = encodings.to_str() {
                Ok(s.to_lowercase().contains("chunked"))
            } else {
                Err(ParseError::Header)
            }
        } else {
            Ok(false)
        }
    }

    /// Parses Range HTTP header string as per RFC 2616.
    /// `size` is full size of response (file).
    pub fn range(&self, size: u64) -> Result<Vec<HttpRange>, HttpRangeParseError> {
        if let Some(range) = self.headers().get(header::RANGE) {
            HttpRange::parse(unsafe{str::from_utf8_unchecked(range.as_bytes())}, size)
        } else {
            Ok(Vec::new())
        }
    }

    /// Return stream to process BODY as multipart.
    ///
    /// Content-type: multipart/form-data;
    pub fn multipart(&self, payload: Payload) -> Result<Multipart, MultipartError> {
        Ok(Multipart::new(Multipart::boundary(&self.headers)?, payload))
    }

    /// Parse `application/x-www-form-urlencoded` encoded body.
    /// Return `UrlEncoded` future. It resolves to a `HashMap<String, String>` which
    /// contains decoded parameters.
    ///
    /// Returns error:
    ///
    /// * content type is not `application/x-www-form-urlencoded`
    /// * transfer encoding is `chunked`.
    /// * content-length is greater than 256k
    pub fn urlencoded(&self, payload: Payload) -> Result<UrlEncoded, Payload> {
        if let Ok(chunked) = self.chunked() {
            if chunked {
                return Err(payload)
            }
        }

        if let Some(len) = self.headers().get(header::CONTENT_LENGTH) {
            if let Ok(s) = len.to_str() {
                if let Ok(len) = s.parse::<u64>() {
                    if len > 262_144 {
                        return Err(payload)
                    }
                } else {
                    return Err(payload)
                }
            } else {
                return Err(payload)
            }
        }

        if let Some(content_type) = self.headers().get(header::CONTENT_TYPE) {
            if let Ok(content_type) = content_type.to_str() {
                if content_type.to_lowercase() == "application/x-www-form-urlencoded" {
                    return Ok(UrlEncoded{pl: payload, body: BytesMut::new()})
                }
            }
        }

        Err(payload)
    }
}

impl fmt::Debug for HttpRequest {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let res = write!(f, "\nHttpRequest {:?} {}:{}\n",
                         self.version, self.method, self.path);
        if !self.query_string().is_empty() {
            let _ = write!(f, "  query: ?{:?}\n", self.query_string());
        }
        if !self.params.is_empty() {
            let _ = write!(f, "  params: {:?}\n", self.params);
        }
        let _ = write!(f, "  headers:\n");
        for key in self.headers.keys() {
            let vals: Vec<_> = self.headers.get_all(key).iter().collect();
            if vals.len() > 1 {
                let _ = write!(f, "    {:?}: {:?}\n", key, vals);
            } else {
                let _ = write!(f, "    {:?}: {:?}\n", key, vals[0]);
            }
        }
        res
    }
}

/// Future that resolves to a parsed urlencoded values.
pub struct UrlEncoded {
    pl: Payload,
    body: BytesMut,
}

impl Future for UrlEncoded {
    type Item = HashMap<String, String>;
    type Error = PayloadError;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        loop {
            return match self.pl.poll() {
                Ok(Async::NotReady) => Ok(Async::NotReady),
                Ok(Async::Ready(None)) => {
                    let mut m = HashMap::new();
                    for (k, v) in form_urlencoded::parse(&self.body) {
                        m.insert(k.into(), v.into());
                    }
                    Ok(Async::Ready(m))
                },
                Ok(Async::Ready(Some(item))) => {
                    self.body.extend(item.0);
                    continue
                },
                Err(err) => Err(err),
            }
        }
    }
}

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

    #[test]
    fn test_urlencoded_error() {
        let mut headers = HeaderMap::new();
        headers.insert(header::TRANSFER_ENCODING,
                       header::HeaderValue::from_static("chunked"));
        let req = HttpRequest::new(
            Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new());

        let (_, payload) = Payload::new(false);
        assert!(req.urlencoded(payload).is_err());

        let mut headers = HeaderMap::new();
        headers.insert(header::CONTENT_TYPE,
                       header::HeaderValue::from_static("application/x-www-form-urlencoded"));
        headers.insert(header::CONTENT_LENGTH,
                       header::HeaderValue::from_static("xxxx"));
        let req = HttpRequest::new(
            Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new());

        let (_, payload) = Payload::new(false);
        assert!(req.urlencoded(payload).is_err());

        let mut headers = HeaderMap::new();
        headers.insert(header::CONTENT_TYPE,
                       header::HeaderValue::from_static("application/x-www-form-urlencoded"));
        headers.insert(header::CONTENT_LENGTH,
                       header::HeaderValue::from_static("1000000"));
        let req = HttpRequest::new(
            Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new());

        let (_, payload) = Payload::new(false);
        assert!(req.urlencoded(payload).is_err());

        let mut headers = HeaderMap::new();
        headers.insert(header::CONTENT_TYPE,
                       header::HeaderValue::from_static("text/plain"));
        headers.insert(header::CONTENT_LENGTH,
                       header::HeaderValue::from_static("10"));
        let req = HttpRequest::new(
            Method::GET, "/".to_owned(), Version::HTTP_11, headers, String::new());

        let (_, payload) = Payload::new(false);
        assert!(req.urlencoded(payload).is_err());
    }

}
<|endoftext|>


<commit_before>use getopts::{getopts};
use help;

fn verify_command(command: &str) -> bool {
    match command {
        "new"  => true,
        "open" => true,
        _      => false
    }
}

fn run_command(command: &str, value: &str) {
    match command {
        "new"  => creator::new(value),
        "open" => editor::new(value)
    }
}

#[test]
fn run_command_prints_value() {
  assert_eq!(run_command("value"), false);
}

pub fn init(args: Vec<String>) {
    let program = args[0].clone();
    let opts = help::opts();

    let matches = match getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_string()) }
    };

    if matches.opt_present("h") {
        help::print_usage(program.as_slice(), opts);
        return;
    }

    let input = if !matches.free.is_empty() && !matches.free.len() == 2 {
        matches.free[0].clone()
    } else {
        help::print_usage(program.as_slice(), opts);
        return;
    };

    if !verify_command(input.as_slice()) {
        help::print_usage(program.as_slice(), opts);
        return;
    }

    run_command(input.as_slice(), matches.free[1].clone().as_slice());
}

#[test]
fn verify_command_new_returns_true() {
  assert_eq!(verify_command("new"), true);
}

#[test]
fn verify_command_open_returns_true() {
  assert_eq!(verify_command("open"), true);
}

#[test]
fn verify_command_value_returns_false() {
  assert_eq!(verify_command("value"), false);
}

<commit_msg>Rename verify_method to validate_method.<commit_after>use getopts::{getopts,OptGroup,Matches};
use help;
use creator;
use editor;

fn run_command(command: &str, value: &str) {
    match command {
        "new"  => creator::new(value),
        "open" => editor::new(value)
    }
}

#[test]
fn run_command_prints_value() {
  assert_eq!(run_command("value"), false);
}

pub fn init(args: Vec<String>) {
    let program = args[0].clone();
    let opts = help::opts();

    let matches = match getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_string()) }
    };

    if matches.opt_present("h") {
        help::print_usage(program.as_slice(), opts);
        return;
    }

    let input = if !matches.free.is_empty() && !matches.free.len() == 2 {
fn validate_command(matches: Matches) -> bool {
    let command = if matches.free.len() == 2 {
        matches.free[0].clone()
    } else {
        help::print_usage(program.as_slice(), opts);
        return;
    };

    if !verify_command(input.as_slice()) {
        help::print_usage(program.as_slice(), opts);
        return;
    return match command {
        "new"  => true,
        "open" => true,
        _      => false
    }
}

    run_command(input.as_slice(), matches.free[1].clone().as_slice());
#[test]
fn validate_command_new_returns_true() {
    let matches = get_matches([String::from_str("new muxed")], help::opts());
    assert_eq!(validate_command(matches), true);
}

#[test]
fn validate_command_open_returns_true() {
    let matches = get_matches([String::from_str("open muxed")], help::opts());
    assert_eq!(validate_command(matches), true);
}

#[test]
fn validate_command_value_returns_false() {
    let matches = get_matches([String::from_str("value")], help::opts());
    assert_eq!(validate_command(matches), false);
}

#[test]
#[should_fail]
fn get_matches_returns_failure_with_bad_opts() {
    get_matches([String::from_str("-m")], help::opts());
}

<|endoftext|>


<commit_before>use token::{Token, Kind, Tokenizer};
use ast::Node;
use parser::Parser;
use std::collections::HashMap;

// # Interpreter
//
// Represents the interpreter that is responsible for interpret
// the Abstracted Sintax Tree generated by the Parser

pub struct Interpreter {
    pub symbol_table: HashMap<String, String>
}
impl Interpreter {
    pub fn new() -> Self {
        Interpreter {
            symbol_table: HashMap::new()
        }
    }
    // eval_tree
    //
    // It visits each node evaluating the binary operations returning the
    // result as String
    //
    // Example:
    //   The expression 3 * 5 + 5 will produce the follow tree and the result 20.
    //   It evaluates the left side first and applies a post-order calc
    //
    //         +-+
    //         |-|
    //     +---------+
    //     |         |
    //     v         v
    //    +-+       +-+
    //    |*|       |5|
    //  +-----+     +-+
    //  |     |
    //  v     v
    // ---   ---
    // |3|   |5|
    // +-+   +-+
    pub fn eval_tree(&mut self, tree: Node) -> String {
        let nodes = tree.clone().nodes();
        let kind = tree.clone().kind();
        match nodes {
            (Some(lnode), Some(rnode)) => {
                match kind {
                    Kind::Operator =>
                        binary_operation(self.eval_tree(lnode),
                                         &tree.value(),
                                         self.eval_tree(rnode)).to_string(),

                    Kind::Assign => {
                        let value = self.eval_tree(rnode);
                        self.assign_variable(lnode.value(), value)
                    },

                    _ => panic!("Interpreter error: unexpecte node kind {:?}",
                                tree)
                }
            },

            (Some(lnode), None) => self.eval_tree(lnode),

            (None, Some(rnode)) => match tree.clone().kind() {
                Kind::Operator =>
                    unary_operation(tree.value(), self.eval_tree(rnode)).to_string(),

                Kind::Return =>
                    self.eval_tree(rnode),
                _ => String::new()
            },

            (None, None) => {
                if let Some(statements) = tree.clone().statements {
                    return statements.iter()
                              .map(|n| self.eval_tree(n.clone()))
                              .fold(String::new(), |_, s|{
                                  s
                              })
                }

                match kind {
                    Kind::ID => self.symbol_table[&tree.value()].clone(),
                    _ => tree.value()
                }
            }
        }
    }

    fn assign_variable(&mut self, name: String, value: String) -> String {
        self.symbol_table.insert(name, value.clone());
        value
    }
}

// unary_operation
// Resolves the unary operations Example: --1 == 1, 1++-1==0
fn unary_operation(operator: String, operand: String) -> i32 {
    let ioperand = if let Ok(val) = operand.parse::<i32>() { val } else {
        panic!("Sintax error: invalid unary operand {}", operand)
    };
    match operator.as_ref() {
        "+" => ioperand,
        "-" => -(ioperand),
        _ => panic!("Sintax error: invalid unary operator {}", operator)
    }
}

// binary_operation
// Resolve binary expression for the given left, operator and right operand
fn binary_operation(operand: String, operator: &String, operand2: String) -> i32 {
    let left = if let Ok(val) = operand.parse::<i32>() { val } else {
        panic!("Sintax error: invalid operand: {}", operand)
    };
    let right = if let Ok(val) = operand2.parse::<i32>() { val } else {
        panic!("Sintax error: invalid operand: {}", operand2)
    };
    match operator.as_ref() {
        "+" => left + right,
        "-" => left - right,
        "*" => left * right,
        "/" => left / right,
        _ => panic!("Sintax error: invalid operator {}", operator)
    }
}

#[test]
fn it_eval_tree_leaf() {
    let token = Token::build(Kind::Integer, String::from("10"));
    let leaf = Node::leaf(token);

    assert_eq!("10", Interpreter::new().eval_tree(leaf))
}

#[test]
fn it_eval_the_node_binary_operation() {
    // 3+5
    let left = Node::leaf(Token::build(Kind::Integer, String::from("3")));
    let operator = Token::build(Kind::Operator, String::from("+"));
    let right = Node::leaf(Token::build(Kind::Integer, String::from("5")));
    let node = Node::new(left, operator, right);

    assert_eq!("8", Interpreter::new().eval_tree(node))
}

#[test]
fn it_eval_complex_tree() {
    // 5+5*3
    let left = Node::leaf(Token::build(Kind::Integer, String::from("3")));
    let operator = Token::build(Kind::Operator, String::from("*"));
    let right = Node::leaf(Token::build(Kind::Integer, String::from("5")));
    let plusnode = Node::new(left, operator, right);

    let operator = Token::build(Kind::Operator, String::from("+"));
    let sumright = Node::leaf(Token::build(Kind::Integer, String::from("5")));
    let sumnode = Node::new(plusnode, operator, sumright);

    assert_eq!("20", Interpreter::new().eval_tree(sumnode))
}

#[test]
fn it_eval_unary_operations() {
    // 2 -- 2
    let rnode = Node::leaf(Token::build(Kind::Integer, String::from("2")));
    let negative_op = Token::build(Kind::Operator, String::from("-"));
    let unarynode = Node::unary(negative_op, rnode);

    let operator = Token::build(Kind::Operator, String::from("-"));
    let left = Node::leaf(Token::build(Kind::Integer, String::from("2")));
    let sumnode = Node::new(left, operator, unarynode);

    assert_eq!("4", Interpreter::new().eval_tree(sumnode))
}

#[test]
fn it_sums() {
    let text = "5+1";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("6", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_substract() {
    let text = "5-1";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("4", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_multiplies() {
    let text = "5*2";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("10", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_divide() {
    let text = "4/2";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("2", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_accepts_multiples_operation() {
    let text = "10+5-4-1";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("10", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_respect_precedence() {
    let text = "1+1*2";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("3", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_respects_grouped_expression() {
    let text = "4+(1+(1+1)*2)+1";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("10", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_accept_unary_operations() {
    let text = "(4+-1)--2";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("5", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_eval_block_assigning_vars_to_symbol_table() {
    let text = "begin x = 10 end";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);
    let mut interpreter = Interpreter::new();
    let _ = interpreter.eval_tree(parser.parse());

    assert_eq!("10", interpreter.symbol_table["x"]);
}

#[test]
fn it_eval_block_retrieve_vars_from_symbol_table() {
    let text = "begin x = 10; y = x + 5 end";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);
    let mut interpreter = Interpreter::new();
    let result = interpreter.eval_tree(parser.parse());

    assert_eq!("15", interpreter.symbol_table["y"]);
}

#[test]
fn it_eval_block_retrieve_eturn_statement() {
    let text = "begin x = 10; y = x + 5; return y + 5 end";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);
    let mut interpreter = Interpreter::new();
    let result = interpreter.eval_tree(parser.parse());

    assert_eq!("20", result);
}
<commit_msg>refactor: cleaning the interpreter<commit_after>use token::{Token, Kind, Tokenizer};
use ast::Node;
use parser::Parser;
use std::collections::HashMap;

// # Interpreter
//
// Represents the interpreter that is responsible for interpret
// the Abstracted Sintax Tree generated by the Parser

pub struct Interpreter {
    pub symbol_table: HashMap<String, String>
}
impl Interpreter {
    pub fn new() -> Self {
        Interpreter {
            symbol_table: HashMap::new()
        }
    }
    // eval_tree
    //
    // It visits each node evaluating the binary operations returning the
    // result as String
    //
    // Example:
    //   The expression 3 * 5 + 5 will produce the follow tree and the result 20.
    //   It evaluates the left side first and applies a post-order calc
    //
    //         +-+
    //         |-|
    //     +---------+
    //     |         |
    //     v         v
    //    +-+       +-+
    //    |*|       |5|
    //  +-----+     +-+
    //  |     |
    //  v     v
    // ---   ---
    // |3|   |5|
    // +-+   +-+
    pub fn eval_tree(&mut self, tree: Node) -> String {
        let nodes = tree.clone().nodes();
        let kind = tree.clone().kind();
        match nodes {
            (Some(lnode), Some(rnode)) => match kind {
                Kind::Operator =>
                    binary_operation(self.eval_tree(lnode),
                                     &tree.value(),
                                     self.eval_tree(rnode)),

                Kind::Assign => {
                    let value = self.eval_tree(rnode);
                    self.assign_variable(lnode.value(), value)
                },

                _ => panic!("Interpreter error: unexpecte node kind {:?}",
                                tree)
            },

            (Some(lnode), None) => self.eval_tree(lnode),

            (None, Some(rnode)) => match tree.clone().kind() {
                Kind::Operator =>
                    unary_operation(tree.value(), self.eval_tree(rnode)),

                Kind::Return => self.eval_tree(rnode),

                _ => String::new()
            },

            (None, None) => match kind {
                Kind::Statement => {
                    return tree.clone().statements
                        .unwrap()
                        .iter()
                        .map(|n| self.eval_tree(n.clone()))
                        .fold(String::new(), |_, s|{
                            s
                        })
                },

                Kind::ID => self.symbol_table[&tree.value()].clone(),

                _ => tree.value()
            }
        }
    }

    fn assign_variable(&mut self, name: String, value: String) -> String {
        self.symbol_table.insert(name, value.clone());
        value
    }
}

// unary_operation
// Resolves the unary operations Example: --1 == 1, 1++-1==0
fn unary_operation(operator: String, operand: String) -> String {
    let ioperand = if let Ok(val) = operand.parse::<i32>() { val } else {
        panic!("Sintax error: invalid unary operand {}", operand)
    };
    let result = match operator.as_ref() {
        "+" => ioperand,
        "-" => -(ioperand),
        _ => panic!("Sintax error: invalid unary operator {}", operator)
    };

    result.to_string()
}

// binary_operation
// Resolve binary expression for the given left, operator and right operand
fn binary_operation(left: String, operator: &String, right: String) -> String {
    let operleft = if let Ok(val) = left.parse::<i32>() { val } else {
        panic!("Sintax error: invalid operand: {}", left)
    };
    let operright = if let Ok(val) = right.parse::<i32>() { val } else {
        panic!("Sintax error: invalid operand: {}", right)
    };
    let result = match operator.as_ref() {
        "+" => operleft + operright,
        "-" => operleft - operright,
        "*" => operleft * operright,
        "/" => operleft / operright,
        _ => panic!("Sintax error: invalid operator {}", operator)
    };

    result.to_string()
}

#[test]
fn it_eval_tree_leaf() {
    let token = Token::build(Kind::Integer, String::from("10"));
    let leaf = Node::leaf(token);

    assert_eq!("10", Interpreter::new().eval_tree(leaf))
}

#[test]
fn it_eval_the_node_binary_operation() {
    // 3+5
    let left = Node::leaf(Token::build(Kind::Integer, String::from("3")));
    let operator = Token::build(Kind::Operator, String::from("+"));
    let right = Node::leaf(Token::build(Kind::Integer, String::from("5")));
    let node = Node::new(left, operator, right);

    assert_eq!("8", Interpreter::new().eval_tree(node))
}

#[test]
fn it_eval_complex_tree() {
    // 5+5*3
    let left = Node::leaf(Token::build(Kind::Integer, String::from("3")));
    let operator = Token::build(Kind::Operator, String::from("*"));
    let right = Node::leaf(Token::build(Kind::Integer, String::from("5")));
    let plusnode = Node::new(left, operator, right);

    let operator = Token::build(Kind::Operator, String::from("+"));
    let sumright = Node::leaf(Token::build(Kind::Integer, String::from("5")));
    let sumnode = Node::new(plusnode, operator, sumright);

    assert_eq!("20", Interpreter::new().eval_tree(sumnode))
}

#[test]
fn it_eval_unary_operations() {
    // 2 -- 2
    let rnode = Node::leaf(Token::build(Kind::Integer, String::from("2")));
    let negative_op = Token::build(Kind::Operator, String::from("-"));
    let unarynode = Node::unary(negative_op, rnode);

    let operator = Token::build(Kind::Operator, String::from("-"));
    let left = Node::leaf(Token::build(Kind::Integer, String::from("2")));
    let sumnode = Node::new(left, operator, unarynode);

    assert_eq!("4", Interpreter::new().eval_tree(sumnode))
}

#[test]
fn it_sums() {
    let text = "5+1";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("6", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_substract() {
    let text = "5-1";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("4", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_multiplies() {
    let text = "5*2";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("10", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_divide() {
    let text = "4/2";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("2", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_accepts_multiples_operation() {
    let text = "10+5-4-1";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("10", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_respect_precedence() {
    let text = "1+1*2";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("3", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_respects_grouped_expression() {
    let text = "4+(1+(1+1)*2)+1";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("10", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_accept_unary_operations() {
    let text = "(4+-1)--2";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);

    assert_eq!("5", Interpreter::new().eval_tree(parser.parse()));
}

#[test]
fn it_eval_block_assigning_vars_to_symbol_table() {
    let text = "begin x = 10 end";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);
    let mut interpreter = Interpreter::new();
    let _ = interpreter.eval_tree(parser.parse());

    assert_eq!("10", interpreter.symbol_table["x"]);
}

#[test]
fn it_eval_block_retrieve_vars_from_symbol_table() {
    let text = "begin x = 10; y = x + 5 end";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);
    let mut interpreter = Interpreter::new();
    let result = interpreter.eval_tree(parser.parse());

    assert_eq!("15", interpreter.symbol_table["y"]);
}

#[test]
fn it_eval_block_retrieve_eturn_statement() {
    let text = "begin x = 10; y = x + 5; return y + 5 end";
    let tokenizer = Tokenizer::new(String::from(text));
    let mut parser = Parser::new(tokenizer);
    let mut interpreter = Interpreter::new();
    let result = interpreter.eval_tree(parser.parse());

    assert_eq!("20", result);
}
<|endoftext|>


<commit_before>use input::Input;
use buffer::Direction;
use keyboard::Key;
use view::View;
use frontends::{Frontend, EditorEvent};
use modes::Mode;
use overlay::{Overlay, OverlayType, OverlayEvent};
use utils;

#[derive(Copy, Show, PartialEq, Eq)]
pub enum Command {
    SaveBuffer,
    ExitEditor,

    MoveCursor(Direction, uint),
    LineEnd,
    LineStart,

    Delete(Direction, uint),
    InsertTab,
    InsertChar(char),

    SetOverlay(OverlayType),

    Undo,
    Redo,

    Unknown,
    None,
}

impl Command {
    #[inline]
    pub fn from_str(string: &str) -> Command {
        match string {
            "q" | "quit"  => Command::ExitEditor,
            "w" | "write" => Command::SaveBuffer,

            _             => Command::Unknown,
        }
    }
}

/// The main Editor structure
///
/// This is the top-most structure in Iota.
pub struct Editor<'e, T: Frontend> {
    view: View<'e>,
    running: bool,
    frontend: T,
    mode: Box<Mode + 'e>,
}

impl<'e, T: Frontend> Editor<'e, T> {
    /// Create a new Editor instance
    pub fn new(source: Input, mode: Box<Mode + 'e>, frontend: T) -> Editor<'e, T> {
        let height = frontend.get_window_height();
        let width = frontend.get_window_width();
        let view = View::new(source, width, height);

        Editor {
            view: view,
            running: true,
            frontend: frontend,
            mode: mode,
        }
    }

    /// Handle key events
    ///
    /// Key events can be handled in an Overlay, OR in the current Mode.
    ///
    /// If there is an active Overlay, the key event is sent there, which gives
    /// back an OverlayEvent. We then parse this OverlayEvent and determine if
    /// the Overlay is finished and can be cleared. The response from the
    /// Overlay is then converted to a Command and sent off to be handled.
    ///
    /// If there is no active Overlay, the key event is sent to the current
    /// Mode, which returns a Command which we dispatch to handle_command.
    fn handle_key_event(&mut self, key: Option<Key>) {
        let key = match key {
            Some(k) => k,
            None => return
        };

        let command = match self.view.overlay {
            Overlay::None => self.mode.handle_key_event(key),
            _             => {
                let event = self.view.overlay.handle_key_event(key);
                if let OverlayEvent::Finished(response) = event {
                    self.view.overlay = Overlay::None;
                    self.view.clear(&mut self.frontend);
                    if let Some(data) = response {
                        Command::from_str(&*data)
                    } else {
                        Command::None
                    }
                } else {
                    Command::None
                }
            }
        };

        self.handle_command(command);
    }

    /// Draw the current view to the frontend
    fn draw(&mut self) {
        self.view.draw(&mut self.frontend);
    }

    /// Handle the given command, performing the associated action
    fn handle_command(&mut self, command: Command) {
        if let Command::ExitEditor = command {
            self.running = false;
        }
        match command {
            // Editor Commands
            Command::SaveBuffer      => utils::save_buffer(&self.view.buffer),

            // Navigation
            Command::MoveCursor(dir, n) => self.view.move_cursor(dir, n),
            Command::LineEnd         => self.view.move_cursor_to_line_end(),
            Command::LineStart       => self.view.move_cursor_to_line_start(),

            // Editing
            Command::Delete(dir, n)     => self.view.delete_chars(dir, n),
            Command::InsertTab       => self.view.insert_tab(),
            Command::InsertChar(c)   => self.view.insert_char(c),
            Command::Redo            => self.view.redo(),
            Command::Undo            => self.view.undo(),

            Command::SetOverlay(o)   => self.view.set_overlay(o),

            _ => {},
        }
    }

    /// Start Iota!
    pub fn start(&mut self) {
        while self.running {
            self.draw();
            self.frontend.present();
            let event = self.frontend.poll_event();

            if let EditorEvent::KeyEvent(key) = event {
                self.handle_key_event(key)
            }
        }
    }
}
<commit_msg>Fixed formatting of match expression<commit_after>use input::Input;
use buffer::Direction;
use keyboard::Key;
use view::View;
use frontends::{Frontend, EditorEvent};
use modes::Mode;
use overlay::{Overlay, OverlayType, OverlayEvent};
use utils;

#[derive(Copy, Show, PartialEq, Eq)]
pub enum Command {
    SaveBuffer,
    ExitEditor,

    MoveCursor(Direction, uint),
    LineEnd,
    LineStart,

    Delete(Direction, uint),
    InsertTab,
    InsertChar(char),

    SetOverlay(OverlayType),

    Undo,
    Redo,

    Unknown,
    None,
}

impl Command {
    #[inline]
    pub fn from_str(string: &str) -> Command {
        match string {
            "q" | "quit"  => Command::ExitEditor,
            "w" | "write" => Command::SaveBuffer,

            _             => Command::Unknown,
        }
    }
}

/// The main Editor structure
///
/// This is the top-most structure in Iota.
pub struct Editor<'e, T: Frontend> {
    view: View<'e>,
    running: bool,
    frontend: T,
    mode: Box<Mode + 'e>,
}

impl<'e, T: Frontend> Editor<'e, T> {
    /// Create a new Editor instance
    pub fn new(source: Input, mode: Box<Mode + 'e>, frontend: T) -> Editor<'e, T> {
        let height = frontend.get_window_height();
        let width = frontend.get_window_width();
        let view = View::new(source, width, height);

        Editor {
            view: view,
            running: true,
            frontend: frontend,
            mode: mode,
        }
    }

    /// Handle key events
    ///
    /// Key events can be handled in an Overlay, OR in the current Mode.
    ///
    /// If there is an active Overlay, the key event is sent there, which gives
    /// back an OverlayEvent. We then parse this OverlayEvent and determine if
    /// the Overlay is finished and can be cleared. The response from the
    /// Overlay is then converted to a Command and sent off to be handled.
    ///
    /// If there is no active Overlay, the key event is sent to the current
    /// Mode, which returns a Command which we dispatch to handle_command.
    fn handle_key_event(&mut self, key: Option<Key>) {
        let key = match key {
            Some(k) => k,
            None => return
        };

        let command = match self.view.overlay {
            Overlay::None => self.mode.handle_key_event(key),
            _             => {
                let event = self.view.overlay.handle_key_event(key);
                if let OverlayEvent::Finished(response) = event {
                    self.view.overlay = Overlay::None;
                    self.view.clear(&mut self.frontend);
                    if let Some(data) = response {
                        Command::from_str(&*data)
                    } else {
                        Command::None
                    }
                } else {
                    Command::None
                }
            }
        };

        self.handle_command(command);
    }

    /// Draw the current view to the frontend
    fn draw(&mut self) {
        self.view.draw(&mut self.frontend);
    }

    /// Handle the given command, performing the associated action
    fn handle_command(&mut self, command: Command) {
        // check for the ExitEditor command first
        if let Command::ExitEditor = command {
            self.running = false;
            return;
        }

        match command {
            // Editor Commands
            Command::SaveBuffer         => utils::save_buffer(&self.view.buffer),
            Command::SetOverlay(o)      => self.view.set_overlay(o),

            // Navigation
            Command::MoveCursor(dir, n) => self.view.move_cursor(dir, n),
            Command::LineEnd            => self.view.move_cursor_to_line_end(),
            Command::LineStart          => self.view.move_cursor_to_line_start(),

            // Editing
            Command::Delete(dir, n)     => self.view.delete_chars(dir, n),
            Command::InsertTab          => self.view.insert_tab(),
            Command::InsertChar(c)      => self.view.insert_char(c),
            Command::Redo               => self.view.redo(),
            Command::Undo               => self.view.undo(),

            _ => {},
        }
    }

    /// Start Iota!
    pub fn start(&mut self) {
        while self.running {
            self.draw();
            self.frontend.present();
            let event = self.frontend.poll_event();

            if let EditorEvent::KeyEvent(key) = event {
                self.handle_key_event(key)
            }
        }
    }
}
<|endoftext|>