<commit_before>#![feature(plugin)]
#![plugin(parse_generics_poc)]
#[macro_use] extern crate custom_derive;

use std::iter::once;
use std::marker::PhantomData;

macro_rules! Iterator {
    (
        () $(pub)* struct $name:ident $($tail:tt)*
    ) => {
        parse_generics! {
            then Iterator!(@with_generics () struct $name,),
            $($tail)*
        }
    };

    (
        @with_generics
        () struct $name:ident,
        $generics:tt,
        ($($body:tt)*)
        $($tail:tt)*
    ) => {
        parse_where! {
            then Iterator!(@with_where () struct $name, $generics,),
            $($tail)* ($($body)*)
        }
    };

    (
        @with_where
        () struct $name:ident,
        $generics:tt,
        $preds:tt,
        ; ($(pub)* $fty:ty)
    ) => {
        Iterator! {
            @with_where
            () struct $name,
            $generics,
            $preds,
            ; ($fty,)
        }
    };

    (
        @with_where
        () struct $name:ident,
        {
            constr: [$($constr:tt)*],
            params: [$($params:tt)*],
            $($_generics_tail:tt)*
        },
        {
            preds: [$($preds:tt)*],
        },
        ; ($(pub)* $fty:ty, $(PhantomData<$_phtys:ty>),* $(,)*)
    ) => {
        Iterator! {
            @as_items
            impl<$($constr)*> Iterator for $name<$($params)*>
            where $fty: Iterator, $($preds)* {
                type Item = <$fty as Iterator>::Item;
                fn next(&mut self) -> Option<Self::Item> {
                    Iterator::next(&mut self.0)
                }
                fn size_hint(&self) -> (usize, Option<usize>) {
                    Iterator::size_hint(&self.0)
                }
            }
        }
    };

    (@as_items $($its:item)*) => { $($its)* };
}

custom_derive! {
    #[derive(Iterator)]
    struct IterA(Box<Iterator<Item=&'static str>>);
}

#[test]
fn test_iter_a() {
    let mut it = IterA(Box::new(once("upon a time")));
    assert_eq!(it.next(), Some("upon a time"));
    assert_eq!(it.next(), None);
}

custom_derive! {
    #[derive(Iterator)]
    struct IterB<'a>(Box<Iterator<Item=&'a str> + 'a>);
}

#[test]
fn test_iter_b() {
    let mut it = IterB::<'static>(Box::new(once("upon a time")));
    assert_eq!(it.next(), Some("upon a time"));
    assert_eq!(it.next(), None);
}

custom_derive! {
    #[derive(Iterator)]
    struct IterC<'a, T: ?Sized + 'a>(Box<Iterator<Item=&'a T> + 'a>);
}

#[test]
fn test_iter_c() {
    let mut it = IterC::<'static, str>(Box::new(once("upon a time")));
    assert_eq!(it.next(), Some("upon a time"));
    assert_eq!(it.next(), None);
}

custom_derive! {
    #[derive(Iterator)]
    struct IterD<'a, T: ?Sized + 'a>(Box<Iterator<Item=&'a T> + 'a>)
    where T: Copy;
}

#[test]
fn test_iter_d() {
    const S: &'static &'static str = &"times in our lives";
    let mut it = IterD(Box::new(once(S)));
    assert_eq!(it.next(), Some(&"times in our lives"));
    assert_eq!(it.next(), None);
}

custom_derive! {
    #[derive(Iterator)]
    struct IterE<T>(Box<Iterator<Item=T>>, PhantomData<T>)
    where T: Copy + Clone;
}

#[test]
fn test_iter_e() {
    const S: &'static &'static str = &"times in our lives";
    let mut it = IterE(Box::new(once(S)), PhantomData);
    assert_eq!(it.next(), Some(&"times in our lives"));
    assert_eq!(it.next(), None);
}

custom_derive! {
    #[derive(Iterator)]
    struct IterF<I: Iterator>(I);
}

#[test]
fn test_iter_f() {
    let mut it = IterF(once("you pop"));
    for e in it {
        assert!(e != "stop");
    }
}

custom_derive! {
    #[derive(Iterator)]
    struct IterG<I>(I) where I: Iterator;
}

#[test]
fn test_iter_g() {
    let mut it = IterG(once("you pop"));
    for e in it {
        assert!(e != "stop");
    }
}
<commit_msg>Fixed warnings.<commit_after>#![feature(plugin)]
#![plugin(parse_generics_poc)]
#[macro_use] extern crate custom_derive;

use std::iter::once;
use std::marker::PhantomData;

macro_rules! Iterator {
    (
        () $(pub)* struct $name:ident $($tail:tt)*
    ) => {
        parse_generics! {
            then Iterator!(@with_generics () struct $name,),
            $($tail)*
        }
    };

    (
        @with_generics
        () struct $name:ident,
        $generics:tt,
        ($($body:tt)*)
        $($tail:tt)*
    ) => {
        parse_where! {
            then Iterator!(@with_where () struct $name, $generics,),
            $($tail)* ($($body)*)
        }
    };

    (
        @with_where
        () struct $name:ident,
        $generics:tt,
        $preds:tt,
        ; ($(pub)* $fty:ty)
    ) => {
        Iterator! {
            @with_where
            () struct $name,
            $generics,
            $preds,
            ; ($fty,)
        }
    };

    (
        @with_where
        () struct $name:ident,
        {
            constr: [$($constr:tt)*],
            params: [$($params:tt)*],
            $($_generics_tail:tt)*
        },
        {
            preds: [$($preds:tt)*],
        },
        ; ($(pub)* $fty:ty, $(PhantomData<$_phtys:ty>),* $(,)*)
    ) => {
        Iterator! {
            @as_items
            impl<$($constr)*> Iterator for $name<$($params)*>
            where $fty: Iterator, $($preds)* {
                type Item = <$fty as Iterator>::Item;
                fn next(&mut self) -> Option<Self::Item> {
                    Iterator::next(&mut self.0)
                }
                fn size_hint(&self) -> (usize, Option<usize>) {
                    Iterator::size_hint(&self.0)
                }
            }
        }
    };

    (@as_items $($its:item)*) => { $($its)* };
}

custom_derive! {
    #[derive(Iterator)]
    struct IterA(Box<Iterator<Item=&'static str>>);
}

#[test]
fn test_iter_a() {
    let mut it = IterA(Box::new(once("upon a time")));
    assert_eq!(it.next(), Some("upon a time"));
    assert_eq!(it.next(), None);
}

custom_derive! {
    #[derive(Iterator)]
    struct IterB<'a>(Box<Iterator<Item=&'a str> + 'a>);
}

#[test]
fn test_iter_b() {
    let mut it = IterB::<'static>(Box::new(once("upon a time")));
    assert_eq!(it.next(), Some("upon a time"));
    assert_eq!(it.next(), None);
}

custom_derive! {
    #[derive(Iterator)]
    struct IterC<'a, T: ?Sized + 'a>(Box<Iterator<Item=&'a T> + 'a>);
}

#[test]
fn test_iter_c() {
    let mut it = IterC::<'static, str>(Box::new(once("upon a time")));
    assert_eq!(it.next(), Some("upon a time"));
    assert_eq!(it.next(), None);
}

custom_derive! {
    #[derive(Iterator)]
    struct IterD<'a, T: ?Sized + 'a>(Box<Iterator<Item=&'a T> + 'a>)
    where T: Copy;
}

#[test]
fn test_iter_d() {
    const S: &'static &'static str = &"times in our lives";
    let mut it = IterD(Box::new(once(S)));
    assert_eq!(it.next(), Some(&"times in our lives"));
    assert_eq!(it.next(), None);
}

custom_derive! {
    #[derive(Iterator)]
    struct IterE<T>(Box<Iterator<Item=T>>, PhantomData<T>)
    where T: Copy + Clone;
}

#[test]
fn test_iter_e() {
    const S: &'static &'static str = &"times in our lives";
    let mut it = IterE(Box::new(once(S)), PhantomData);
    assert_eq!(it.next(), Some(&"times in our lives"));
    assert_eq!(it.next(), None);
}

custom_derive! {
    #[derive(Iterator)]
    struct IterF<I: Iterator>(I);
}

#[test]
fn test_iter_f() {
    let it = IterF(once("you pop"));
    for e in it {
        assert!(e != "stop");
    }
}

custom_derive! {
    #[derive(Iterator)]
    struct IterG<I>(I) where I: Iterator;
}

#[test]
fn test_iter_g() {
    let it = IterG(once("you pop"));
    for e in it {
        assert!(e != "stop");
    }
}
<|endoftext|>


<commit_before>use ide_db::helpers::FamousDefs;
use syntax::{AstNode, ast::{self, make, ArgListOwner, edit::AstNodeEdit}};

use crate::{AssistContext, AssistId, AssistKind, Assists};

/// Assist: convert_iter_for_each_to_for
//
/// Converts an Iterator::for_each function into a for loop.
///
/// ```rust
/// fn main() {
///     let vec = vec![(1, 2), (2, 3), (3, 4)];
///     x.iter().for_each(|(x, y)| {
///         println!("x: {}, y: {}", x, y);
///    })
/// }
/// ```
/// ->
/// ```rust
/// fn main() {
///     let vec = vec![(1, 2), (2, 3), (3, 4)];
///     for (x, y) in x.iter() {
///         println!("x: {}, y: {}", x, y);
///     });
/// }
/// ```
pub(crate) fn convert_iter_for_each_to_for(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let closure;

    let total_expr = match ctx.find_node_at_offset::<ast::Expr>()? {
        ast::Expr::MethodCallExpr(expr) => {
            closure = match expr.arg_list()?.args().next()? {
                ast::Expr::ClosureExpr(expr) => expr,
                _ => { return None; }
            };

            expr
        },
        ast::Expr::ClosureExpr(expr) => {
            closure = expr;
            ast::MethodCallExpr::cast(closure.syntax().ancestors().nth(2)?)?
        },
        _ => { return None; }
    };

    let (total_expr, parent) = validate_method_call_expr(&ctx.sema, total_expr)?;

    let param_list = closure.param_list()?;
    let param = param_list.params().next()?.pat()?;
    let body = closure.body()?;

    acc.add(
        AssistId("convert_iter_for_each_to_for", AssistKind::RefactorRewrite),
        "Replace this `Iterator::for_each` with a for loop",
        total_expr.syntax().text_range(),
        |builder| {
            let original_indentation = total_expr.indent_level();

            let block = match body {
                ast::Expr::BlockExpr(block) => block,
                _ => make::block_expr(Vec::new(), Some(body))
            }.reset_indent().indent(original_indentation);

            let expr_for_loop = make::expr_for_loop(param, parent, block);
            builder.replace_ast(total_expr, expr_for_loop)
        },
    )
}

fn validate_method_call_expr(
    sema: &hir::Semantics<ide_db::RootDatabase>,
    expr: ast::MethodCallExpr,
) -> Option<(ast::Expr, ast::Expr)> {
    if expr.name_ref()?.text() != "for_each" {
        return None;
    }

    let expr = ast::Expr::MethodCallExpr(expr);
    let parent = ast::Expr::cast(expr.syntax().first_child()?)?;

    let it_type = sema.type_of_expr(&parent)?;
    let module = sema.scope(parent.syntax()).module()?;
    let krate = module.krate();

    let iter_trait = FamousDefs(sema, Some(krate)).core_iter_Iterator()?;
    it_type.impls_trait(sema.db, iter_trait, &[]).then(|| (expr, parent))
}

#[cfg(test)]
mod tests {
    use crate::tests::check_assist;

    use super::*;

    fn check_assist_with_fixtures(before: &str, after: &str) {
        let before = &format!(
            "//- /main.rs crate:main deps:core,empty_iter{}{}",
            before,
            FamousDefs::FIXTURE,
        );
        check_assist(convert_iter_for_each_to_for, before, after);
    }

    #[test]
    fn test_for_each_in_method() {
        check_assist_with_fixtures(
            r#"
fn main() {
    let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
    x.iter().$0for_each(|(x, y)| {
        println!("x: {}, y: {}", x, y);
    });
}"#,
            r#"
fn main() {
    let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y);
    };
}"#,
        )
    }

    #[test]
    fn test_for_each_without_braces() {
        check_assist_with_fixtures(
            r#"
fn main() {
    let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
    x.iter().$0for_each(|(x, y)| println!("x: {}, y: {}", x, y));
}"#,
            r#"
fn main() {
    let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y)
    };
}"#,
        )
    }

    #[test]
    fn test_for_each_in_closure() {
        check_assist_with_fixtures(
            r#"
fn main() {
    let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
    x.iter().for_each($0|(x, y)| println!("x: {}, y: {}", x, y));
}"#,
            r#"
fn main() {
    let x = vec![(1, 1), (2, 2), (3, 3), (4, 4)];
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y)
    };
}"#,
        )
    }
}<commit_msg>fix:  tests should work for convert_iter_for_each_to_for<commit_after>use ide_db::helpers::FamousDefs;
use syntax::{AstNode, ast::{self, make, ArgListOwner, edit::AstNodeEdit}};

use crate::{AssistContext, AssistId, AssistKind, Assists};

/// Assist: convert_iter_for_each_to_for
//
/// Converts an Iterator::for_each function into a for loop.
///
/// ```rust
/// fn main() {
///     let vec = vec![(1, 2), (2, 3), (3, 4)];
///     x.iter().for_each(|(x, y)| {
///         println!("x: {}, y: {}", x, y);
///    })
/// }
/// ```
/// ->
/// ```rust
/// fn main() {
///     let vec = vec![(1, 2), (2, 3), (3, 4)];
///     for (x, y) in x.iter() {
///         println!("x: {}, y: {}", x, y);
///     });
/// }
/// ```
pub(crate) fn convert_iter_for_each_to_for(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let closure;

    let total_expr = match ctx.find_node_at_offset::<ast::Expr>()? {
        ast::Expr::MethodCallExpr(expr) => {
            closure = match expr.arg_list()?.args().next()? {
                ast::Expr::ClosureExpr(expr) => expr,
                _ => { return None; }
            };

            expr
        },
        ast::Expr::ClosureExpr(expr) => {
            closure = expr;
            ast::MethodCallExpr::cast(closure.syntax().ancestors().nth(2)?)?
        },
        _ => { return None; }
    };

    let (total_expr, parent) = validate_method_call_expr(&ctx.sema, total_expr)?;

    let param_list = closure.param_list()?;
    let param = param_list.params().next()?.pat()?;
    let body = closure.body()?;

    acc.add(
        AssistId("convert_iter_for_each_to_for", AssistKind::RefactorRewrite),
        "Replace this `Iterator::for_each` with a for loop",
        total_expr.syntax().text_range(),
        |builder| {
            let original_indentation = total_expr.indent_level();

            let block = match body {
                ast::Expr::BlockExpr(block) => block,
                _ => make::block_expr(Vec::new(), Some(body))
            }.reset_indent().indent(original_indentation);

            let expr_for_loop = make::expr_for_loop(param, parent, block);
            builder.replace_ast(total_expr, expr_for_loop)
        },
    )
}

fn validate_method_call_expr(
    sema: &hir::Semantics<ide_db::RootDatabase>,
    expr: ast::MethodCallExpr,
) -> Option<(ast::Expr, ast::Expr)> {
    if expr.name_ref()?.text() != "for_each" {
        return None;
    }

    let expr = ast::Expr::MethodCallExpr(expr);
    let parent = ast::Expr::cast(expr.syntax().first_child()?)?;

    let it_type = sema.type_of_expr(&parent)?;
    let module = sema.scope(parent.syntax()).module()?;
    let krate = module.krate();

    let iter_trait = FamousDefs(sema, Some(krate)).core_iter_Iterator()?;
    it_type.impls_trait(sema.db, iter_trait, &[]).then(|| (expr, parent))
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    const EMPTY_ITER_FIXTURE: &'static str = r"
//- /lib.rs deps:core crate:empty_iter
pub struct EmptyIter;
impl Iterator for EmptyIter {
    type Item = usize;
    fn next(&mut self) -> Option<Self::Item> { None }
}
pub struct Empty;
impl Empty {
    pub fn iter(&self) -> EmptyIter { EmptyIter }
}
";

    fn check_assist_with_fixtures(before: &str, after: &str) {
        let before = &format!(
            "//- /main.rs crate:main deps:core,empty_iter{}{}{}",
            before,
            EMPTY_ITER_FIXTURE,
            FamousDefs::FIXTURE,
        );
        check_assist(convert_iter_for_each_to_for, before, after);
    }

    #[test]
    fn test_for_each_in_method() {
        check_assist_with_fixtures(
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    x.iter().$0for_each(|(x, y)| {
        println!("x: {}, y: {}", x, y);
    });
}"#,
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y);
    };
}
"#,
        )
    }

    #[test]
    fn test_for_each_without_braces() {
        check_assist_with_fixtures(
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    x.iter().$0for_each(|(x, y)| println!("x: {}, y: {}", x, y));
}"#,
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y)
    };
}
"#,
        )
    }

    #[test]
    fn test_for_each_in_closure() {
        check_assist_with_fixtures(
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    x.iter().for_each($0|(x, y)| println!("x: {}, y: {}", x, y));
}"#,
            r#"
use empty_iter::*;
fn main() {
    let x = Empty;
    for (x, y) in x.iter() {
        println!("x: {}, y: {}", x, y)
    };
}
"#,
        )
    }

    #[test]
    fn test_for_each_not_applicable() {
        check_assist_not_applicable(
            convert_iter_for_each_to_for,
            r#"
fn main() {
    value.$0for_each(|x| println!("{}", x));
}"#)
    }
}<|endoftext|>


<commit_before>mod features;

use proc_macro2::TokenStream;
use syn::{Result, Visibility};
use syn::parse::{Parse, ParseStream};

#[derive(Debug)]
struct VisRest {
    vis: Visibility,
    rest: TokenStream,
}

impl Parse for VisRest {
    fn parse(input: ParseStream) -> Result<Self> {
        Ok(VisRest {
            vis: input.parse()?,
            rest: input.parse()?,
        })
    }
}

macro_rules! assert_vis_parse {
    ($input:expr, Ok($p:pat)) => {
        assert_vis_parse!($input, Ok($p) + "");
    };

    ($input:expr, Ok($p:pat) + $rest:expr) => {
        let expected = $rest.parse::<TokenStream>().unwrap();
        let parse: VisRest = syn::parse_str($input).unwrap();

        match parse.vis {
            $p => {}
            _ => panic!("Expected {}, got {:?}", stringify!($p), parse.vis),
        }

        // NOTE: Round-trips through `to_string` to avoid potential whitespace
        // diffs.
        assert_eq!(parse.rest.to_string(), expected.to_string());
    };

    ($input:expr, Err) => {
        syn::parse2::<VisRest>($input.parse().unwrap()).unwrap_err();
    };
}

#[test]
fn test_pub() {
    assert_vis_parse!("pub", Ok(Visibility::Public(_)));
}

#[test]
fn test_crate() {
    assert_vis_parse!("crate", Ok(Visibility::Crate(_)));
}

#[test]
fn test_inherited() {
    assert_vis_parse!("", Ok(Visibility::Inherited));
}

#[test]
fn test_in() {
    assert_vis_parse!("pub(in foo::bar)", Ok(Visibility::Restricted(_)));
}

#[test]
fn test_pub_crate() {
    assert_vis_parse!("pub(crate)", Ok(Visibility::Restricted(_)));
}

#[test]
fn test_pub_self() {
    assert_vis_parse!("pub(self)", Ok(Visibility::Restricted(_)));
}

#[test]
fn test_pub_super() {
    assert_vis_parse!("pub(super)", Ok(Visibility::Restricted(_)));
}

#[test]
fn test_missing_in() {
    assert_vis_parse!("pub(foo::bar)", Ok(Visibility::Public(_)) + "(foo::bar)");
}

#[test]
fn test_missing_in_path() {
    assert_vis_parse!("pub(in)", Err);
}

#[test]
fn test_crate_path() {
    assert_vis_parse!("pub(crate::A, crate::B)", Ok(Visibility::Public(_)) + "(crate::A, crate::B)");
}

#[test]
fn test_junk_after_in() {
    assert_vis_parse!("pub(in some::path @@garbage)", Err);
}
<commit_msg>Format with rustfmt 2019-10-07<commit_after>mod features;

use proc_macro2::TokenStream;
use syn::parse::{Parse, ParseStream};
use syn::{Result, Visibility};

#[derive(Debug)]
struct VisRest {
    vis: Visibility,
    rest: TokenStream,
}

impl Parse for VisRest {
    fn parse(input: ParseStream) -> Result<Self> {
        Ok(VisRest {
            vis: input.parse()?,
            rest: input.parse()?,
        })
    }
}

macro_rules! assert_vis_parse {
    ($input:expr, Ok($p:pat)) => {
        assert_vis_parse!($input, Ok($p) + "");
    };

    ($input:expr, Ok($p:pat) + $rest:expr) => {
        let expected = $rest.parse::<TokenStream>().unwrap();
        let parse: VisRest = syn::parse_str($input).unwrap();

        match parse.vis {
            $p => {}
            _ => panic!("Expected {}, got {:?}", stringify!($p), parse.vis),
        }

        // NOTE: Round-trips through `to_string` to avoid potential whitespace
        // diffs.
        assert_eq!(parse.rest.to_string(), expected.to_string());
    };

    ($input:expr, Err) => {
        syn::parse2::<VisRest>($input.parse().unwrap()).unwrap_err();
    };
}

#[test]
fn test_pub() {
    assert_vis_parse!("pub", Ok(Visibility::Public(_)));
}

#[test]
fn test_crate() {
    assert_vis_parse!("crate", Ok(Visibility::Crate(_)));
}

#[test]
fn test_inherited() {
    assert_vis_parse!("", Ok(Visibility::Inherited));
}

#[test]
fn test_in() {
    assert_vis_parse!("pub(in foo::bar)", Ok(Visibility::Restricted(_)));
}

#[test]
fn test_pub_crate() {
    assert_vis_parse!("pub(crate)", Ok(Visibility::Restricted(_)));
}

#[test]
fn test_pub_self() {
    assert_vis_parse!("pub(self)", Ok(Visibility::Restricted(_)));
}

#[test]
fn test_pub_super() {
    assert_vis_parse!("pub(super)", Ok(Visibility::Restricted(_)));
}

#[test]
fn test_missing_in() {
    assert_vis_parse!("pub(foo::bar)", Ok(Visibility::Public(_)) + "(foo::bar)");
}

#[test]
fn test_missing_in_path() {
    assert_vis_parse!("pub(in)", Err);
}

#[test]
fn test_crate_path() {
    assert_vis_parse!("pub(crate::A, crate::B)", Ok(Visibility::Public(_)) + "(crate::A, crate::B)");
}

#[test]
fn test_junk_after_in() {
    assert_vis_parse!("pub(in some::path @@garbage)", Err);
}
<|endoftext|>


<commit_before>extern crate walkdir;

use std::path::PathBuf;

use walkdir::WalkDir;

fn generate_rust_module() -> String {
    let mut rust_lib = String::new();
    let out_dir = std::env::var("OUT_DIR").unwrap();
    // NOTE(jwall): Since the generated file will be included using the include! macro
    // This has to be an expression or item. This means we need to enclose it with
    // braces to force it to be a single expression instead of multiple.
    rust_lib.push_str("{");
    for entry in WalkDir::new("std").into_iter().filter_map(|e| e.ok()) {
        // Okay we want to add these as include bytes in a simulated
        // filesystem for our binary to use.
        let path = entry.into_path();
        // We only include files that are not test files.
        let path_str = path.to_string_lossy().to_string();
        if path.is_file() && !path_str.ends_with("_test.ucg") {
            println!("Adding lib file: {}", path_str);
            let out_path = PathBuf::from(format!("{}/{}", out_dir, path_str));
            // We have to copy the file into out out directory to ensure that we
            // have a reliable way for the stdlib.rs module file to include them
            // from.
            std::fs::create_dir_all(out_path.parent().unwrap()).unwrap();
            std::fs::copy(&path_str, &out_path).unwrap();
            let include = format!(
                "\tstdlib.insert(\n\t\t\"{}\".to_string(),\n\t\tinclude_str!(\"{}/{}\"));\n",
                path_str, out_dir, path_str
            );
            rust_lib.push_str(&include);
            rust_lib.push_str("\n");
        }
    }
    rust_lib.push_str("}");
    println!("Finished Adding lib files");
    rust_lib
}

fn main() {
    let contents = generate_rust_module();
    let out_dir = std::env::var("OUT_DIR").unwrap();
    std::fs::write(format!("{}/stdlib_generated.rs", out_dir), contents.as_bytes()).unwrap();
}
<commit_msg>MAINT: Cargo fmt<commit_after>extern crate walkdir;

use std::path::PathBuf;

use walkdir::WalkDir;

fn generate_rust_module() -> String {
    let mut rust_lib = String::new();
    let out_dir = std::env::var("OUT_DIR").unwrap();
    // NOTE(jwall): Since the generated file will be included using the include! macro
    // This has to be an expression or item. This means we need to enclose it with
    // braces to force it to be a single expression instead of multiple.
    rust_lib.push_str("{");
    for entry in WalkDir::new("std").into_iter().filter_map(|e| e.ok()) {
        // Okay we want to add these as include bytes in a simulated
        // filesystem for our binary to use.
        let path = entry.into_path();
        // We only include files that are not test files.
        let path_str = path.to_string_lossy().to_string();
        if path.is_file() && !path_str.ends_with("_test.ucg") {
            println!("Adding lib file: {}", path_str);
            let out_path = PathBuf::from(format!("{}/{}", out_dir, path_str));
            // We have to copy the file into out out directory to ensure that we
            // have a reliable way for the stdlib.rs module file to include them
            // from.
            std::fs::create_dir_all(out_path.parent().unwrap()).unwrap();
            std::fs::copy(&path_str, &out_path).unwrap();
            let include = format!(
                "\tstdlib.insert(\n\t\t\"{}\".to_string(),\n\t\tinclude_str!(\"{}/{}\"));\n",
                path_str, out_dir, path_str
            );
            rust_lib.push_str(&include);
            rust_lib.push_str("\n");
        }
    }
    rust_lib.push_str("}");
    println!("Finished Adding lib files");
    rust_lib
}

fn main() {
    let contents = generate_rust_module();
    let out_dir = std::env::var("OUT_DIR").unwrap();
    std::fs::write(
        format!("{}/stdlib_generated.rs", out_dir),
        contents.as_bytes(),
    )
    .unwrap();
}
<|endoftext|>


<commit_before>extern crate std;

use std::collections::HashMap;

pub type EntityID = uint;
pub type ComponentID = uint;

#[deriving(Show)]
pub enum StateError {
	EntityNotFound(EntityID),
	ComponentNotFound(ComponentID),
	FieldDoesNotExist(ComponentID, String)
}

pub struct EntitiesState {
	components: std::collections::HashMap<ComponentID, Component>,
	entities: std::collections::HashMap<EntityID, EntityData>,
	nextComponentID: ComponentID,
	nextEntityID: EntityID,
	componentsOfNativeType: HashMap<String, ComponentID>
}

struct EntityData {
	name: Option<String>,
	visible: bool,

	components: Vec<ComponentID>,

	componentsOfType: Vec<ComponentID>,
	parameters: std::collections::HashMap<String, Box<std::any::Any>>,
	defaultParameters: std::collections::HashMap<String, Box<std::any::Any>>
}

struct Component {
	owner: EntityID,

	data: ComponentData,

	linkedFrom: Vec<ComponentID>,

	parent: Option<ComponentID>,
	children: Vec<ComponentID>,

	cmpType: ComponentType
}

enum ComponentData {
	ComponentDataNative(HashMap<String, Data>),
	ComponentDataLink(ComponentID)
}

#[deriving(Clone,Show)]
pub enum ComponentType {
	NativeComponentType(String),
	EntityComponentType(EntityID)
}

#[deriving(Clone,Show)]
pub enum Data {
	Number(f64),
	String(String),
	Boolean(bool),
	List(Vec<Data>),
	Entity(EntityID),
	Empty
}

impl EntitiesState {
	pub fn new() -> EntitiesState
	{
		EntitiesState {
			components: HashMap::new(),
			entities: HashMap::new(),
			nextComponentID: 1,
			nextEntityID: 1,
			componentsOfNativeType: HashMap::new()
		}
	}

	pub fn create_entity(&mut self, name: Option<String>, visible: bool)
		-> EntityID
	{
		let id = self.nextEntityID;

		let entity = EntityData {
			name: name,
			visible: visible,

			components: Vec::new(),

			componentsOfType: Vec::new(),
			parameters: std::collections::HashMap::new(),
			defaultParameters: std::collections::HashMap::new()
		};

		self.entities.insert(id, entity);
		self.nextEntityID += 1;
		return id;
	}

	pub fn destroy_entity(&mut self, id: &EntityID)
		-> Result<(), StateError>
	{
		let componentsList = {
			let entity = try!(self.get_entity_by_id(id));

			if entity.componentsOfType.len() != 0 {
				unimplemented!()
				//return Err(format!("Cannot destroy entity with ID {} (name: {}) because it has components of its type", id, entity.name));
			}

			entity.components.clone()
		};

		for cmp in componentsList.iter() {
			self.destroy_component(cmp).ok();
		}

		self.entities.remove(id);
		Ok(())
	}

	fn clone_entity(&mut self, id: &EntityID)
		-> EntityID
	{
		unimplemented!()
	}

	fn add_entity_parameter(&mut self, id: &EntityID, name: &String)
	{
		unimplemented!()
	}

	pub fn create_native_component(&mut self, owner: &EntityID, typename: &str, data: HashMap<String, Data>)
		-> Result<ComponentID, StateError>
	{
		let newID = self.nextComponentID;

		let newComponent = Component {
			owner: owner.clone(),
			data: ComponentDataNative(data),
			linkedFrom: Vec::new(),
			parent: None,
			children: Vec::new(),
			cmpType: NativeComponentType(typename.to_string())
		};

		(try!(self.get_entity_by_id_mut(owner))).components.push(newID);

		self.components.insert(newID, newComponent);
		self.nextComponentID = self.nextComponentID + 1;

		self.componentsOfNativeType.insert(typename.to_string(), newID);

		Ok(newID)
	}

	// TODO: better error handling
	pub fn create_component_from_entity(&mut self, owner: &EntityID, typename: &EntityID, data: HashMap<String, Data>)
		-> Result<ComponentID, StateError>
	{
		let newID = self.nextComponentID;

		let newComponent = Component {
			owner: owner.clone(),
			data: ComponentDataNative(data),
			linkedFrom: Vec::new(),
			parent: None,
			children: Vec::new(),
			cmpType: EntityComponentType(typename.clone())
		};

		(try!(self.get_entity_by_id_mut(owner))).components.push(newID);
		(try!(self.get_entity_by_id_mut(typename))).componentsOfType.push(newID);

		// creating the list of components to inherit
		let componentsToInherit: Vec<ComponentID> = (try!(self.get_entity_by_id(typename))).components.iter().map(|c| c.clone()).collect();

		self.components.insert(newID, newComponent);
		self.nextComponentID = self.nextComponentID + 1;

		// inheriting components
		for cmp in componentsToInherit.move_iter() {
			match self.create_inherited_component(owner, &newID, &cmp) {
				Ok(_) => (),
				Err(err) => {
					self.destroy_component(&newID);
					return Err(err);
				}
			}
		}

		Ok(newID)
	}

	pub fn destroy_component(&mut self, id: &ComponentID)
		-> Result<(), StateError>
	{
		let children = (try!(self.get_component_by_id(id))).children.clone();
		let linked = (try!(self.get_component_by_id(id))).linkedFrom.clone();

		let parent = (try!(self.get_component_by_id(id))).parent;
		if parent.is_some() {
			let mut p = (try!(self.get_component_by_id_mut(&parent.unwrap())));
			let pos = p.children.iter().position(|c| *c == *id).unwrap();
			p.children.remove(pos);
		}

		for child in children.iter() {
			self.destroy_component(child).ok();
		}

		for cmp in linked.iter() {
			self.destroy_component(cmp).ok();
		}

		// removing from entity
		{
			let owner = (try!(self.get_component_by_id(id))).owner;
			let mut entity = try!(self.get_entity_by_id_mut(&owner));
			let pos = entity.components.iter().position(|e| *e == *id).unwrap();
			entity.components.remove(pos);
		}

		// TODO: remove from componentsOfNativeType

		// removing from components list
		self.components.remove(id);

		Ok(())
	}

	pub fn set(&mut self, id: &ComponentID, field: &str, data: Data)
		-> Result<(), StateError>
	{
		let mut idIter = id.clone();

		loop {
			let mut component = match self.components.find_mut(&idIter) {
				None => return Err(ComponentNotFound(idIter)),
				Some(c) => c
			};

			match &mut component.data {
				&ComponentDataNative(ref mut val) => {
					val.insert(field.to_string(), data);
					return Ok(());
				},
				&ComponentDataLink(c) => {
					idIter = c.clone();
					continue;
				}
			}
		}

		unreachable!();
	}

	pub fn get<'a>(&'a self, id: &ComponentID, field: &str)
		-> Result<&'a Data, StateError>
	{
		match (try!(self.get_component_by_id(id))).data {
			ComponentDataNative(ref data) => {
				match data.find_equiv(&field) {
					Some(a) => Ok(a),
					None => Err(FieldDoesNotExist(id.clone(), field.to_string()))
				}
			},
			ComponentDataLink(c) => {
				self.get(&c, field)
			}
		}
	}

	pub fn get_owner(&self, id: &ComponentID)
		-> Result<EntityID, StateError>
	{
		Ok((try!(self.get_component_by_id(id))).owner)
	}

	pub fn get_type(&self, id: &ComponentID)
		-> Result<ComponentType, StateError>
	{
		Ok((try!(self.get_component_by_id(id))).cmpType.clone())
	}

	pub fn get_entities_iter<'a>(&'a self)
		-> std::collections::hashmap::Keys<'a, EntityID, EntityData>
	{
		self.entities.keys()
	}

	pub fn get_entity_name<'a>(&'a self, id: &EntityID)
		-> Result<Option<String>, StateError>
	{
		Ok((try!(self.get_entity_by_id(id))).name.clone())
	}

	pub fn get_entities_by_name<'a>(&'a self, name: &str)
		-> Vec<EntityID>
	{
		self.entities.iter().filter(|&(_, ref e)| e.name == Some(name.to_string())).map(|(id, _)| id.clone()).collect()
	}

	pub fn get_components_iter<'a>(&'a self)
		-> std::collections::hashmap::Keys<'a, ComponentID, Component>
	{
		self.components.keys()
	}

	/*pub fn get_name<'a>(&'a self, id: &EntityID)
		-> Result<Option<&'a str>, String>
	{
		let mut entity = match self.entities.find(id) {
			None => return Err(format!("Entity with ID {} doesn't exist", id)),
			Some(e) => e
		};

		Ok(entity.name.map(|e| e.as_slice()))
	}*/

	/*pub fn get_components_of_native_type(&self, typename: &str) {

	}*/

	fn link_component_data(&mut self, component: &ComponentID, link_to: &ComponentID) {
		unimplemented!()
	}

	fn unlink(&mut self, component: &ComponentID) {
		unimplemented!()
	}

	pub fn set_component_parent(&mut self, component: &ComponentID, parent: &ComponentID)
		-> Result<(), StateError>
	{
		if (try!(self.get_component_by_id_mut(component))).parent.is_some() {
			self.clear_component_parent(component);
		}

		(try!(self.get_component_by_id_mut(component))).parent = Some(parent.clone());
		(try!(self.get_component_by_id_mut(parent))).children.push(component.clone());

		Ok(())
	}

	fn clear_component_parent(&mut self, component: &ComponentID) {
		unimplemented!()
	}

	pub fn get_component_children(&self, component: &ComponentID)
		-> Result<Vec<ComponentID>, StateError>
	{
		Ok((try!(self.get_component_by_id(component))).children.clone())
	}

	/**
	 * Creates a component inherited from another
	 */
	// TODO: better error handling
	fn create_inherited_component(&mut self, owner: &EntityID, parent: &ComponentID, inherit: &ComponentID)
		-> Result<ComponentID, StateError>
	{
		let newID = self.nextComponentID;

		let newComponent = Component {
			owner: owner.clone(),
			data: ComponentDataLink(inherit.clone()),
			linkedFrom: Vec::new(),
			parent: Some(parent.clone()),
			children: Vec::new(),
			cmpType: (try!(self.get_component_by_id(inherit))).cmpType.clone()
		};

		(try!(self.get_component_by_id_mut(inherit))).linkedFrom.push(newID);
		(try!(self.get_component_by_id_mut(parent))).children.push(newID);
		(try!(self.get_entity_by_id_mut(owner))).components.push(newID);

		self.components.insert(newID, newComponent);

		self.nextComponentID = self.nextComponentID + 1;

		Ok(newID)
	}

	fn get_entity_by_id<'a>(&'a self, id: &ComponentID)
		-> Result<&'a EntityData, StateError>
	{
		match self.entities.find(id) {
			None => Err(EntityNotFound(id.clone())),
			Some(c) => Ok(c)
		}
	}

	fn get_entity_by_id_mut<'a>(&'a mut self, id: &ComponentID)
		-> Result<&'a mut EntityData, StateError>
	{
		match self.entities.find_mut(id) {
			None => Err(EntityNotFound(id.clone())),
			Some(c) => Ok(c)
		}
	}

	fn get_component_by_id<'a>(&'a self, id: &ComponentID)
		-> Result<&'a Component, StateError>
	{
		match self.components.find(id) {
			None => Err(ComponentNotFound(id.clone())),
			Some(c) => Ok(c)
		}
	}

	fn get_component_by_id_mut<'a>(&'a mut self, id: &ComponentID)
		-> Result<&'a mut Component, StateError>
	{
		match self.components.find_mut(id) {
			None => Err(ComponentNotFound(id.clone())),
			Some(c) => Ok(c)
		}
	}

	pub fn is_component_visible(&self, id: &ComponentID)
		-> Result<bool, StateError>
	{
		let owner = try!(self.get_owner(id));
		Ok((try!(self.get_entity_by_id(&owner))).visible)
	}
}

#[cfg(test)]
mod tests {
	#[test]
	fn basic() {
		let es = super::EntitiesState::new();

		let id = es.create_entity();
	}
}
<commit_msg>Minor cleanup of EntitiesState<commit_after>extern crate std;

use std::collections::HashMap;

/**
 * Identifier of an entity
 */
pub type EntityID = uint;

/**
 * Identifier of a component
 */
pub type ComponentID = uint;

/**
 * An error while doing an operation on the state
 */
#[deriving(Show)]
pub enum StateError {
    EntityNotFound(EntityID),
    ComponentNotFound(ComponentID),
    FieldDoesNotExist(ComponentID, String)
}

/**
 *
 */
#[unstable]
pub struct EntitiesState {
    components: HashMap<ComponentID, Component>,
    entities: HashMap<EntityID, EntityData>,

    next_component_id: ComponentID,
    next_entity_id: EntityID,

    components_of_native_type: HashMap<String, ComponentID>
}

struct EntityData {
    // name of the entity with its path as prefix
    name: Option<String>,
    visible: bool,

    // components owned by the entity
    components: Vec<ComponentID>,

    // components whose type is the entity
    components_of_type: Vec<ComponentID>,

    // list of parameters of the current entity
    default_parameters: HashMap<String, Data>
}

struct Component {
    owner: EntityID,

    cmp_type: ComponentType,

    data: ComponentData,

    // all components in this list have their data as a ComponentDataLink to this one
    linked_from: Vec<ComponentID>,

    parent: Option<ComponentID>,
    // when a component is destroyed, all children are destroyed too
    children: Vec<ComponentID>
}

enum ComponentData {
    ComponentDataNative(HashMap<String, Data>),
    ComponentDataLink(ComponentID)
}

/**
 * Type of a component
 */
#[deriving(Clone,Show)]
pub enum ComponentType {
    NativeComponentType(String),
    EntityComponentType(EntityID)
}

#[deriving(Clone,Show)]
pub enum Data {
    Number(f64),
    String(String),
    Boolean(bool),
    List(Vec<Data>),
    Entity(EntityID),
    FromProperty(String),
    Empty
}

impl EntitiesState {
    /**
     * Builds a new empty state
     */
    pub fn new() -> EntitiesState
    {
        EntitiesState {
            components: HashMap::new(),
            entities: HashMap::new(),
            next_component_id: 1,
            next_entity_id: 1,
            components_of_native_type: HashMap::new()
        }
    }

    /**
     * Creates a new empty entity in the state
     */
    pub fn create_entity(&mut self, name: Option<String>, visible: bool)
        -> EntityID
    {
        let id = self.next_entity_id;

        let entity = EntityData {
            name: name,
            visible: visible,

            components: Vec::new(),

            components_of_type: Vec::new(),
            default_parameters: std::collections::HashMap::new()
        };

        self.entities.insert(id, entity);
        self.next_entity_id += 1;
        id
    }

    /**
     * Destroys an entity
     * This operation will also destroy all the components owned by this entity and all components whose type is this entity
     */
    pub fn destroy_entity(&mut self, id: &EntityID)
        -> Result<(), StateError>
    {
        let components_list = {
            let entity = try!(self.get_entity_by_id(id));

            if entity.components_of_type.len() != 0 {
                unimplemented!()
                //return Err(format!("Cannot destroy entity with ID {} (name: {}) because it has components of its type", id, entity.name));
            }

            entity.components.clone()
        };

        for cmp in components_list.iter() {
            // ignoring error from destroying component because we don't want to recreate them
            self.destroy_component(cmp).ok();
        }

        self.entities.remove(id);
        Ok(())
    }

    /**
     * Creates a new component of native type
     */
    pub fn create_native_component(&mut self, owner: &EntityID, typename: &str, data: HashMap<String, Data>)
        -> Result<ComponentID, StateError>
    {
        let newID = self.next_component_id;

        let newComponent = Component {
            owner: owner.clone(),
            data: ComponentDataNative(data),
            linked_from: Vec::new(),
            parent: None,
            children: Vec::new(),
            cmp_type: NativeComponentType(typename.to_string())
        };

        (try!(self.get_entity_by_id_mut(owner))).components.push(newID);

        self.components.insert(newID, newComponent);
        self.next_component_id = self.next_component_id + 1;

        self.components_of_native_type.insert(typename.to_string(), newID);

        Ok(newID)
    }

    /**
     * Creates a new component of an entity type
     */
    /// TODO: better error handling
    pub fn create_component_from_entity(&mut self, owner: &EntityID, typename: &EntityID, data: HashMap<String, Data>)
        -> Result<ComponentID, StateError>
    {
        let newID = self.next_component_id;

        let newComponent = Component {
            owner: owner.clone(),
            data: ComponentDataNative(data),
            linked_from: Vec::new(),
            parent: None,
            children: Vec::new(),
            cmp_type: EntityComponentType(typename.clone())
        };

        (try!(self.get_entity_by_id_mut(owner))).components.push(newID);
        (try!(self.get_entity_by_id_mut(typename))).components_of_type.push(newID);

        // creating the list of components to inherit
        let components_to_inherit: Vec<ComponentID> = (try!(self.get_entity_by_id(typename))).components.iter().map(|c| c.clone()).collect();

        self.components.insert(newID, newComponent);
        self.next_component_id = self.next_component_id + 1;

        // inheriting components
        for cmp in components_to_inherit.move_iter() {
            match self.create_inherited_component(owner, &newID, &cmp) {
                Ok(_) => (),
                Err(err) => {
                    self.destroy_component(&newID);
                    return Err(err);
                }
            }
        }

        Ok(newID)
    }

    /**
     * Destroys a component
     */
    pub fn destroy_component(&mut self, id: &ComponentID)
        -> Result<(), StateError>
    {
        let children = (try!(self.get_component_by_id(id))).children.clone();
        let linked = (try!(self.get_component_by_id(id))).linked_from.clone();

        let parent = (try!(self.get_component_by_id(id))).parent;
        if parent.is_some() {
            let mut p = (try!(self.get_component_by_id_mut(&parent.unwrap())));
            let pos = p.children.iter().position(|c| *c == *id).unwrap();
            p.children.remove(pos);
        }

        for child in children.iter() {
            self.destroy_component(child).ok();
        }

        for cmp in linked.iter() {
            self.destroy_component(cmp).ok();
        }

        // removing from entity
        {
            let owner = (try!(self.get_component_by_id(id))).owner;
            let mut entity = try!(self.get_entity_by_id_mut(&owner));
            let pos = entity.components.iter().position(|e| *e == *id).unwrap();
            entity.components.remove(pos);
        }

        // TODO: remove from components_of_native_type

        // removing from components list
        self.components.remove(id);

        Ok(())
    }

    pub fn set(&mut self, id: &ComponentID, field: &str, data: Data)
        -> Result<(), StateError>
    {
        let mut idIter = id.clone();

        loop {
            let mut component = match self.components.find_mut(&idIter) {
                None => return Err(ComponentNotFound(idIter)),
                Some(c) => c
            };

            match &mut component.data {
                &ComponentDataNative(ref mut val) => {
                    val.insert(field.to_string(), data);
                    return Ok(());
                },
                &ComponentDataLink(c) => {
                    idIter = c.clone();
                    continue;
                }
            }
        }

        unreachable!();
    }

    pub fn get<'a>(&'a self, id: &ComponentID, field: &str)
        -> Result<&'a Data, StateError>
    {
        match (try!(self.get_component_by_id(id))).data {
            ComponentDataNative(ref data) => {
                match data.find_equiv(&field) {
                    Some(a) => Ok(a),
                    None => Err(FieldDoesNotExist(id.clone(), field.to_string()))
                }
            },
            ComponentDataLink(c) => {
                self.get(&c, field)
            }
        }
    }

    pub fn get_owner(&self, id: &ComponentID)
        -> Result<EntityID, StateError>
    {
        Ok((try!(self.get_component_by_id(id))).owner)
    }

    pub fn get_type(&self, id: &ComponentID)
        -> Result<ComponentType, StateError>
    {
        Ok((try!(self.get_component_by_id(id))).cmp_type.clone())
    }

    pub fn get_entities_iter<'a>(&'a self)
        -> std::collections::hashmap::Keys<'a, EntityID, EntityData>
    {
        self.entities.keys()
    }

    pub fn get_entity_name<'a>(&'a self, id: &EntityID)
        -> Result<Option<String>, StateError>
    {
        Ok((try!(self.get_entity_by_id(id))).name.clone())
    }

    pub fn get_entities_by_name<'a>(&'a self, name: &str)
        -> Vec<EntityID>
    {
        self.entities.iter().filter(|&(_, ref e)| e.name == Some(name.to_string())).map(|(id, _)| id.clone()).collect()
    }

    pub fn get_components_iter<'a>(&'a self)
        -> std::collections::hashmap::Keys<'a, ComponentID, Component>
    {
        self.components.keys()
    }

    pub fn is_component_visible(&self, id: &ComponentID)
        -> Result<bool, StateError>
    {
        let owner = try!(self.get_owner(id));
        Ok((try!(self.get_entity_by_id(&owner))).visible)
    }

    pub fn set_component_parent(&mut self, component: &ComponentID, parent: &ComponentID)
        -> Result<(), StateError>
    {
        if (try!(self.get_component_by_id_mut(component))).parent.is_some() {
            self.clear_component_parent(component);
        }

        (try!(self.get_component_by_id_mut(component))).parent = Some(parent.clone());
        (try!(self.get_component_by_id_mut(parent))).children.push(component.clone());

        Ok(())
    }

    pub fn clear_component_parent(&mut self, component: &ComponentID) {
        unimplemented!()
    }

    pub fn get_component_children(&self, component: &ComponentID)
        -> Result<Vec<ComponentID>, StateError>
    {
        Ok((try!(self.get_component_by_id(component))).children.clone())
    }

    /**
     * Creates a component inherited from another
     */
    // TODO: better error handling
    fn create_inherited_component(&mut self, owner: &EntityID, parent: &ComponentID, inherit: &ComponentID)
        -> Result<ComponentID, StateError>
    {
        let newID = self.next_component_id;

        let newComponent = Component {
            owner: owner.clone(),
            data: ComponentDataLink(inherit.clone()),
            linked_from: Vec::new(),
            parent: Some(parent.clone()),
            children: Vec::new(),
            cmp_type: (try!(self.get_component_by_id(inherit))).cmp_type.clone()
        };

        (try!(self.get_component_by_id_mut(inherit))).linked_from.push(newID);
        (try!(self.get_component_by_id_mut(parent))).children.push(newID);
        (try!(self.get_entity_by_id_mut(owner))).components.push(newID);

        self.components.insert(newID, newComponent);

        self.next_component_id = self.next_component_id + 1;

        Ok(newID)
    }

    fn get_entity_by_id<'a>(&'a self, id: &ComponentID)
        -> Result<&'a EntityData, StateError>
    {
        match self.entities.find(id) {
            None => Err(EntityNotFound(id.clone())),
            Some(c) => Ok(c)
        }
    }

    fn get_entity_by_id_mut<'a>(&'a mut self, id: &ComponentID)
        -> Result<&'a mut EntityData, StateError>
    {
        match self.entities.find_mut(id) {
            None => Err(EntityNotFound(id.clone())),
            Some(c) => Ok(c)
        }
    }

    fn get_component_by_id<'a>(&'a self, id: &ComponentID)
        -> Result<&'a Component, StateError>
    {
        match self.components.find(id) {
            None => Err(ComponentNotFound(id.clone())),
            Some(c) => Ok(c)
        }
    }

    fn get_component_by_id_mut<'a>(&'a mut self, id: &ComponentID)
        -> Result<&'a mut Component, StateError>
    {
        match self.components.find_mut(id) {
            None => Err(ComponentNotFound(id.clone())),
            Some(c) => Ok(c)
        }
    }
}

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

    #[test]
    fn basic() {
        let mut state = EntitiesState::new();

        let eID = state.create_entity();

        let cmpID = state.create_native_component(&eID, "test", HashMap::new());
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 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.

//! Tidy check to ensure that there are no binaries checked into the source tree
//! by accident.
//!
//! In the past we've accidentally checked in test binaries and such which add a
//! huge amount of bloat to the git history, so it's good to just ensure we
//! don't do that again :)

use std::path::Path;

// All files are executable on Windows, so just check on Unix
#[cfg(windows)]
pub fn check(_path: &Path, _bad: &mut bool) {}

#[cfg(unix)]
pub fn check(path: &Path, bad: &mut bool) {
    use std::fs;
    use std::os::unix::prelude::*;

    super::walk(path,
                &mut |path| super::filter_dirs(path) || path.ends_with("src/etc"),
                &mut |file| {
        let filename = file.file_name().unwrap().to_string_lossy();
        let extensions = [".py", ".sh"];
        if extensions.iter().any(|e| filename.ends_with(e)) {
            return
        }

        let metadata = t!(fs::symlink_metadata(&file), &file);
        if metadata.mode() & 0o111 != 0 {
            println!("binary checked into source: {}", file.display());
            *bad = true;
        }
    })
}

<commit_msg>Check that executable file is in-tree before failing tidy check.<commit_after>// Copyright 2016 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.

//! Tidy check to ensure that there are no binaries checked into the source tree
//! by accident.
//!
//! In the past we've accidentally checked in test binaries and such which add a
//! huge amount of bloat to the git history, so it's good to just ensure we
//! don't do that again :)

use std::path::Path;

// All files are executable on Windows, so just check on Unix
#[cfg(windows)]
pub fn check(_path: &Path, _bad: &mut bool) {}

#[cfg(unix)]
pub fn check(path: &Path, bad: &mut bool) {
    use std::fs;
    use std::process::{Command, Stdio};
    use std::os::unix::prelude::*;

    super::walk(path,
                &mut |path| super::filter_dirs(path) || path.ends_with("src/etc"),
                &mut |file| {
        let filename = file.file_name().unwrap().to_string_lossy();
        let extensions = [".py", ".sh"];
        if extensions.iter().any(|e| filename.ends_with(e)) {
            return
        }

        let metadata = t!(fs::symlink_metadata(&file), &file);
        if metadata.mode() & 0o111 != 0 {
            let rel_path = file.strip_prefix(path).unwrap();
            let git_friendly_path = rel_path.to_str().unwrap().replace("\\", "/");
            let ret_code = Command::new("git")
                                        .arg("ls-files")
                                        .arg(&git_friendly_path)
                                        .current_dir(path)
                                        .stdout(Stdio::null())
                                        .stderr(Stdio::null())
                                        .status()
                                        .unwrap_or_else(|e| {
                                            panic!("could not run git ls-files: {}", e);
                                        });
            if ret_code.success() {
                println!("binary checked into source: {}", file.display());
                *bad = true;
            }
        }
    })
}

<|endoftext|>


<commit_before>use super::TcpTransport;
use super::TcpTransportError;
use super::test_stream::TestStream;

use protocol::cmd::Cmd;
use protocol::cmd::Get;
use protocol::cmd::Resp;
use protocol::cmd::Set;
use protocol::cmd::Stat;
use protocol::cmd::Value;

// Basic methods to consume the stream

#[test]
fn test_as_string_ok() {
    let ts = TestStream::new(vec![]);
    let transport = TcpTransport::new(ts);

    let string = transport.as_string(vec![97, 32, 65]).unwrap();
    assert_eq!(string, "a A".to_string());
}

#[test]
fn test_as_string_invalid() {
    let ts = TestStream::new(vec![]);
    let transport = TcpTransport::new(ts);

    // Invalid utf8 bytes
    let err = transport.as_string(vec![97, 254, 255]).unwrap_err();
    assert_eq!(err, TcpTransportError::Utf8Error);
}

#[test]
fn test_as_number_ok() {
    let ts = TestStream::new(vec![]);
    let transport = TcpTransport::new(ts);

    let bytes = "123".to_string().into_bytes();
    let num = transport.as_number::<u32>(bytes).unwrap();
    assert_eq!(num, 123);
}

#[test]
fn test_as_number_invalid() {
    let ts = TestStream::new(vec![]);
    let transport = TcpTransport::new(ts);

    let bytes = "12 3".to_string().into_bytes();
    let err = transport.as_number::<u32>(bytes).unwrap_err();
    assert_eq!(err, TcpTransportError::NumberParseError);
}

#[test]
fn test_read_byte() {
    let ts = TestStream::new(vec![93]);
    let mut transport = TcpTransport::new(ts);

    let byte = transport.read_byte().unwrap();
    assert_eq!(byte, 93);
}

#[test]
fn test_read_bytes() {
    let ts = TestStream::new(vec![93, 13, 10]);
    let mut transport = TcpTransport::new(ts);

    let bytes = transport.read_bytes(3).unwrap();
    assert_eq!(bytes, [93, 13, 10]);
}

#[test]
fn test_read_line_ok() {
    let ts = TestStream::new(vec![93, 13, 10]);
    let mut transport = TcpTransport::new(ts);

    let line = transport.read_line(3).unwrap();
    assert_eq!(line, [93]);
}

#[test]
fn test_read_line_invalid_newline_marker() {
    let ts = TestStream::new(vec![93, 10]);
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_line(2).unwrap_err();
    assert_eq!(err, TcpTransportError::LineReadError);
}

#[test]
fn test_read_line_too_long() {
    let ts = TestStream::new(vec![93, 1, 2, 3, 13, 10]);
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_line(5).unwrap_err();
    assert_eq!(err, TcpTransportError::LineReadError);
}

#[test]
fn test_remove_first_char() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let mut bytes = vec![1];
    let rv = transport.remove_first_char(&mut bytes);
    assert!(rv.is_ok());

    let mut bytes = vec![];
    let rv = transport.remove_first_char(&mut bytes);
    assert!(rv.is_err());
}

#[test]
fn test_parse_word_split() {
    let ts = TestStream::new(vec![1, 2, 32, 3, 4, 11, 32]);
    let mut transport = TcpTransport::new(ts);

    let bytes = transport.read_bytes(7).unwrap();
    let (word, rest) = transport.parse_word(bytes).unwrap();
    assert_eq!(word, [1, 2]);
    assert_eq!(rest, [32, 3, 4, 11, 32]);
}

#[test]
fn test_parse_word_whole() {
    let ts = TestStream::new(vec![1, 2, 3, 3, 4, 11]);
    let mut transport = TcpTransport::new(ts);

    let bytes = transport.read_bytes(6).unwrap();
    let (word, rest) = transport.parse_word(bytes).unwrap();
    assert_eq!(word, [1, 2, 3, 3, 4, 11]);
    assert_eq!(rest, []);
}

// Basic methods to produce the stream

#[test]
fn test_write_bytes() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let bytelen = transport.write_bytes(&vec![97, 98, 99]).unwrap();
    assert_eq!(bytelen, 3);
    assert_eq!(transport.get_outgoing_buffer(), &[97, 98, 99]);

    transport.flush_writes().unwrap();
    assert_eq!(transport.get_outgoing_buffer(), &[]);
    assert_eq!(transport.get_stream().outgoing, [97, 98, 99]);
}

#[test]
fn test_write_string() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let bytelen = transport.write_string("abc").unwrap();
    transport.flush_writes().unwrap();
    assert_eq!(bytelen, 3);
    assert_eq!(transport.get_stream().outgoing, [97, 98, 99]);
}

// Command parsing: malformed examples

#[test]
fn test_read_cmd_invalid() {
    let cmd_str = "invalid key 0 0 3\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_cmd().unwrap_err();
    assert_eq!(err, TcpTransportError::InvalidCmd);
}

#[test]
fn test_read_cmd_malterminated() {
    let cmd_str = "stats\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_cmd().unwrap_err();
    assert_eq!(err, TcpTransportError::StreamReadError);
}

// Command parsing: Get

#[test]
fn test_read_cmd_get_ok() {
    let cmd_str = "get x\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let cmd = transport.read_cmd().unwrap();
    assert_eq!(cmd, Cmd::Get(Get::new("x")));
}

#[test]
fn test_read_cmd_get_non_utf8() {
    // get X\r\n
    let cmd_bytes = vec![103, 101, 116, 32, 254, 13, 10];
    let ts = TestStream::new(cmd_bytes);
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_cmd().unwrap_err();
    assert_eq!(err, TcpTransportError::Utf8Error);
}

#[test]
fn test_read_cmd_get_malformed() {
    fn try_cmd(cmd: &str) {
        let cmd_str = cmd.to_string();
        let ts = TestStream::new(cmd_str.into_bytes());
        let mut transport = TcpTransport::new(ts);

        let err = transport.read_cmd().unwrap_err();
        assert_eq!(err, TcpTransportError::StreamReadError);
    }

    // Test for truncated stream
    try_cmd("get x\r");
    try_cmd("get x");
    try_cmd("get ");
    try_cmd("get");
}

// Command parsing: Set

#[test]
fn test_read_cmd_set_ok() {
    let cmd_str = "set x 0 0 3\r\nabc\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let cmd = transport.read_cmd().unwrap();
    assert_eq!(cmd, Cmd::Set(Set::new("x", 0, vec![97, 98, 99])));
}

#[test]
fn test_read_cmd_set_under_size() {
    let cmd_str = "set x 0 0 2\r\nabc\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_cmd().unwrap_err();
    assert_eq!(err, TcpTransportError::CommandParseError);
}

#[test]
fn test_read_cmd_set_over_size() {
    let cmd_str = "set x 0 0 4\r\nabc\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_cmd().unwrap_err();
    assert_eq!(err, TcpTransportError::StreamReadError);
}

#[test]
fn test_read_cmd_set_malformed() {
    fn try_cmd(cmd: &str) {
        let cmd_str = cmd.to_string();
        let ts = TestStream::new(cmd_str.into_bytes());
        let mut transport = TcpTransport::new(ts);

        let err = transport.read_cmd().unwrap_err();
        assert_eq!(err, TcpTransportError::StreamReadError);
    }

    // Test for truncated stream
    try_cmd("set x 0 0 3\r\nabc\r");
    try_cmd("set x 0 0 3\r\nabc");
    try_cmd("set x 0 0 3\r\nab");
    try_cmd("set x 0 0 3\r\na");
    try_cmd("set x 0 0 3\r\n");
    try_cmd("set x 0 0 3\r");
    try_cmd("set x 0 0 3");
    try_cmd("set x 0 0 ");
    try_cmd("set x 0 0");
    try_cmd("set x 0 ");
    try_cmd("set x 0");
    try_cmd("set x ");
    try_cmd("set x");
    try_cmd("set ");
    try_cmd("set");
}

// Command parsing: Stats

#[test]
fn test_read_cmd_stats() {
    let cmd_str = "stats\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let cmd = transport.read_cmd().unwrap();
    assert_eq!(cmd, Cmd::Stats);
}

// Response writing: Error

#[test]
fn test_write_resp_error() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let resp = Resp::Error;
    transport.write_resp(&resp).unwrap();
    let expected = "ERROR\r\n".to_string().into_bytes();
    assert_eq!(transport.get_stream().outgoing, expected);
}

// Response writing: Stats

#[test]
fn test_write_resp_stats() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let stat = Stat::new("curr_items", "0".to_string());
    let resp = Resp::Stats(vec![stat]);
    transport.write_resp(&resp).unwrap();
    let expected = "curr_items 0\r\nEND\r\n".to_string().into_bytes();
    assert_eq!(transport.get_stream().outgoing, expected);
}

// Response writing: Stored

#[test]
fn test_write_resp_stored() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let resp = Resp::Stored;
    transport.write_resp(&resp).unwrap();
    let expected = "STORED\r\n".to_string().into_bytes();
    assert_eq!(transport.get_stream().outgoing, expected);
}

// Response writing: Value

#[test]
fn test_write_resp_value() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let resp = Resp::Value(Value::new("x", "abc".to_string().into_bytes()));
    transport.write_resp(&resp).unwrap();
    let expected = "VALUE x 0 3\r\nabc\r\n".to_string().into_bytes();
    assert_eq!(transport.get_stream().outgoing, expected);
}
<commit_msg>fix stats test<commit_after>use super::TcpTransport;
use super::TcpTransportError;
use super::test_stream::TestStream;

use protocol::cmd::Cmd;
use protocol::cmd::Get;
use protocol::cmd::Resp;
use protocol::cmd::Set;
use protocol::cmd::Stat;
use protocol::cmd::Value;

// Basic methods to consume the stream

#[test]
fn test_as_string_ok() {
    let ts = TestStream::new(vec![]);
    let transport = TcpTransport::new(ts);

    let string = transport.as_string(vec![97, 32, 65]).unwrap();
    assert_eq!(string, "a A".to_string());
}

#[test]
fn test_as_string_invalid() {
    let ts = TestStream::new(vec![]);
    let transport = TcpTransport::new(ts);

    // Invalid utf8 bytes
    let err = transport.as_string(vec![97, 254, 255]).unwrap_err();
    assert_eq!(err, TcpTransportError::Utf8Error);
}

#[test]
fn test_as_number_ok() {
    let ts = TestStream::new(vec![]);
    let transport = TcpTransport::new(ts);

    let bytes = "123".to_string().into_bytes();
    let num = transport.as_number::<u32>(bytes).unwrap();
    assert_eq!(num, 123);
}

#[test]
fn test_as_number_invalid() {
    let ts = TestStream::new(vec![]);
    let transport = TcpTransport::new(ts);

    let bytes = "12 3".to_string().into_bytes();
    let err = transport.as_number::<u32>(bytes).unwrap_err();
    assert_eq!(err, TcpTransportError::NumberParseError);
}

#[test]
fn test_read_byte() {
    let ts = TestStream::new(vec![93]);
    let mut transport = TcpTransport::new(ts);

    let byte = transport.read_byte().unwrap();
    assert_eq!(byte, 93);
}

#[test]
fn test_read_bytes() {
    let ts = TestStream::new(vec![93, 13, 10]);
    let mut transport = TcpTransport::new(ts);

    let bytes = transport.read_bytes(3).unwrap();
    assert_eq!(bytes, [93, 13, 10]);
}

#[test]
fn test_read_line_ok() {
    let ts = TestStream::new(vec![93, 13, 10]);
    let mut transport = TcpTransport::new(ts);

    let line = transport.read_line(3).unwrap();
    assert_eq!(line, [93]);
}

#[test]
fn test_read_line_invalid_newline_marker() {
    let ts = TestStream::new(vec![93, 10]);
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_line(2).unwrap_err();
    assert_eq!(err, TcpTransportError::LineReadError);
}

#[test]
fn test_read_line_too_long() {
    let ts = TestStream::new(vec![93, 1, 2, 3, 13, 10]);
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_line(5).unwrap_err();
    assert_eq!(err, TcpTransportError::LineReadError);
}

#[test]
fn test_remove_first_char() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let mut bytes = vec![1];
    let rv = transport.remove_first_char(&mut bytes);
    assert!(rv.is_ok());

    let mut bytes = vec![];
    let rv = transport.remove_first_char(&mut bytes);
    assert!(rv.is_err());
}

#[test]
fn test_parse_word_split() {
    let ts = TestStream::new(vec![1, 2, 32, 3, 4, 11, 32]);
    let mut transport = TcpTransport::new(ts);

    let bytes = transport.read_bytes(7).unwrap();
    let (word, rest) = transport.parse_word(bytes).unwrap();
    assert_eq!(word, [1, 2]);
    assert_eq!(rest, [32, 3, 4, 11, 32]);
}

#[test]
fn test_parse_word_whole() {
    let ts = TestStream::new(vec![1, 2, 3, 3, 4, 11]);
    let mut transport = TcpTransport::new(ts);

    let bytes = transport.read_bytes(6).unwrap();
    let (word, rest) = transport.parse_word(bytes).unwrap();
    assert_eq!(word, [1, 2, 3, 3, 4, 11]);
    assert_eq!(rest, []);
}

// Basic methods to produce the stream

#[test]
fn test_write_bytes() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let bytelen = transport.write_bytes(&vec![97, 98, 99]).unwrap();
    assert_eq!(bytelen, 3);
    assert_eq!(transport.get_outgoing_buffer(), &[97, 98, 99]);

    transport.flush_writes().unwrap();
    assert_eq!(transport.get_outgoing_buffer(), &[]);
    assert_eq!(transport.get_stream().outgoing, [97, 98, 99]);
}

#[test]
fn test_write_string() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let bytelen = transport.write_string("abc").unwrap();
    transport.flush_writes().unwrap();
    assert_eq!(bytelen, 3);
    assert_eq!(transport.get_stream().outgoing, [97, 98, 99]);
}

// Command parsing: malformed examples

#[test]
fn test_read_cmd_invalid() {
    let cmd_str = "invalid key 0 0 3\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_cmd().unwrap_err();
    assert_eq!(err, TcpTransportError::InvalidCmd);
}

#[test]
fn test_read_cmd_malterminated() {
    let cmd_str = "stats\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_cmd().unwrap_err();
    assert_eq!(err, TcpTransportError::StreamReadError);
}

// Command parsing: Get

#[test]
fn test_read_cmd_get_ok() {
    let cmd_str = "get x\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let cmd = transport.read_cmd().unwrap();
    assert_eq!(cmd, Cmd::Get(Get::new("x")));
}

#[test]
fn test_read_cmd_get_non_utf8() {
    // get X\r\n
    let cmd_bytes = vec![103, 101, 116, 32, 254, 13, 10];
    let ts = TestStream::new(cmd_bytes);
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_cmd().unwrap_err();
    assert_eq!(err, TcpTransportError::Utf8Error);
}

#[test]
fn test_read_cmd_get_malformed() {
    fn try_cmd(cmd: &str) {
        let cmd_str = cmd.to_string();
        let ts = TestStream::new(cmd_str.into_bytes());
        let mut transport = TcpTransport::new(ts);

        let err = transport.read_cmd().unwrap_err();
        assert_eq!(err, TcpTransportError::StreamReadError);
    }

    // Test for truncated stream
    try_cmd("get x\r");
    try_cmd("get x");
    try_cmd("get ");
    try_cmd("get");
}

// Command parsing: Set

#[test]
fn test_read_cmd_set_ok() {
    let cmd_str = "set x 0 0 3\r\nabc\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let cmd = transport.read_cmd().unwrap();
    assert_eq!(cmd, Cmd::Set(Set::new("x", 0, vec![97, 98, 99])));
}

#[test]
fn test_read_cmd_set_under_size() {
    let cmd_str = "set x 0 0 2\r\nabc\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_cmd().unwrap_err();
    assert_eq!(err, TcpTransportError::CommandParseError);
}

#[test]
fn test_read_cmd_set_over_size() {
    let cmd_str = "set x 0 0 4\r\nabc\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let err = transport.read_cmd().unwrap_err();
    assert_eq!(err, TcpTransportError::StreamReadError);
}

#[test]
fn test_read_cmd_set_malformed() {
    fn try_cmd(cmd: &str) {
        let cmd_str = cmd.to_string();
        let ts = TestStream::new(cmd_str.into_bytes());
        let mut transport = TcpTransport::new(ts);

        let err = transport.read_cmd().unwrap_err();
        assert_eq!(err, TcpTransportError::StreamReadError);
    }

    // Test for truncated stream
    try_cmd("set x 0 0 3\r\nabc\r");
    try_cmd("set x 0 0 3\r\nabc");
    try_cmd("set x 0 0 3\r\nab");
    try_cmd("set x 0 0 3\r\na");
    try_cmd("set x 0 0 3\r\n");
    try_cmd("set x 0 0 3\r");
    try_cmd("set x 0 0 3");
    try_cmd("set x 0 0 ");
    try_cmd("set x 0 0");
    try_cmd("set x 0 ");
    try_cmd("set x 0");
    try_cmd("set x ");
    try_cmd("set x");
    try_cmd("set ");
    try_cmd("set");
}

// Command parsing: Stats

#[test]
fn test_read_cmd_stats() {
    let cmd_str = "stats\r\n".to_string();
    let ts = TestStream::new(cmd_str.into_bytes());
    let mut transport = TcpTransport::new(ts);

    let cmd = transport.read_cmd().unwrap();
    assert_eq!(cmd, Cmd::Stats);
}

// Response writing: Error

#[test]
fn test_write_resp_error() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let resp = Resp::Error;
    transport.write_resp(&resp).unwrap();
    let expected = "ERROR\r\n".to_string().into_bytes();
    assert_eq!(transport.get_stream().outgoing, expected);
}

// Response writing: Stats

#[test]
fn test_write_resp_stats() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let stat = Stat::new("curr_items", "0".to_string());
    let resp = Resp::Stats(vec![stat]);
    transport.write_resp(&resp).unwrap();
    let expected = "STAT curr_items 0\r\nEND\r\n".to_string().into_bytes();
    assert_eq!(transport.get_stream().outgoing, expected);
}

// Response writing: Stored

#[test]
fn test_write_resp_stored() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let resp = Resp::Stored;
    transport.write_resp(&resp).unwrap();
    let expected = "STORED\r\n".to_string().into_bytes();
    assert_eq!(transport.get_stream().outgoing, expected);
}

// Response writing: Value

#[test]
fn test_write_resp_value() {
    let ts = TestStream::new(vec![]);
    let mut transport = TcpTransport::new(ts);

    let resp = Resp::Value(Value::new("x", "abc".to_string().into_bytes()));
    transport.write_resp(&resp).unwrap();
    let expected = "VALUE x 0 3\r\nabc\r\n".to_string().into_bytes();
    assert_eq!(transport.get_stream().outgoing, expected);
}
<|endoftext|>


<commit_before>// Copyright 2016 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.

//! Check license of third-party deps by inspecting src/vendor

use std::fs::File;
use std::io::Read;
use std::path::Path;

static LICENSES: &'static [&'static str] = &[
    "MIT/Apache-2.0",
    "MIT / Apache-2.0",
    "Apache-2.0/MIT",
    "MIT OR Apache-2.0",
    "MIT",
    "Unlicense/MIT",
];

// These are exceptions to Rust's permissive licensing policy, and
// should be considered bugs. Exceptions are only allowed in Rust
// tooling. It is _crucial_ that no exception crates be dependencies
// of the Rust runtime (std / test).
static EXCEPTIONS: &'static [&'static str] = &[
    "mdbook", // MPL2, mdbook
    "openssl", // BSD+advertising clause, cargo, mdbook
    "pest", // MPL2, mdbook via handlebars
    "thread-id", // Apache-2.0, mdbook
    "strings", // this is actually MIT/Apache-2.0 but it's not in the manifest yet
];

pub fn check(path: &Path, bad: &mut bool) {
    let path = path.join("vendor");
    assert!(path.exists(), "vendor directory missing");
    let mut saw_dir = false;
    'next_path: for dir in t!(path.read_dir()) {
        saw_dir = true;
        let dir = t!(dir);

        // skip our exceptions
        for exception in EXCEPTIONS {
            if dir.path()
                .to_str()
                .unwrap()
                .contains(&format!("src/vendor/{}", exception)) {
                continue 'next_path;
            }
        }

        let toml = dir.path().join("Cargo.toml");
        if !check_license(&toml) {
            *bad = true;
        }
    }
    assert!(saw_dir, "no vendored source");
}

fn check_license(path: &Path) -> bool {
    if !path.exists() {
        panic!("{} does not exist", path.display());
    }
    let mut contents = String::new();
    t!(t!(File::open(path)).read_to_string(&mut contents));

    let mut found_license = false;
    for line in contents.lines() {
        if !line.starts_with("license") {
            continue;
        }
        let license = extract_license(line);
        if !LICENSES.contains(&&*license) {
            println!("invalid license {} in {}", license, path.display());
            return false;
        }
        found_license = true;
        break;
    }
    if !found_license {
        println!("no license in {}", path.display());
        return false;
    }

    true
}

fn extract_license(line: &str) -> String {
    let first_quote = line.find('"');
    let last_quote = line.rfind('"');
    if let (Some(f), Some(l)) = (first_quote, last_quote) {
        let license = &line[f + 1 .. l];
        license.into()
    } else {
        "bad-license-parse".into()
    }
}
<commit_msg>Remove exception from license check for strings.rs<commit_after>// Copyright 2016 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.

//! Check license of third-party deps by inspecting src/vendor

use std::fs::File;
use std::io::Read;
use std::path::Path;

static LICENSES: &'static [&'static str] = &[
    "MIT/Apache-2.0",
    "MIT / Apache-2.0",
    "Apache-2.0/MIT",
    "MIT OR Apache-2.0",
    "MIT",
    "Unlicense/MIT",
];

// These are exceptions to Rust's permissive licensing policy, and
// should be considered bugs. Exceptions are only allowed in Rust
// tooling. It is _crucial_ that no exception crates be dependencies
// of the Rust runtime (std / test).
static EXCEPTIONS: &'static [&'static str] = &[
    "mdbook", // MPL2, mdbook
    "openssl", // BSD+advertising clause, cargo, mdbook
    "pest", // MPL2, mdbook via handlebars
    "thread-id", // Apache-2.0, mdbook
];

pub fn check(path: &Path, bad: &mut bool) {
    let path = path.join("vendor");
    assert!(path.exists(), "vendor directory missing");
    let mut saw_dir = false;
    'next_path: for dir in t!(path.read_dir()) {
        saw_dir = true;
        let dir = t!(dir);

        // skip our exceptions
        for exception in EXCEPTIONS {
            if dir.path()
                .to_str()
                .unwrap()
                .contains(&format!("src/vendor/{}", exception)) {
                continue 'next_path;
            }
        }

        let toml = dir.path().join("Cargo.toml");
        if !check_license(&toml) {
            *bad = true;
        }
    }
    assert!(saw_dir, "no vendored source");
}

fn check_license(path: &Path) -> bool {
    if !path.exists() {
        panic!("{} does not exist", path.display());
    }
    let mut contents = String::new();
    t!(t!(File::open(path)).read_to_string(&mut contents));

    let mut found_license = false;
    for line in contents.lines() {
        if !line.starts_with("license") {
            continue;
        }
        let license = extract_license(line);
        if !LICENSES.contains(&&*license) {
            println!("invalid license {} in {}", license, path.display());
            return false;
        }
        found_license = true;
        break;
    }
    if !found_license {
        println!("no license in {}", path.display());
        return false;
    }

    true
}

fn extract_license(line: &str) -> String {
    let first_quote = line.find('"');
    let last_quote = line.rfind('"');
    if let (Some(f), Some(l)) = (first_quote, last_quote) {
        let license = &line[f + 1 .. l];
        license.into()
    } else {
        "bad-license-parse".into()
    }
}
<|endoftext|>