<commit_before>use super::*;

#[test]
fn macro_rules_are_globally_visible() {
    let map = def_map(
        r"
        //- /lib.rs
        macro_rules! structs {
            ($($i:ident),*) => {
                $(struct $i { field: u32 } )*
            }
        }
        structs!(Foo);
        mod nested;

        //- /nested.rs
        structs!(Bar, Baz);
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Foo: t v
   ⋮nested: t
   ⋮
   ⋮crate::nested
   ⋮Bar: t v
   ⋮Baz: t v
    "###);
}

#[test]
fn macro_rules_can_define_modules() {
    let map = def_map(
        r"
        //- /lib.rs
        macro_rules! m {
            ($name:ident) => { mod $name;  }
        }
        m!(n1);

        mod m {
            m!(n3)
        }

        //- /n1.rs
        m!(n2)
        //- /n1/n2.rs
        struct X;
        //- /m/n3.rs
        struct Y;
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮m: t
        ⋮n1: t
        ⋮
        ⋮crate::m
        ⋮n3: t
        ⋮
        ⋮crate::m::n3
        ⋮Y: t v
        ⋮
        ⋮crate::n1
        ⋮n2: t
        ⋮
        ⋮crate::n1::n2
        ⋮X: t v
    "###);
}

#[test]
fn macro_rules_from_other_crates_are_visible() {
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        foo::structs!(Foo, Bar)
        mod bar;

        //- /bar.rs
        use crate::*;

        //- /lib.rs crate:foo
        #[macro_export]
        macro_rules! structs {
            ($($i:ident),*) => {
                $(struct $i { field: u32 } )*
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Bar: t v
   ⋮Foo: t v
   ⋮bar: t
   ⋮
   ⋮crate::bar
   ⋮Bar: t v
   ⋮Foo: t v
   ⋮bar: t
    "###);
}

#[test]
fn macro_rules_export_with_local_inner_macros_are_visible() {
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        foo::structs!(Foo, Bar)
        mod bar;

        //- /bar.rs
        use crate::*;

        //- /lib.rs crate:foo
        #[macro_export(local_inner_macros)]
        macro_rules! structs {
            ($($i:ident),*) => {
                $(struct $i { field: u32 } )*
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Bar: t v
   ⋮Foo: t v
   ⋮bar: t
   ⋮
   ⋮crate::bar
   ⋮Bar: t v
   ⋮Foo: t v
   ⋮bar: t
    "###);
}

#[test]
fn local_inner_macros_makes_local_macros_usable() {
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        foo::structs!(Foo, Bar);
        mod bar;
        //- /bar.rs
        use crate::*;
        //- /lib.rs crate:foo
        #[macro_export(local_inner_macros)]
        macro_rules! structs {
            ($($i:ident),*) => {
                inner!($($i),*);
            }
        }
        #[macro_export]
        macro_rules! inner {
            ($($i:ident),*) => {
                $(struct $i { field: u32 } )*
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Bar: t v
   ⋮Foo: t v
   ⋮bar: t
   ⋮
   ⋮crate::bar
   ⋮Bar: t v
   ⋮Foo: t v
   ⋮bar: t
    "###);
}

#[test]
fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        macro_rules! baz {
            () => {
                use foo::bar;
            }
        }

        foo!();
        bar!();
        baz!();

        //- /lib.rs crate:foo
        #[macro_export]
        macro_rules! foo {
            () => {
                struct Foo { field: u32 }
            }
        }
        #[macro_export]
        macro_rules! bar {
            () => {
                use foo::foo;
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Foo: t v
   ⋮bar: m
   ⋮foo: m
    "###);
}

#[test]
fn macro_rules_from_other_crates_are_visible_with_macro_use() {
    covers!(macro_rules_from_other_crates_are_visible_with_macro_use);
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        structs!(Foo);
        structs_priv!(Bar);
        structs_not_exported!(MacroNotResolved1);
        crate::structs!(MacroNotResolved2);

        mod bar;

        #[macro_use]
        extern crate foo;

        //- /bar.rs
        structs!(Baz);
        crate::structs!(MacroNotResolved3);

        //- /lib.rs crate:foo
        #[macro_export]
        macro_rules! structs {
            ($i:ident) => { struct $i; }
        }

        macro_rules! structs_not_exported {
            ($i:ident) => { struct $i; }
        }

        mod priv_mod {
            #[macro_export]
            macro_rules! structs_priv {
                ($i:ident) => { struct $i; }
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Bar: t v
   ⋮Foo: t v
   ⋮bar: t
   ⋮foo: t
   ⋮
   ⋮crate::bar
   ⋮Baz: t v
    "###);
}

#[test]
fn prelude_is_macro_use() {
    covers!(prelude_is_macro_use);
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        structs!(Foo);
        structs_priv!(Bar);
        structs_outside!(Out);
        crate::structs!(MacroNotResolved2);

        mod bar;

        //- /bar.rs
        structs!(Baz);
        crate::structs!(MacroNotResolved3);

        //- /lib.rs crate:foo
        #[prelude_import]
        use self::prelude::*;

        mod prelude {
            #[macro_export]
            macro_rules! structs {
                ($i:ident) => { struct $i; }
            }

            mod priv_mod {
                #[macro_export]
                macro_rules! structs_priv {
                    ($i:ident) => { struct $i; }
                }
            }
        }

        #[macro_export]
        macro_rules! structs_outside {
            ($i:ident) => { struct $i; }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Bar: t v
   ⋮Foo: t v
   ⋮Out: t v
   ⋮bar: t
   ⋮
   ⋮crate::bar
   ⋮Baz: t v
    "###);
}

#[test]
fn prelude_cycle() {
    let map = def_map(
        "
        //- /lib.rs
        #[prelude_import]
        use self::prelude::*;

        declare_mod!();

        mod prelude {
            macro_rules! declare_mod {
                () => (mod foo {})
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮prelude: t
        ⋮
        ⋮crate::prelude
    "###);
}

#[test]
fn plain_macros_are_legacy_textual_scoped() {
    let map = def_map(
        r#"
        //- /main.rs
        mod m1;
        bar!(NotFoundNotMacroUse);

        mod m2 {
            foo!(NotFoundBeforeInside2);
        }

        macro_rules! foo {
            ($x:ident) => { struct $x; }
        }
        foo!(Ok);

        mod m3;
        foo!(OkShadowStop);
        bar!(NotFoundMacroUseStop);

        #[macro_use]
        mod m5 {
            #[macro_use]
            mod m6 {
                macro_rules! foo {
                    ($x:ident) => { fn $x() {} }
                }
            }
        }
        foo!(ok_double_macro_use_shadow);

        baz!(NotFoundBefore);
        #[macro_use]
        mod m7 {
            macro_rules! baz {
                ($x:ident) => { struct $x; }
            }
        }
        baz!(OkAfter);

        //- /m1.rs
        foo!(NotFoundBeforeInside1);
        macro_rules! bar {
            ($x:ident) => { struct $x; }
        }

        //- /m3/mod.rs
        foo!(OkAfterInside);
        macro_rules! foo {
            ($x:ident) => { fn $x() {} }
        }
        foo!(ok_shadow);

        #[macro_use]
        mod m4;
        bar!(OkMacroUse);

        //- /m3/m4.rs
        foo!(ok_shadow_deep);
        macro_rules! bar {
            ($x:ident) => { struct $x; }
        }
        "#,
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Ok: t v
   ⋮OkAfter: t v
   ⋮OkShadowStop: t v
   ⋮m1: t
   ⋮m2: t
   ⋮m3: t
   ⋮m5: t
   ⋮m7: t
   ⋮ok_double_macro_use_shadow: v
   ⋮
   ⋮crate::m7
   ⋮
   ⋮crate::m1
   ⋮
   ⋮crate::m5
   ⋮m6: t
   ⋮
   ⋮crate::m5::m6
   ⋮
   ⋮crate::m2
   ⋮
   ⋮crate::m3
   ⋮OkAfterInside: t v
   ⋮OkMacroUse: t v
   ⋮m4: t
   ⋮ok_shadow: v
   ⋮
   ⋮crate::m3::m4
   ⋮ok_shadow_deep: v
    "###);
}

#[test]
fn type_value_macro_live_in_different_scopes() {
    let map = def_map(
        "
        //- /main.rs
        #[macro_export]
        macro_rules! foo {
            ($x:ident) => { type $x = (); }
        }

        foo!(foo);
        use foo as bar;

        use self::foo as baz;
        fn baz() {}
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮bar: t m
        ⋮baz: t v m
        ⋮foo: t m
    "###);
}

#[test]
fn macro_use_can_be_aliased() {
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        #[macro_use]
        extern crate foo;

        foo!(Direct);
        bar!(Alias);

        //- /lib.rs crate:foo
        use crate::foo as bar;

        mod m {
            #[macro_export]
            macro_rules! foo {
                ($x:ident) => { struct $x; }
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮Alias: t v
        ⋮Direct: t v
        ⋮foo: t
    "###);
}

#[test]
fn path_qualified_macros() {
    let map = def_map(
        "
        //- /main.rs
        macro_rules! foo {
            ($x:ident) => { struct $x; }
        }

        crate::foo!(NotResolved);

        crate::bar!(OkCrate);
        bar!(OkPlain);
        alias1!(NotHere);
        m::alias1!(OkAliasPlain);
        m::alias2!(OkAliasSuper);
        m::alias3!(OkAliasCrate);
        not_found!(NotFound);

        mod m {
            #[macro_export]
            macro_rules! bar {
                ($x:ident) => { struct $x; }
            }

            pub use bar as alias1;
            pub use super::bar as alias2;
            pub use crate::bar as alias3;
            pub use self::bar as not_found;
        }
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮OkAliasCrate: t v
        ⋮OkAliasPlain: t v
        ⋮OkAliasSuper: t v
        ⋮OkCrate: t v
        ⋮OkPlain: t v
        ⋮bar: m
        ⋮m: t
        ⋮
        ⋮crate::m
        ⋮alias1: m
        ⋮alias2: m
        ⋮alias3: m
        ⋮not_found: _
    "###);
}

#[test]
fn macro_dollar_crate_is_correct_in_item() {
    covers!(macro_dollar_crate_self);
    covers!(macro_dollar_crate_other);
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        #[macro_use]
        extern crate foo;

        #[macro_use]
        mod m {
            macro_rules! current {
                () => {
                    use $crate::Foo as FooSelf;
                }
            }
        }

        struct Foo;

        current!();
        not_current1!();
        foo::not_current2!();

        //- /lib.rs crate:foo
        mod m {
            #[macro_export]
            macro_rules! not_current1 {
                () => {
                    use $crate::Bar;
                }
            }
        }

        #[macro_export]
        macro_rules! not_current2 {
            () => {
                use $crate::Baz;
            }
        }

        struct Bar;
        struct Baz;
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮Bar: t v
        ⋮Baz: t v
        ⋮Foo: t v
        ⋮FooSelf: t v
        ⋮foo: t
        ⋮m: t
        ⋮
        ⋮crate::m
    "###);
}

#[test]
fn macro_dollar_crate_is_correct_in_indirect_deps() {
    covers!(macro_dollar_crate_other);
    // From std
    let map = def_map(
        r#"
        //- /main.rs crate:main deps:std
        foo!();

        //- /std.rs crate:std deps:core
        #[prelude_import]
        use self::prelude::*;

        pub use core::foo;

        mod prelude {}

        #[macro_use]
        mod std_macros;

        //- /core.rs crate:core
        #[macro_export]
        macro_rules! foo {
            () => {
                use $crate::bar;
            }
        }

        pub struct bar;
        "#,
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮bar: t v
    "###);
}

#[test]
fn expand_derive() {
    let map = compute_crate_def_map(
        "
        //- /main.rs
        #[derive(Clone)]
        struct Foo;
        ",
    );
    assert_eq!(map.modules[map.root].scope.impls().len(), 1);
}

#[test]
fn expand_multiple_derive() {
    let map = compute_crate_def_map(
        "
        //- /main.rs
        #[derive(Copy, Clone)]
        struct Foo;
        ",
    );
    assert_eq!(map.modules[map.root].scope.impls().len(), 2);
}
<commit_msg>Fix test<commit_after>use super::*;

#[test]
fn macro_rules_are_globally_visible() {
    let map = def_map(
        r"
        //- /lib.rs
        macro_rules! structs {
            ($($i:ident),*) => {
                $(struct $i { field: u32 } )*
            }
        }
        structs!(Foo);
        mod nested;

        //- /nested.rs
        structs!(Bar, Baz);
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Foo: t
   ⋮nested: t
   ⋮
   ⋮crate::nested
   ⋮Bar: t
   ⋮Baz: t
    "###);
}

#[test]
fn macro_rules_can_define_modules() {
    let map = def_map(
        r"
        //- /lib.rs
        macro_rules! m {
            ($name:ident) => { mod $name;  }
        }
        m!(n1);

        mod m {
            m!(n3)
        }

        //- /n1.rs
        m!(n2)
        //- /n1/n2.rs
        struct X;
        //- /m/n3.rs
        struct Y;
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮m: t
        ⋮n1: t
        ⋮
        ⋮crate::m
        ⋮n3: t
        ⋮
        ⋮crate::m::n3
        ⋮Y: t v
        ⋮
        ⋮crate::n1
        ⋮n2: t
        ⋮
        ⋮crate::n1::n2
        ⋮X: t v
    "###);
}

#[test]
fn macro_rules_from_other_crates_are_visible() {
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        foo::structs!(Foo, Bar)
        mod bar;

        //- /bar.rs
        use crate::*;

        //- /lib.rs crate:foo
        #[macro_export]
        macro_rules! structs {
            ($($i:ident),*) => {
                $(struct $i { field: u32 } )*
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Bar: t
   ⋮Foo: t
   ⋮bar: t
   ⋮
   ⋮crate::bar
   ⋮Bar: t
   ⋮Foo: t
   ⋮bar: t
    "###);
}

#[test]
fn macro_rules_export_with_local_inner_macros_are_visible() {
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        foo::structs!(Foo, Bar)
        mod bar;

        //- /bar.rs
        use crate::*;

        //- /lib.rs crate:foo
        #[macro_export(local_inner_macros)]
        macro_rules! structs {
            ($($i:ident),*) => {
                $(struct $i { field: u32 } )*
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Bar: t
   ⋮Foo: t
   ⋮bar: t
   ⋮
   ⋮crate::bar
   ⋮Bar: t
   ⋮Foo: t
   ⋮bar: t
    "###);
}

#[test]
fn local_inner_macros_makes_local_macros_usable() {
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        foo::structs!(Foo, Bar);
        mod bar;
        //- /bar.rs
        use crate::*;
        //- /lib.rs crate:foo
        #[macro_export(local_inner_macros)]
        macro_rules! structs {
            ($($i:ident),*) => {
                inner!($($i),*);
            }
        }
        #[macro_export]
        macro_rules! inner {
            ($($i:ident),*) => {
                $(struct $i { field: u32 } )*
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Bar: t
   ⋮Foo: t
   ⋮bar: t
   ⋮
   ⋮crate::bar
   ⋮Bar: t
   ⋮Foo: t
   ⋮bar: t
    "###);
}

#[test]
fn unexpanded_macro_should_expand_by_fixedpoint_loop() {
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        macro_rules! baz {
            () => {
                use foo::bar;
            }
        }

        foo!();
        bar!();
        baz!();

        //- /lib.rs crate:foo
        #[macro_export]
        macro_rules! foo {
            () => {
                struct Foo { field: u32 }
            }
        }
        #[macro_export]
        macro_rules! bar {
            () => {
                use foo::foo;
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Foo: t
   ⋮bar: m
   ⋮foo: m
    "###);
}

#[test]
fn macro_rules_from_other_crates_are_visible_with_macro_use() {
    covers!(macro_rules_from_other_crates_are_visible_with_macro_use);
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        structs!(Foo);
        structs_priv!(Bar);
        structs_not_exported!(MacroNotResolved1);
        crate::structs!(MacroNotResolved2);

        mod bar;

        #[macro_use]
        extern crate foo;

        //- /bar.rs
        structs!(Baz);
        crate::structs!(MacroNotResolved3);

        //- /lib.rs crate:foo
        #[macro_export]
        macro_rules! structs {
            ($i:ident) => { struct $i; }
        }

        macro_rules! structs_not_exported {
            ($i:ident) => { struct $i; }
        }

        mod priv_mod {
            #[macro_export]
            macro_rules! structs_priv {
                ($i:ident) => { struct $i; }
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Bar: t v
   ⋮Foo: t v
   ⋮bar: t
   ⋮foo: t
   ⋮
   ⋮crate::bar
   ⋮Baz: t v
    "###);
}

#[test]
fn prelude_is_macro_use() {
    covers!(prelude_is_macro_use);
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        structs!(Foo);
        structs_priv!(Bar);
        structs_outside!(Out);
        crate::structs!(MacroNotResolved2);

        mod bar;

        //- /bar.rs
        structs!(Baz);
        crate::structs!(MacroNotResolved3);

        //- /lib.rs crate:foo
        #[prelude_import]
        use self::prelude::*;

        mod prelude {
            #[macro_export]
            macro_rules! structs {
                ($i:ident) => { struct $i; }
            }

            mod priv_mod {
                #[macro_export]
                macro_rules! structs_priv {
                    ($i:ident) => { struct $i; }
                }
            }
        }

        #[macro_export]
        macro_rules! structs_outside {
            ($i:ident) => { struct $i; }
        }
        ",
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Bar: t v
   ⋮Foo: t v
   ⋮Out: t v
   ⋮bar: t
   ⋮
   ⋮crate::bar
   ⋮Baz: t v
    "###);
}

#[test]
fn prelude_cycle() {
    let map = def_map(
        "
        //- /lib.rs
        #[prelude_import]
        use self::prelude::*;

        declare_mod!();

        mod prelude {
            macro_rules! declare_mod {
                () => (mod foo {})
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮prelude: t
        ⋮
        ⋮crate::prelude
    "###);
}

#[test]
fn plain_macros_are_legacy_textual_scoped() {
    let map = def_map(
        r#"
        //- /main.rs
        mod m1;
        bar!(NotFoundNotMacroUse);

        mod m2 {
            foo!(NotFoundBeforeInside2);
        }

        macro_rules! foo {
            ($x:ident) => { struct $x; }
        }
        foo!(Ok);

        mod m3;
        foo!(OkShadowStop);
        bar!(NotFoundMacroUseStop);

        #[macro_use]
        mod m5 {
            #[macro_use]
            mod m6 {
                macro_rules! foo {
                    ($x:ident) => { fn $x() {} }
                }
            }
        }
        foo!(ok_double_macro_use_shadow);

        baz!(NotFoundBefore);
        #[macro_use]
        mod m7 {
            macro_rules! baz {
                ($x:ident) => { struct $x; }
            }
        }
        baz!(OkAfter);

        //- /m1.rs
        foo!(NotFoundBeforeInside1);
        macro_rules! bar {
            ($x:ident) => { struct $x; }
        }

        //- /m3/mod.rs
        foo!(OkAfterInside);
        macro_rules! foo {
            ($x:ident) => { fn $x() {} }
        }
        foo!(ok_shadow);

        #[macro_use]
        mod m4;
        bar!(OkMacroUse);

        //- /m3/m4.rs
        foo!(ok_shadow_deep);
        macro_rules! bar {
            ($x:ident) => { struct $x; }
        }
        "#,
    );
    assert_snapshot!(map, @r###"
   ⋮crate
   ⋮Ok: t v
   ⋮OkAfter: t v
   ⋮OkShadowStop: t v
   ⋮m1: t
   ⋮m2: t
   ⋮m3: t
   ⋮m5: t
   ⋮m7: t
   ⋮ok_double_macro_use_shadow: v
   ⋮
   ⋮crate::m7
   ⋮
   ⋮crate::m1
   ⋮
   ⋮crate::m5
   ⋮m6: t
   ⋮
   ⋮crate::m5::m6
   ⋮
   ⋮crate::m2
   ⋮
   ⋮crate::m3
   ⋮OkAfterInside: t v
   ⋮OkMacroUse: t v
   ⋮m4: t
   ⋮ok_shadow: v
   ⋮
   ⋮crate::m3::m4
   ⋮ok_shadow_deep: v
    "###);
}

#[test]
fn type_value_macro_live_in_different_scopes() {
    let map = def_map(
        "
        //- /main.rs
        #[macro_export]
        macro_rules! foo {
            ($x:ident) => { type $x = (); }
        }

        foo!(foo);
        use foo as bar;

        use self::foo as baz;
        fn baz() {}
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮bar: t m
        ⋮baz: t v m
        ⋮foo: t m
    "###);
}

#[test]
fn macro_use_can_be_aliased() {
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        #[macro_use]
        extern crate foo;

        foo!(Direct);
        bar!(Alias);

        //- /lib.rs crate:foo
        use crate::foo as bar;

        mod m {
            #[macro_export]
            macro_rules! foo {
                ($x:ident) => { struct $x; }
            }
        }
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮Alias: t v
        ⋮Direct: t v
        ⋮foo: t
    "###);
}

#[test]
fn path_qualified_macros() {
    let map = def_map(
        "
        //- /main.rs
        macro_rules! foo {
            ($x:ident) => { struct $x; }
        }

        crate::foo!(NotResolved);

        crate::bar!(OkCrate);
        bar!(OkPlain);
        alias1!(NotHere);
        m::alias1!(OkAliasPlain);
        m::alias2!(OkAliasSuper);
        m::alias3!(OkAliasCrate);
        not_found!(NotFound);

        mod m {
            #[macro_export]
            macro_rules! bar {
                ($x:ident) => { struct $x; }
            }

            pub use bar as alias1;
            pub use super::bar as alias2;
            pub use crate::bar as alias3;
            pub use self::bar as not_found;
        }
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮OkAliasCrate: t v
        ⋮OkAliasPlain: t v
        ⋮OkAliasSuper: t v
        ⋮OkCrate: t v
        ⋮OkPlain: t v
        ⋮bar: m
        ⋮m: t
        ⋮
        ⋮crate::m
        ⋮alias1: m
        ⋮alias2: m
        ⋮alias3: m
        ⋮not_found: _
    "###);
}

#[test]
fn macro_dollar_crate_is_correct_in_item() {
    covers!(macro_dollar_crate_self);
    covers!(macro_dollar_crate_other);
    let map = def_map(
        "
        //- /main.rs crate:main deps:foo
        #[macro_use]
        extern crate foo;

        #[macro_use]
        mod m {
            macro_rules! current {
                () => {
                    use $crate::Foo as FooSelf;
                }
            }
        }

        struct Foo;

        current!();
        not_current1!();
        foo::not_current2!();

        //- /lib.rs crate:foo
        mod m {
            #[macro_export]
            macro_rules! not_current1 {
                () => {
                    use $crate::Bar;
                }
            }
        }

        #[macro_export]
        macro_rules! not_current2 {
            () => {
                use $crate::Baz;
            }
        }

        struct Bar;
        struct Baz;
        ",
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮Bar: t v
        ⋮Baz: t v
        ⋮Foo: t v
        ⋮FooSelf: t v
        ⋮foo: t
        ⋮m: t
        ⋮
        ⋮crate::m
    "###);
}

#[test]
fn macro_dollar_crate_is_correct_in_indirect_deps() {
    covers!(macro_dollar_crate_other);
    // From std
    let map = def_map(
        r#"
        //- /main.rs crate:main deps:std
        foo!();

        //- /std.rs crate:std deps:core
        #[prelude_import]
        use self::prelude::*;

        pub use core::foo;

        mod prelude {}

        #[macro_use]
        mod std_macros;

        //- /core.rs crate:core
        #[macro_export]
        macro_rules! foo {
            () => {
                use $crate::bar;
            }
        }

        pub struct bar;
        "#,
    );
    assert_snapshot!(map, @r###"
        ⋮crate
        ⋮bar: t v
    "###);
}

#[test]
fn expand_derive() {
    let map = compute_crate_def_map(
        "
        //- /main.rs
        #[derive(Clone)]
        struct Foo;
        ",
    );
    assert_eq!(map.modules[map.root].scope.impls().len(), 1);
}

#[test]
fn expand_multiple_derive() {
    let map = compute_crate_def_map(
        "
        //- /main.rs
        #[derive(Copy, Clone)]
        struct Foo;
        ",
    );
    assert_eq!(map.modules[map.root].scope.impls().len(), 2);
}
<|endoftext|>


<commit_before>mod add;
mod build;
mod cmin;
mod fmt;
mod init;
mod list;
mod run;
mod tmin;

pub use self::{
    add::Add, build::Build, cmin::Cmin, fmt::Fmt, init::Init, list::List, run::Run, tmin::Tmin,
};

use std::fmt as stdfmt;
use std::str::FromStr;
use structopt::StructOpt;

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Sanitizer {
    Address,
    Leak,
    Memory,
    Thread,
    None,
}

impl stdfmt::Display for Sanitizer {
    fn fmt(&self, f: &mut stdfmt::Formatter) -> stdfmt::Result {
        write!(
            f,
            "{}",
            match self {
                Sanitizer::Address => "address",
                Sanitizer::Leak => "leak",
                Sanitizer::Memory => "memory",
                Sanitizer::Thread => "thread",
                Sanitizer::None => "",
            }
        )
    }
}

impl FromStr for Sanitizer {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "address" => Ok(Sanitizer::Address),
            "leak" => Ok(Sanitizer::Leak),
            "memory" => Ok(Sanitizer::Memory),
            "thread" => Ok(Sanitizer::Thread),
            "none" => Ok(Sanitizer::None),
            _ => Err(format!("unknown sanitizer: {}", s)),
        }
    }
}

#[derive(Clone, Debug, StructOpt, PartialEq)]
pub struct BuildOptions {
    #[structopt(short = "D", long = "dev", conflicts_with = "release")]
    /// Build artifacts in development mode, without optimizations
    pub dev: bool,

    #[structopt(short = "O", long = "release", conflicts_with = "dev")]
    /// Build artifacts in release mode, with optimizations
    pub release: bool,

    #[structopt(short = "a", long = "debug-assertions")]
    /// Build artifacts with debug assertions and overflow checks enabled (default if not -O)
    pub debug_assertions: bool,

    /// Build target with verbose output from `cargo build`
    #[structopt(short = "v", long = "verbose")]
    pub verbose: bool,

    #[structopt(long = "no-default-features")]
    /// Build artifacts with default Cargo features disabled
    pub no_default_features: bool,

    #[structopt(
        long = "all-features",
        conflicts_with = "no-default-features",
        conflicts_with = "features"
    )]
    /// Build artifacts with all Cargo features enabled
    pub all_features: bool,

    #[structopt(long = "features")]
    /// Build artifacts with given Cargo feature enabled
    pub features: Option<String>,

    #[structopt(
        short = "s",
        long = "sanitizer",
        possible_values(&["address", "leak", "memory", "thread", "none"]),
        default_value = "address",
    )]
    /// Use a specific sanitizer
    pub sanitizer: Sanitizer,

    #[structopt(
        name = "triple",
        long = "target",
        default_value(crate::utils::default_target())
    )]
    /// Target triple of the fuzz target
    pub triple: String,

    #[structopt(short = "Z", value_name = "FLAG")]
    /// Unstable (nightly-only) flags to Cargo
    pub unstable_flags: Vec<String>,

    #[structopt(long = "target-dir")]
    /// Target dir option to pass to cargo build.
    pub target_dir: Option<String>,

    #[structopt(long = "coverage")]
    /// Instrument program code with source-based code coverage information.
    /// The profiler data will be saved in the given file.
    pub coverage_output_file: Option<String>,
}

impl stdfmt::Display for BuildOptions {
    fn fmt(&self, f: &mut stdfmt::Formatter) -> stdfmt::Result {
        if self.dev {
            write!(f, " -D")?;
        }

        if self.release {
            write!(f, " -O")?;
        }

        if self.debug_assertions {
            write!(f, " -a")?;
        }

        if self.verbose {
            write!(f, " -v")?;
        }

        if self.no_default_features {
            write!(f, " --no-default-features")?;
        }

        if self.all_features {
            write!(f, " --all-features")?;
        }

        if let Some(feature) = &self.features {
            write!(f, " --features={}", feature)?;
        }

        match self.sanitizer {
            Sanitizer::None => write!(f, " --sanitizer=none")?,
            Sanitizer::Address => {}
            _ => write!(f, " --sanitizer={}", self.sanitizer)?,
        }

        if self.triple != crate::utils::default_target() {
            write!(f, " --target={}", self.triple)?;
        }

        for flag in &self.unstable_flags {
            write!(f, " -Z{}", flag)?;
        }

        if let Some(target_dir) = &self.target_dir {
            write!(f, " --target-dir={}", target_dir)?;
        }

        if let Some(filename) = &self.coverage_output_file {
            write!(f, "  --coverage={}", filename)?;
        }

        Ok(())
    }
}

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

    #[test]
    fn display_build_options() {
        let default_opts = BuildOptions {
            dev: false,
            release: false,
            debug_assertions: false,
            verbose: false,
            no_default_features: false,
            all_features: false,
            features: None,
            sanitizer: Sanitizer::Address,
            triple: String::from(crate::utils::default_target()),
            unstable_flags: Vec::new(),
            target_dir: None,
            coverage_output_file: None,
        };

        let opts = vec![
            default_opts.clone(),
            BuildOptions {
                dev: true,
                ..default_opts.clone()
            },
            BuildOptions {
                release: true,
                ..default_opts.clone()
            },
            BuildOptions {
                debug_assertions: true,
                ..default_opts.clone()
            },
            BuildOptions {
                verbose: true,
                ..default_opts.clone()
            },
            BuildOptions {
                no_default_features: true,
                ..default_opts.clone()
            },
            BuildOptions {
                all_features: true,
                ..default_opts.clone()
            },
            BuildOptions {
                features: Some(String::from("features")),
                ..default_opts.clone()
            },
            BuildOptions {
                sanitizer: Sanitizer::None,
                ..default_opts.clone()
            },
            BuildOptions {
                triple: String::from("custom_triple"),
                ..default_opts.clone()
            },
            BuildOptions {
                unstable_flags: vec![String::from("unstable"), String::from("flags")],
                ..default_opts.clone()
            },
            BuildOptions {
                target_dir: Some(String::from("/tmp/test")),
                ..default_opts
            },
            BuildOptions {
                coverage_output_file: None,
                ..default_opts.clone()
            },
        ];

        for case in opts {
            assert_eq!(
                case,
                BuildOptions::from_clap(
                    &BuildOptions::clap().get_matches_from(case.to_string().split(' '))
                )
            );
        }
    }
}
<commit_msg>Fixed borrowing error.<commit_after>mod add;
mod build;
mod cmin;
mod fmt;
mod init;
mod list;
mod run;
mod tmin;

pub use self::{
    add::Add, build::Build, cmin::Cmin, fmt::Fmt, init::Init, list::List, run::Run, tmin::Tmin,
};

use std::fmt as stdfmt;
use std::str::FromStr;
use structopt::StructOpt;

#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Sanitizer {
    Address,
    Leak,
    Memory,
    Thread,
    None,
}

impl stdfmt::Display for Sanitizer {
    fn fmt(&self, f: &mut stdfmt::Formatter) -> stdfmt::Result {
        write!(
            f,
            "{}",
            match self {
                Sanitizer::Address => "address",
                Sanitizer::Leak => "leak",
                Sanitizer::Memory => "memory",
                Sanitizer::Thread => "thread",
                Sanitizer::None => "",
            }
        )
    }
}

impl FromStr for Sanitizer {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "address" => Ok(Sanitizer::Address),
            "leak" => Ok(Sanitizer::Leak),
            "memory" => Ok(Sanitizer::Memory),
            "thread" => Ok(Sanitizer::Thread),
            "none" => Ok(Sanitizer::None),
            _ => Err(format!("unknown sanitizer: {}", s)),
        }
    }
}

#[derive(Clone, Debug, StructOpt, PartialEq)]
pub struct BuildOptions {
    #[structopt(short = "D", long = "dev", conflicts_with = "release")]
    /// Build artifacts in development mode, without optimizations
    pub dev: bool,

    #[structopt(short = "O", long = "release", conflicts_with = "dev")]
    /// Build artifacts in release mode, with optimizations
    pub release: bool,

    #[structopt(short = "a", long = "debug-assertions")]
    /// Build artifacts with debug assertions and overflow checks enabled (default if not -O)
    pub debug_assertions: bool,

    /// Build target with verbose output from `cargo build`
    #[structopt(short = "v", long = "verbose")]
    pub verbose: bool,

    #[structopt(long = "no-default-features")]
    /// Build artifacts with default Cargo features disabled
    pub no_default_features: bool,

    #[structopt(
        long = "all-features",
        conflicts_with = "no-default-features",
        conflicts_with = "features"
    )]
    /// Build artifacts with all Cargo features enabled
    pub all_features: bool,

    #[structopt(long = "features")]
    /// Build artifacts with given Cargo feature enabled
    pub features: Option<String>,

    #[structopt(
        short = "s",
        long = "sanitizer",
        possible_values(&["address", "leak", "memory", "thread", "none"]),
        default_value = "address",
    )]
    /// Use a specific sanitizer
    pub sanitizer: Sanitizer,

    #[structopt(
        name = "triple",
        long = "target",
        default_value(crate::utils::default_target())
    )]
    /// Target triple of the fuzz target
    pub triple: String,

    #[structopt(short = "Z", value_name = "FLAG")]
    /// Unstable (nightly-only) flags to Cargo
    pub unstable_flags: Vec<String>,

    #[structopt(long = "target-dir")]
    /// Target dir option to pass to cargo build.
    pub target_dir: Option<String>,

    #[structopt(long = "coverage")]
    /// Instrument program code with source-based code coverage information.
    /// The profiler data will be saved in the given file.
    pub coverage_output_file: Option<String>,
}

impl stdfmt::Display for BuildOptions {
    fn fmt(&self, f: &mut stdfmt::Formatter) -> stdfmt::Result {
        if self.dev {
            write!(f, " -D")?;
        }

        if self.release {
            write!(f, " -O")?;
        }

        if self.debug_assertions {
            write!(f, " -a")?;
        }

        if self.verbose {
            write!(f, " -v")?;
        }

        if self.no_default_features {
            write!(f, " --no-default-features")?;
        }

        if self.all_features {
            write!(f, " --all-features")?;
        }

        if let Some(feature) = &self.features {
            write!(f, " --features={}", feature)?;
        }

        match self.sanitizer {
            Sanitizer::None => write!(f, " --sanitizer=none")?,
            Sanitizer::Address => {}
            _ => write!(f, " --sanitizer={}", self.sanitizer)?,
        }

        if self.triple != crate::utils::default_target() {
            write!(f, " --target={}", self.triple)?;
        }

        for flag in &self.unstable_flags {
            write!(f, " -Z{}", flag)?;
        }

        if let Some(target_dir) = &self.target_dir {
            write!(f, " --target-dir={}", target_dir)?;
        }

        if let Some(filename) = &self.coverage_output_file {
            write!(f, "  --coverage={}", filename)?;
        }

        Ok(())
    }
}

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

    #[test]
    fn display_build_options() {
        let default_opts = BuildOptions {
            dev: false,
            release: false,
            debug_assertions: false,
            verbose: false,
            no_default_features: false,
            all_features: false,
            features: None,
            sanitizer: Sanitizer::Address,
            triple: String::from(crate::utils::default_target()),
            unstable_flags: Vec::new(),
            target_dir: None,
            coverage_output_file: None,
        };

        let opts = vec![
            default_opts.clone(),
            BuildOptions {
                dev: true,
                ..default_opts.clone()
            },
            BuildOptions {
                release: true,
                ..default_opts.clone()
            },
            BuildOptions {
                debug_assertions: true,
                ..default_opts.clone()
            },
            BuildOptions {
                verbose: true,
                ..default_opts.clone()
            },
            BuildOptions {
                no_default_features: true,
                ..default_opts.clone()
            },
            BuildOptions {
                all_features: true,
                ..default_opts.clone()
            },
            BuildOptions {
                features: Some(String::from("features")),
                ..default_opts.clone()
            },
            BuildOptions {
                sanitizer: Sanitizer::None,
                ..default_opts.clone()
            },
            BuildOptions {
                triple: String::from("custom_triple"),
                ..default_opts.clone()
            },
            BuildOptions {
                unstable_flags: vec![String::from("unstable"), String::from("flags")],
                ..default_opts.clone()
            },
            BuildOptions {
                target_dir: Some(String::from("/tmp/test")),
                ..default_opts.clone()
            },
            BuildOptions {
                coverage_output_file: None,
                ..default_opts
            },
        ];

        for case in opts {
            assert_eq!(
                case,
                BuildOptions::from_clap(
                    &BuildOptions::clap().get_matches_from(case.to_string().split(' '))
                )
            );
        }
    }
}
<|endoftext|>


<commit_before>#![feature(libc,question_mark)]
extern crate libc;

use std::any::Any;
use std::fs;
use std::io;
use std::io::Read;
use std::path::Path;
use std::process::{Command, Stdio};
use std::str::from_utf8_unchecked;

/// Shortcut to path->filename conversion.
///
/// Returns the unchanged `path` if there is a character encoding error or something.
pub fn filename<'a> (path: &'a str) -> &'a str {
  match Path::new (path) .file_name() {
    Some (filename) => match filename.to_str() {
      Some (fstr) => if fstr.ends_with (".rs") {&fstr[0 .. fstr.len() - 3]} else {fstr},
      None => path},
    None => path}}

mod gstuff {pub fn filename<'a> (path: &'a str) -> &'a str {super::filename (path)}}

// A trick to use the `try_s` macro from both the outside and inside of the crate.
//mod gstuff {pub fn filename<'a> (path: &'a str) -> &'a str {::filename (path)}}

/// Returns on error, converting the `Err` value to `String` and prepending the current location.
///
/// cf. http://www.reddit.com/r/rust/comments/29wwzw/error_handling_and_result_types/cipcm9a
#[macro_export] macro_rules! try_s {
  ($e: expr) => {match $e {Ok (ok) => ok, Err (err) => {return Err (format! ("{}:{}] {}", ::gstuff::filename (file!()), line!(), err));}}}}

/// Returns on error, prepending the current location to a stringified error, then passing the string to `From::from`.
#[macro_export] macro_rules! try_f {
  ($e: expr) => {match $e {
    Ok (ok) => ok,
    Err (err) => {return Err (From::from (format! ("{}:{}] {}", ::gstuff::filename (file!()), line!(), err)));}}}}

// Like `try_s`, but takes a reference.
#[macro_export] macro_rules! try_sp {
  ($e: expr) => {match $e {&Ok (ref ok) => ok,
    &Err (ref err) => {return Err (format! ("{}:{}] {:?}", ::gstuff::filename (file!()), line!(), err));}}}}

/// Returns a `Err(String)`, prepending the current location (file name and line number) to the string.
///
/// Examples: `ERR! ("too bad")`; `ERR! ("{}", foo)`;
#[macro_export] macro_rules! ERR {
  ($format: expr, $($args: tt)+) => {Err (format! (concat! ("{}:{}] ", $format), ::gstuff::filename (file!()), line!(), $($args)+))};
  ($format: expr) => {Err (format! (concat! ("{}:{}] ", $format), ::gstuff::filename (file!()), line!()))}}

/// A helper to build a string on the stack.
///
/// Given an array it makes a writeable cursor available to the passed code block.
///
/// Returns a &str slice pointing at memory between the array start and the cursor.
///
/// Example:
///
///     use std::io::Write;
///     let mut foobar: [u8; 128] = unsafe {std::mem::uninitialized()};
///     let foobar = gstring! (foobar, {
///         write! (foobar, "foo") .expect ("!write");
///         write! (foobar, "bar") .expect ("!write");
///     });
///
/// Alternatives: https://crates.io/crates/stack.
#[macro_export] macro_rules! gstring {($array: ident, $code: block) => {{
  let end = {
    let mut $array = ::std::io::Cursor::new (&mut $array[..]);
    let $array = &mut $array;
    $code;
    $array.position() as usize};
  unsafe {::std::str::from_utf8_unchecked (&$array[0..end])}}}}

/// Takes a netstring from the front of the slice.
///
/// Returns the unpacked netstring and the remainder of the slice.
pub fn netstring (at: &[u8]) -> Result<(&[u8], &[u8]), String> {
  let length_end = match at.iter().position (|&ch| ch < b'0' || ch > b'9') {Some (l) if l > 0 => l, _ => return ERR! ("No len.")};
  match at.get (length_end) {Some (&ch) if ch == b':' => (), _ => return ERR! ("No colon.")};
  let length = unsafe {from_utf8_unchecked (&at[0 .. length_end])};
  let length: usize = try_s! (length.parse());
  let bulk_pos = 0 + length_end + 1;
  let bulk_end = bulk_pos + length;
  match at.get (bulk_end) {Some (&ch) if ch == b',' => (), _ => return ERR! ("No comma.")}
  Ok ((&at[bulk_pos .. bulk_end], &at[bulk_end + 1 ..]))}

/// Wraps `gethostname` to fetch the current hostname into a temporary buffer.
#[cfg(unix)]
pub fn with_hostname (visitor: &mut FnMut (&[u8])) -> Result<(), std::io::Error> {
  use libc::{size_t, gethostname};  // http://man7.org/linux/man-pages/man2/gethostname.2.html
  use std::ffi::CStr;
  use std::io;

  let mut buf = [0; 128];
  let rc = unsafe {gethostname (buf.as_mut_ptr(), (buf.len() - 1) as size_t)};
  if rc == 0 {
    let cs = unsafe {CStr::from_ptr (buf.as_ptr())};
    Ok (visitor (cs.to_bytes()))
  } else {
    Err (io::Error::last_os_error())}}

#[cfg(unix)] #[test] fn test_hostname() {
  let mut hostname = String::new();
  with_hostname (&mut |bytes| hostname = String::from_utf8_lossy (bytes) .into_owned()) .unwrap();}

/// Read contents of the file into a String.
///
/// Returns an empty string if the file is not present under the given path.
pub fn slurp (path: &AsRef<Path>) -> String {
  let mut file = match fs::File::open (path) {
    Ok (f) => f,
    Err (ref err) if err.kind() == io::ErrorKind::NotFound => return String::new(),
    Err (err) => panic! ("Can't open {:?}: {}", path.as_ref(), err)};
  let mut buf = String::new();
  file.read_to_string (&mut buf) .expect ("!read");
  buf}

/// Runs a command in a shell, returning stderr+stdout on success.
///
/// Sometimes we need something simpler than constructing a Command.
///
/// If the command failed then returns it's stderr
pub fn slurp_prog (command: &str) -> Result<String, String> {
  let output = match Command::new ("dash") .arg ("-c") .arg (command) .output() {
    Ok (output) => output,
    Err (ref err) if err.kind() == io::ErrorKind::NotFound => {  // "sh" was not found, try a different name.
      try_s! (Command::new ("sh") .arg ("-c") .arg (command) .output())},
    Err (err) => return ERR! ("{}", err)};

  let combined_output: String = if output.stderr.is_empty() {
    try_s! (String::from_utf8 (output.stdout))
  } else if output.stdout.is_empty() {
    try_s! (String::from_utf8 (output.stderr))
  } else {
    let mut buf = String::with_capacity (output.stderr.len() + output.stdout.len());
    buf.push_str (try_s! (std::str::from_utf8 (&output.stderr[..])));
    buf.push_str (try_s! (std::str::from_utf8 (&output.stdout[..])));
    buf};

  if output.status.success() {Ok (combined_output)} else {Err (combined_output)}}

#[test] fn test_slurp_prog() {
  let foo = match slurp_prog ("echo foo") {Ok (foo) => foo, Err (err) => panic! ("{}", err)};
  assert_eq! (foo.trim(), "foo");}

/// Run a command, printing it first. Stdout and stderr are forwarded through (`inherit`).
pub fn cmd (cmd: &str) -> Result<(), String> {
  println! ("$ {}", cmd);
  let status = try_s! (Command::new ("dash") .arg ("-c") .arg (cmd) .stdout (Stdio::inherit()) .stderr (Stdio::inherit()) .status());
  if !status.success() {Err (format! ("Command returned an error status: {}", status))} else {Ok(())}}

/// Useful with panic handlers.
pub fn any_to_str<'a> (message: &'a Box<Any + Send + 'static>) -> Option<&'a str> {
  if let Some (message) = message.downcast_ref::<&str>() {return Some (message)}
  if let Some (message) = message.downcast_ref::<String>() {return Some (&message[..])}
  return None}

// --- nom extensions ---

/// Implements the `/(?x) (.*?) (remainder)/` pattern:
/// looks for remainder first, then returns a tuple with the prefix and the remainder.
///
/// Discussion: https://www.reddit.com/r/rust/comments/4yokxd/crash_course_into_nom_kind_of_question/
#[macro_export]
macro_rules! take_until_parse_s (
  ($i: expr, $remainder: ident! ($($args:tt)*)) => ({
    let input = $i as &str;
    let mut ret = IResult::Error (nom::Err::Position (nom::ErrorKind::Custom (0), input));
    for (pos, _) in $i.char_indices() {
      match $remainder! (&input[pos..], $($args)*) {
        IResult::Done (i,o)    => {ret = IResult::Done (i, (&input[0..pos], o)); break},  // Found the remainder!
        IResult::Error(_)      => continue,  // Keep looking.
        IResult::Incomplete(_) => continue}}  // Keep looking.

    if !ret.is_done() {
      // Last chance. See if subparser accepts an empty string.
      if let IResult::Done (i,o) = $remainder! ("", $($args)*) {
        ret = IResult::Done (i, (input, o))}}  // Empty remainder was accepted.

    ret});

  ($i: expr, $f: expr) => (take_until_parse_s! ($i, call! ($f));););

/// Uses nom to find all matches of the given `$submac` parser and replace them with the `$submac` results.
///
/// For exaple, replacing "foo" with "bar" might look like this:
///
///     let bar_bar = parse_replace_s! ("foo bar", map! (tag_s! ("foo"), |_| "bar"));
#[macro_export]
macro_rules! parse_replace_s {
  ($i: expr, $submac: ident! ($($args:tt)*)) => ({
    let input = $i as &str;
    let mut output = String::with_capacity (input.len() * 2 + 32);
    let mut pos = input;
    while let IResult::Done (tail, (head, evaluation)) = take_until_parse_s! (pos, $submac! ($($args)*)) {
      output.push_str (head);
      output.push_str (&evaluation);
      pos = tail;}
    output.push_str (pos);
    output});

  ($i: expr, $f: expr) => (parse_replace_s! ($i, call! ($f)););}

/// `$starts` is an optional `Pattern` used to optimize the `$remainder` search.
///
/// For example, with jetscii: `take_until_find_parse_s! ("foo bar", ascii_chars! ('b'), tag_s! ("bar"))`.
#[macro_export]
macro_rules! take_until_find_parse_s (
  ($i: expr, $starts: expr, $remainder: ident! ($($args:tt)*)) => ({
    let input = $i as &str;
    let mut ret = IResult::Error (nom::Err::Position (nom::ErrorKind::Custom (0), input));
    for (pos, _) in $i.match_indices ($starts) {
      match $remainder! (&input[pos..], $($args)*) {
        IResult::Done (i,o)    => {ret = IResult::Done (i, (&input[0..pos], o)); break},  // Found the remainder!
        IResult::Error(_)      => continue,  // Keep looking.
        IResult::Incomplete(_) => continue}}  // Keep looking.
    ret});

  ($i: expr, $starts: expr, $f: expr) => (take_until_find_parse_s! ($i, $starts, call! ($f));););

/// Uses nom to find all matches of the given `$submac` parser and replace them with the parser's evaluations.
///
/// `$starts` is a `Pattern` that is used to speed up the search. It must match the beginning of any `$submac`-compatible substrings.
///
/// For exaple, replacing "foo" with "bar" might look like this:
///
///     let bar_bar = find_parse_replace_s! ("foo bar", ascii_chars! ('f'), map! (tag_s! ("foo"), |_| "bar"));
#[macro_export]
macro_rules! find_parse_replace_s {
  ($i: expr, $starts: expr, $submac: ident! ($($args:tt)*)) => ({
    let input = $i as &str;
    let mut output = String::with_capacity (input.len() * 2 + 32);
    let mut pos = input;
    while let IResult::Done (tail, (head, evaluation)) =
      take_until_find_parse_s! (pos, $starts, $submac! ($($args)*)) {
        output.push_str (head);
        output.push_str (&evaluation);
        pos = tail;}
    output.push_str (pos);
    output});

  ($i: expr, $starts: expr, $f: expr) => (find_parse_replace_s! ($i, $starts, call! ($f)););}
<commit_msg>Incorporate From::from directly in try_s<commit_after>#![feature(libc,question_mark)]
extern crate libc;

use std::any::Any;
use std::fs;
use std::io;
use std::io::Read;
use std::path::Path;
use std::process::{Command, Stdio};
use std::str::from_utf8_unchecked;

/// Shortcut to path->filename conversion.
///
/// Returns the unchanged `path` if there is a character encoding error or something.
pub fn filename<'a> (path: &'a str) -> &'a str {
  match Path::new (path) .file_name() {
    Some (filename) => match filename.to_str() {
      Some (fstr) => if fstr.ends_with (".rs") {&fstr[0 .. fstr.len() - 3]} else {fstr},
      None => path},
    None => path}}

mod gstuff {pub fn filename<'a> (path: &'a str) -> &'a str {super::filename (path)}}

// A trick to use the `try_s` macro from both the outside and inside of the crate.
//mod gstuff {pub fn filename<'a> (path: &'a str) -> &'a str {::filename (path)}}

/// Returns on error, converting the `Err` value to `String` and prepending the current location.
///
/// cf. http://www.reddit.com/r/rust/comments/29wwzw/error_handling_and_result_types/cipcm9a
#[macro_export] macro_rules! try_s {
  ($e: expr) => {match $e {
    Ok (ok) => ok,
    Err (err) => {return Err (From::from (format! ("{}:{}] {}", ::gstuff::filename (file!()), line!(), err)));}}}}

// Like `try_s`, but takes a reference.
#[macro_export] macro_rules! try_sp {
  ($e: expr) => {match $e {&Ok (ref ok) => ok,
    &Err (ref err) => {return Err (From::from (format! ("{}:{}] {:?}", ::gstuff::filename (file!()), line!(), err)));}}}}

/// Returns a `Err(String)`, prepending the current location (file name and line number) to the string.
///
/// Examples: `ERR! ("too bad")`; `ERR! ("{}", foo)`;
#[macro_export] macro_rules! ERR {
  ($format: expr, $($args: tt)+) => {Err (format! (concat! ("{}:{}] ", $format), ::gstuff::filename (file!()), line!(), $($args)+))};
  ($format: expr) => {Err (format! (concat! ("{}:{}] ", $format), ::gstuff::filename (file!()), line!()))}}

/// A helper to build a string on the stack.
///
/// Given an array it makes a writeable cursor available to the passed code block.
///
/// Returns a &str slice pointing at memory between the array start and the cursor.
///
/// Example:
///
///     use std::io::Write;
///     let mut foobar: [u8; 128] = unsafe {std::mem::uninitialized()};
///     let foobar = gstring! (foobar, {
///         write! (foobar, "foo") .expect ("!write");
///         write! (foobar, "bar") .expect ("!write");
///     });
///
/// Alternatives: https://crates.io/crates/stack.
#[macro_export] macro_rules! gstring {($array: ident, $code: block) => {{
  let end = {
    let mut $array = ::std::io::Cursor::new (&mut $array[..]);
    let $array = &mut $array;
    $code;
    $array.position() as usize};
  unsafe {::std::str::from_utf8_unchecked (&$array[0..end])}}}}

/// Takes a netstring from the front of the slice.
///
/// Returns the unpacked netstring and the remainder of the slice.
pub fn netstring (at: &[u8]) -> Result<(&[u8], &[u8]), String> {
  let length_end = match at.iter().position (|&ch| ch < b'0' || ch > b'9') {Some (l) if l > 0 => l, _ => return ERR! ("No len.")};
  match at.get (length_end) {Some (&ch) if ch == b':' => (), _ => return ERR! ("No colon.")};
  let length = unsafe {from_utf8_unchecked (&at[0 .. length_end])};
  let length: usize = try_s! (length.parse());
  let bulk_pos = 0 + length_end + 1;
  let bulk_end = bulk_pos + length;
  match at.get (bulk_end) {Some (&ch) if ch == b',' => (), _ => return ERR! ("No comma.")}
  Ok ((&at[bulk_pos .. bulk_end], &at[bulk_end + 1 ..]))}

/// Wraps `gethostname` to fetch the current hostname into a temporary buffer.
#[cfg(unix)]
pub fn with_hostname (visitor: &mut FnMut (&[u8])) -> Result<(), std::io::Error> {
  use libc::{size_t, gethostname};  // http://man7.org/linux/man-pages/man2/gethostname.2.html
  use std::ffi::CStr;
  use std::io;

  let mut buf = [0; 128];
  let rc = unsafe {gethostname (buf.as_mut_ptr(), (buf.len() - 1) as size_t)};
  if rc == 0 {
    let cs = unsafe {CStr::from_ptr (buf.as_ptr())};
    Ok (visitor (cs.to_bytes()))
  } else {
    Err (io::Error::last_os_error())}}

#[cfg(unix)] #[test] fn test_hostname() {
  let mut hostname = String::new();
  with_hostname (&mut |bytes| hostname = String::from_utf8_lossy (bytes) .into_owned()) .unwrap();}

/// Read contents of the file into a String.
///
/// Returns an empty string if the file is not present under the given path.
pub fn slurp (path: &AsRef<Path>) -> String {
  let mut file = match fs::File::open (path) {
    Ok (f) => f,
    Err (ref err) if err.kind() == io::ErrorKind::NotFound => return String::new(),
    Err (err) => panic! ("Can't open {:?}: {}", path.as_ref(), err)};
  let mut buf = String::new();
  file.read_to_string (&mut buf) .expect ("!read");
  buf}

/// Runs a command in a shell, returning stderr+stdout on success.
///
/// Sometimes we need something simpler than constructing a Command.
///
/// If the command failed then returns it's stderr
pub fn slurp_prog (command: &str) -> Result<String, String> {
  let output = match Command::new ("dash") .arg ("-c") .arg (command) .output() {
    Ok (output) => output,
    Err (ref err) if err.kind() == io::ErrorKind::NotFound => {  // "sh" was not found, try a different name.
      try_s! (Command::new ("sh") .arg ("-c") .arg (command) .output())},
    Err (err) => return ERR! ("{}", err)};

  let combined_output: String = if output.stderr.is_empty() {
    try_s! (String::from_utf8 (output.stdout))
  } else if output.stdout.is_empty() {
    try_s! (String::from_utf8 (output.stderr))
  } else {
    let mut buf = String::with_capacity (output.stderr.len() + output.stdout.len());
    buf.push_str (try_s! (std::str::from_utf8 (&output.stderr[..])));
    buf.push_str (try_s! (std::str::from_utf8 (&output.stdout[..])));
    buf};

  if output.status.success() {Ok (combined_output)} else {Err (combined_output)}}

#[test] fn test_slurp_prog() {
  let foo = match slurp_prog ("echo foo") {Ok (foo) => foo, Err (err) => panic! ("{}", err)};
  assert_eq! (foo.trim(), "foo");}

/// Run a command, printing it first. Stdout and stderr are forwarded through (`inherit`).
pub fn cmd (cmd: &str) -> Result<(), String> {
  println! ("$ {}", cmd);
  let status = try_s! (Command::new ("dash") .arg ("-c") .arg (cmd) .stdout (Stdio::inherit()) .stderr (Stdio::inherit()) .status());
  if !status.success() {Err (format! ("Command returned an error status: {}", status))} else {Ok(())}}

/// Useful with panic handlers.
pub fn any_to_str<'a> (message: &'a Box<Any + Send + 'static>) -> Option<&'a str> {
  if let Some (message) = message.downcast_ref::<&str>() {return Some (message)}
  if let Some (message) = message.downcast_ref::<String>() {return Some (&message[..])}
  return None}

// --- nom extensions ---

/// Implements the `/(?x) (.*?) (remainder)/` pattern:
/// looks for remainder first, then returns a tuple with the prefix and the remainder.
///
/// Discussion: https://www.reddit.com/r/rust/comments/4yokxd/crash_course_into_nom_kind_of_question/
#[macro_export]
macro_rules! take_until_parse_s (
  ($i: expr, $remainder: ident! ($($args:tt)*)) => ({
    let input = $i as &str;
    let mut ret = IResult::Error (nom::Err::Position (nom::ErrorKind::Custom (0), input));
    for (pos, _) in $i.char_indices() {
      match $remainder! (&input[pos..], $($args)*) {
        IResult::Done (i,o)    => {ret = IResult::Done (i, (&input[0..pos], o)); break},  // Found the remainder!
        IResult::Error(_)      => continue,  // Keep looking.
        IResult::Incomplete(_) => continue}}  // Keep looking.

    if !ret.is_done() {
      // Last chance. See if subparser accepts an empty string.
      if let IResult::Done (i,o) = $remainder! ("", $($args)*) {
        ret = IResult::Done (i, (input, o))}}  // Empty remainder was accepted.

    ret});

  ($i: expr, $f: expr) => (take_until_parse_s! ($i, call! ($f));););

/// Uses nom to find all matches of the given `$submac` parser and replace them with the `$submac` results.
///
/// For exaple, replacing "foo" with "bar" might look like this:
///
///     let bar_bar = parse_replace_s! ("foo bar", map! (tag_s! ("foo"), |_| "bar"));
#[macro_export]
macro_rules! parse_replace_s {
  ($i: expr, $submac: ident! ($($args:tt)*)) => ({
    let input = $i as &str;
    let mut output = String::with_capacity (input.len() * 2 + 32);
    let mut pos = input;
    while let IResult::Done (tail, (head, evaluation)) = take_until_parse_s! (pos, $submac! ($($args)*)) {
      output.push_str (head);
      output.push_str (&evaluation);
      pos = tail;}
    output.push_str (pos);
    output});

  ($i: expr, $f: expr) => (parse_replace_s! ($i, call! ($f)););}

/// `$starts` is an optional `Pattern` used to optimize the `$remainder` search.
///
/// For example, with jetscii: `take_until_find_parse_s! ("foo bar", ascii_chars! ('b'), tag_s! ("bar"))`.
#[macro_export]
macro_rules! take_until_find_parse_s (
  ($i: expr, $starts: expr, $remainder: ident! ($($args:tt)*)) => ({
    let input = $i as &str;
    let mut ret = IResult::Error (nom::Err::Position (nom::ErrorKind::Custom (0), input));
    for (pos, _) in $i.match_indices ($starts) {
      match $remainder! (&input[pos..], $($args)*) {
        IResult::Done (i,o)    => {ret = IResult::Done (i, (&input[0..pos], o)); break},  // Found the remainder!
        IResult::Error(_)      => continue,  // Keep looking.
        IResult::Incomplete(_) => continue}}  // Keep looking.
    ret});

  ($i: expr, $starts: expr, $f: expr) => (take_until_find_parse_s! ($i, $starts, call! ($f));););

/// Uses nom to find all matches of the given `$submac` parser and replace them with the parser's evaluations.
///
/// `$starts` is a `Pattern` that is used to speed up the search. It must match the beginning of any `$submac`-compatible substrings.
///
/// For exaple, replacing "foo" with "bar" might look like this:
///
///     let bar_bar = find_parse_replace_s! ("foo bar", ascii_chars! ('f'), map! (tag_s! ("foo"), |_| "bar"));
#[macro_export]
macro_rules! find_parse_replace_s {
  ($i: expr, $starts: expr, $submac: ident! ($($args:tt)*)) => ({
    let input = $i as &str;
    let mut output = String::with_capacity (input.len() * 2 + 32);
    let mut pos = input;
    while let IResult::Done (tail, (head, evaluation)) =
      take_until_find_parse_s! (pos, $starts, $submac! ($($args)*)) {
        output.push_str (head);
        output.push_str (&evaluation);
        pos = tail;}
    output.push_str (pos);
    output});

  ($i: expr, $starts: expr, $f: expr) => (find_parse_replace_s! ($i, $starts, call! ($f)););}
<|endoftext|>


<commit_before>extern mod std;

struct Solver<T> {
    number: uint,
    answer: T,
    solver: extern fn() -> T
}

impl<T: Eq> Solver<T> {
    fn solve(&self) {
        let answer = (self.solver)();
        assert_eq!(&answer, &self.answer);
        io::println(fmt!("Problem #%u: %?", self.number, self.answer));
    }
}

enum Wrap {
    Uint(Solver<uint>),
    Int(Solver<int>)
}

impl Wrap {
    fn solve(&self) {
        match self {
            &Uint(s) => s.solve(),
            &Int(s) => s.solve()
        }
    }
}

macro_rules! define_solver(
    ($module:ident, $num:expr, $answer:expr, $wrap:ident) => (
        $wrap(Solver {
            number: $num,
            answer: $answer,
            solver: $module::solve
        })
    )
)

#[path="./common/mod.rs"]
mod common;

#[path="./prob0001_0050/mod.rs"]
mod prob0001_0050;
use prob0001_0050::*;

static solvers: &'static [Wrap] = &[
    define_solver!(prob0001, 1, 233168, Uint),
    define_solver!(prob0002, 2, 4613732, Uint),
    define_solver!(prob0003, 3, 6857, Uint),
    define_solver!(prob0004, 4, 906609, Uint),
    define_solver!(prob0005, 5, 232792560, Uint),
    define_solver!(prob0006, 6, 25164150, Uint),
    define_solver!(prob0007, 7, 104743, Uint),
    define_solver!(prob0008, 8, 40824, Uint),
    define_solver!(prob0009, 9, 31875000, Uint),
    define_solver!(prob0010, 10, 142913828922, Uint),
    define_solver!(prob0011, 11, 70600674, Uint),
    define_solver!(prob0012, 12, 76576500, Uint),
    define_solver!(prob0013, 13, 5537376230, Uint),
    define_solver!(prob0014, 14, 837799, Uint),
    define_solver!(prob0015, 15, 137846528820, Uint),
    define_solver!(prob0016, 16, 1366, Uint),
    define_solver!(prob0017, 17, 21124, Uint),
    define_solver!(prob0018, 18, 1074, Uint),
    define_solver!(prob0019, 19, 171, Uint),
    define_solver!(prob0020, 20, 648, Uint),
    define_solver!(prob0021, 21, 31626, Uint),
    define_solver!(prob0022, 22, 871198282, Uint),
    define_solver!(prob0023, 23, 4179871, Uint),
    define_solver!(prob0024, 24, 2783915460, Uint),
    define_solver!(prob0025, 25, 4782, Uint),
    define_solver!(prob0026, 26, 983, Uint),
    define_solver!(prob0027, 27, -59231, Int),
    define_solver!(prob0028, 28, 669171001, Uint),
    define_solver!(prob0029, 29, 9183, Uint),
    define_solver!(prob0030, 30, 443839, Uint),
    define_solver!(prob0031, 31, 73682, Uint),
    define_solver!(prob0032, 32, 45228, Uint),
    define_solver!(prob0033, 33, 100, Uint),
    define_solver!(prob0034, 34, 40730, Uint),
    define_solver!(prob0035, 35, 55, Uint),
    define_solver!(prob0036, 36, 872187, Uint),
    define_solver!(prob0037, 37, 748317, Uint),
    define_solver!(prob0038, 38, 932718654, Uint),
    define_solver!(prob0039, 39, 840, Uint),
    define_solver!(prob0040, 40, 210, Uint),
    define_solver!(prob0041, 41, 7652413, Uint),
    define_solver!(prob0042, 42, 162, Uint),
    define_solver!(prob0043, 43, 16695334890, Uint),
    define_solver!(prob0044, 44, 5482660, Uint),
    define_solver!(prob0045, 45, 1533776805, Uint),
    define_solver!(prob0046, 46, 5777, Uint),
    define_solver!(prob0047, 47, 134043, Uint),
    define_solver!(prob0048, 48, 9110846700, Uint),
    define_solver!(prob0049, 49, 296962999629, Uint),
    define_solver!(prob0050, 50, 997651, Uint)
 ];

fn main() {
    for solvers.each |s| { s.solve(); };
}
<commit_msg>Rename struct and enum<commit_after>extern mod std;

struct Solver<T> {
    number: uint,
    answer: T,
    solver: extern fn() -> T
}

impl<T: Eq> Solver<T> {
    fn solve(&self) {
        let answer = (self.solver)();
        assert_eq!(&answer, &self.answer);
        io::println(fmt!("Problem #%u: %?", self.number, self.answer));
    }
}

enum Problem {
    UintProblem(Solver<uint>),
    IntProblem(Solver<int>)
}

impl Problem {
    fn solve(&self) {
        match self {
            &UintProblem(s) => s.solve(),
            &IntProblem(s) => s.solve()
        }
    }
}

macro_rules! define_solver(
    ($module:ident, $num:expr, $answer:expr) => (
        define_solver!($module, $num, $answer, UintProblem)
    );
    ($module:ident, $num:expr, $answer:expr, $problem:ident) => (
        $problem(Solver {
            number: $num,
            answer: $answer,
            solver: $module::solve
        })
    );
)

#[path="./common/mod.rs"]
mod common;

#[path="./prob0001_0050/mod.rs"]
mod prob0001_0050;
use prob0001_0050::*;

static problems: &'static [Problem] = &[
    define_solver!(prob0001, 1, 233168),
    define_solver!(prob0002, 2, 4613732),
    define_solver!(prob0003, 3, 6857),
    define_solver!(prob0004, 4, 906609),
    define_solver!(prob0005, 5, 232792560),
    define_solver!(prob0006, 6, 25164150),
    define_solver!(prob0007, 7, 104743),
    define_solver!(prob0008, 8, 40824),
    define_solver!(prob0009, 9, 31875000),
    define_solver!(prob0010, 10, 142913828922),
    define_solver!(prob0011, 11, 70600674),
    define_solver!(prob0012, 12, 76576500),
    define_solver!(prob0013, 13, 5537376230),
    define_solver!(prob0014, 14, 837799),
    define_solver!(prob0015, 15, 137846528820),
    define_solver!(prob0016, 16, 1366),
    define_solver!(prob0017, 17, 21124),
    define_solver!(prob0018, 18, 1074),
    define_solver!(prob0019, 19, 171),
    define_solver!(prob0020, 20, 648),
    define_solver!(prob0021, 21, 31626),
    define_solver!(prob0022, 22, 871198282),
    define_solver!(prob0023, 23, 4179871),
    define_solver!(prob0024, 24, 2783915460),
    define_solver!(prob0025, 25, 4782),
    define_solver!(prob0026, 26, 983),
    define_solver!(prob0027, 27, -59231, IntProblem),
    define_solver!(prob0028, 28, 669171001),
    define_solver!(prob0029, 29, 9183),
    define_solver!(prob0030, 30, 443839),
    define_solver!(prob0031, 31, 73682),
    define_solver!(prob0032, 32, 45228),
    define_solver!(prob0033, 33, 100),
    define_solver!(prob0034, 34, 40730),
    define_solver!(prob0035, 35, 55),
    define_solver!(prob0036, 36, 872187),
    define_solver!(prob0037, 37, 748317),
    define_solver!(prob0038, 38, 932718654),
    define_solver!(prob0039, 39, 840),
    define_solver!(prob0040, 40, 210),
    define_solver!(prob0041, 41, 7652413),
    define_solver!(prob0042, 42, 162),
    define_solver!(prob0043, 43, 16695334890),
    define_solver!(prob0044, 44, 5482660),
    define_solver!(prob0045, 45, 1533776805),
    define_solver!(prob0046, 46, 5777),
    define_solver!(prob0047, 47, 134043),
    define_solver!(prob0048, 48, 9110846700),
    define_solver!(prob0049, 49, 296962999629),
    define_solver!(prob0050, 50, 997651)
];

fn main() {
    for problems.each |s| { s.solve(); };
}
<|endoftext|>


<commit_before>extern crate bytes;
extern crate env_logger;
extern crate futures;
extern crate futures_cpupool;
extern crate grpc;
extern crate protobuf;
#[macro_use]
extern crate log;

extern crate grpc_interop;
use grpc_interop::*;

use std::thread;

use bytes::Bytes;

use futures::stream;
use futures::stream::Stream;

use grpc::*;
use futures::Async;

static DICTIONARY: &'static str = "ABCDEFGHIJKLMNOPQRSTUVabcdefghijklmnoqprstuvwxyz0123456789";

/**
 * Returns a Vec<u8> with a given size containing printable u8s.
 */
fn make_string(size: usize) -> Vec<u8> {
    let dict = DICTIONARY.to_owned().into_bytes();
    let mut result = Vec::<u8>::with_capacity(size);

    for n in 0..size {
        result.push(dict[n % DICTIONARY.len()]);
    }

    return result;
}

fn echo_custom_metadata(req_metadata: &Metadata) -> Metadata {
    static TEST_ECHO_KEY: &'static str = "x-grpc-test-echo-initial";
    let mut metadata = Metadata::new();
    if let Some(value) = req_metadata.get(TEST_ECHO_KEY) {
        metadata.add(MetadataKey::from(TEST_ECHO_KEY), Bytes::from(value));
    }
    metadata
}

fn echo_custom_trailing(req_metadata: &Metadata) -> Metadata {
    static TEST_ECHO_TRAILING_KEY: &'static str = "x-grpc-test-echo-trailing-bin";
    let mut metadata = Metadata::new();
    if let Some(value) = req_metadata.get(TEST_ECHO_TRAILING_KEY) {
        metadata.add(
            MetadataKey::from(TEST_ECHO_TRAILING_KEY),
            Bytes::from(value),
        );
    }
    metadata
}

struct TestServerImpl {}

impl TestService for TestServerImpl {
    // One empty request followed by one empty response.
    fn empty_call(&self, _ctx: ServerHandlerContext, _req: ServerRequestSingle<Empty>, resp: ServerResponseUnarySink<Empty>) -> grpc::Result<()> {
        resp.finish(Empty::new())
    }

    // One request followed by one response.
    fn unary_call(&self, _ctx: ServerHandlerContext, req: ServerRequestSingle<SimpleRequest>, mut resp: ServerResponseUnarySink<SimpleResponse>) -> grpc::Result<()> {
        if req.message.get_response_status().get_code() != 0 {
            info!("requested to send grpc error {}", req.message.get_response_status().get_code());
            return resp.send_grpc_error(
                GrpcStatus::from_code_or_unknown(req.message.get_response_status().get_code() as u32),
                req.message.get_response_status().message.clone(),
            );
        }

        let mut payload = Payload::new();
        payload.set_body(make_string(req.message.get_response_size() as usize));
        let mut response = SimpleResponse::new();
        response.set_payload(payload);
        resp.send_metadata(echo_custom_metadata(&req.metadata))?;
        resp.finish_with_trailers(response, echo_custom_trailing(&req.metadata))
    }

    // One request followed by one response. Response has cache control
    // headers set such that a caching HTTP proxy (such as GFE) can
    // satisfy subsequent requests.
    fn cacheable_unary_call(&self, _ctx: ServerHandlerContext, _req: ServerRequestSingle<SimpleRequest>, resp: ServerResponseUnarySink<SimpleResponse>) -> grpc::Result<()> {
        // TODO: implement fully
        resp.finish(SimpleResponse::new())
    }

    // One request followed by a sequence of responses (streamed download).
    // The server returns the payload with client desired type and sizes.
    fn streaming_output_call(&self, o: ServerHandlerContext, mut req: ServerRequestSingle<StreamingOutputCallRequest>, resp: ServerResponseSink<StreamingOutputCallResponse>) -> grpc::Result<()> {
        let sizes = req
            .message
            .take_response_parameters()
            .into_iter()
            .map(|res| res.get_size() as usize);
        let output = stream::iter_ok(sizes).map(|size| {
            let mut response = StreamingOutputCallResponse::new();
            let mut payload = Payload::new();
            payload.set_body(make_string(size));
            response.set_payload(payload);
            response
        });
        o.pump(output, resp);
        Ok(())
    }

    // A sequence of requests followed by one response (streamed upload).
    // The server returns the aggregated size of client payload as the result.
    fn streaming_input_call(&self, _ctx: ServerHandlerContext, req: ServerRequest<StreamingInputCallRequest>, resp: ServerResponseUnarySink<StreamingInputCallResponse>) -> grpc::Result<()> {
        let mut resp = Some(resp);
        let mut aggregate_size = 0;
        req.register_stream_handler_basic(move |message| {
            Ok(match message {
                Some(m) => {
                    aggregate_size += m.get_payload().body.len() as i32;
                }
                None => {
                    let mut response = StreamingInputCallResponse::new();
                    response.set_aggregated_payload_size(aggregate_size);
                    resp.take().unwrap().finish(response)?;
                }
            })
        });
        Ok(())
    }

    // A sequence of requests with each request served by the server immediately.
    // As one request could lead to multiple responses, this interface
    // demonstrates the idea of full duplexing.
    fn full_duplex_call(&self, o: ServerHandlerContext, req: ServerRequest<StreamingOutputCallRequest>, mut resp: ServerResponseSink<StreamingOutputCallResponse>) -> grpc::Result<()> {
        let metadata = req.metadata();
        info!("sending custom metadata");
        resp.send_metadata(echo_custom_metadata(&metadata))?;
        let mut req = req.into_stream();
        o.spawn_poll_fn(move || {
            loop {
                if let Async::NotReady = resp.poll()? {
                    return Ok(Async::NotReady);
                }
                match req.poll()? {
                    Async::Ready(Some(m)) => {
                        if m.get_response_status().get_code() != 0 {
                            info!("requested to send grpc error {}", m.get_response_status().get_code());
                            resp.send_grpc_error(
                                GrpcStatus::from_code_or_unknown(m.get_response_status().code as u32),
                                m.get_response_status().message.clone(),
                            )?;
                            return Ok(Async::Ready(()));
                        }

                        for p in &m.response_parameters {
                            info!("requested to send data of size {}", p.size);
                            resp.send_data({
                                let mut response = StreamingOutputCallResponse::new();
                                let mut payload = Payload::new();
                                payload.set_body(make_string(p.size as usize));
                                response.set_payload(payload);
                                response
                            })?;
                        }
                    }
                    Async::Ready(None) => {
                        info!("sending custom trailers");
                        resp.send_trailers(echo_custom_trailing(&metadata))?;
                        return Ok(Async::Ready(()));
                    }
                    Async::NotReady => {
                        return Ok(Async::NotReady)
                    }
                }
            }
        });
        Ok(())
    }

    // TODO: implement this if we find an interop client that needs it.
    // A sequence of requests followed by a sequence of responses.
    // The server buffers all the client requests and then serves them in order. A
    // stream of responses are returned to the client when the server starts with
    // first request.
    fn half_duplex_call(&self, _ctx: ServerHandlerContext, _req: ServerRequest<StreamingOutputCallRequest>, mut resp: ServerResponseSink<StreamingOutputCallResponse>) -> grpc::Result<()> {
        resp.send_trailers(Metadata::new())
    }
}

fn main() {
    env_logger::init();

    let mut server = ServerBuilder::new_plain();
    server.http.set_port(DEFAULT_PORT);
    server.add_service(TestServiceServer::new_service_def(TestServerImpl {}));
    let _server = server.build().expect("server");

    loop {
        thread::park();
    }
}
<commit_msg>Update interop_server.rs<commit_after>extern crate bytes;
extern crate env_logger;
extern crate futures;
extern crate futures_cpupool;
extern crate grpc;
extern crate protobuf;
#[macro_use]
extern crate log;

extern crate grpc_interop;
use grpc_interop::*;

use std::thread;

use bytes::Bytes;

use futures::stream;
use futures::stream::Stream;

use grpc::*;
use futures::Async;

static DICTIONARY: &'static str = "ABCDEFGHIJKLMNOPQRSTUVabcdefghijklmnoqprstuvwxyz0123456789";

/**
 * Returns a Vec<u8> with a given size containing printable u8s.
 */
fn make_string(size: usize) -> Vec<u8> {
    let dict = DICTIONARY.to_owned().into_bytes();
    let mut result = Vec::<u8>::with_capacity(size);

    for n in 0..size {
        result.push(dict[n % DICTIONARY.len()]);
    }

    return result;
}

fn echo_custom_metadata(req_metadata: &Metadata) -> Metadata {
    static TEST_ECHO_KEY: &'static str = "x-grpc-test-echo-initial";
    let mut metadata = Metadata::new();
    if let Some(value) = req_metadata.get(TEST_ECHO_KEY) {
        metadata.add(MetadataKey::from(TEST_ECHO_KEY), Bytes::from(value));
    }
    metadata
}

fn echo_custom_trailing(req_metadata: &Metadata) -> Metadata {
    static TEST_ECHO_TRAILING_KEY: &'static str = "x-grpc-test-echo-trailing-bin";
    let mut metadata = Metadata::new();
    if let Some(value) = req_metadata.get(TEST_ECHO_TRAILING_KEY) {
        metadata.add(
            MetadataKey::from(TEST_ECHO_TRAILING_KEY),
            Bytes::from(value),
        );
    }
    metadata
}

struct TestServerImpl {}

impl TestService for TestServerImpl {
    // One empty request followed by one empty response.
    fn empty_call(&self, _ctx: ServerHandlerContext, _req: ServerRequestSingle<Empty>, resp: ServerResponseUnarySink<Empty>) -> grpc::Result<()> {
        resp.finish(Empty::new())
    }

    // One request followed by one response.
    fn unary_call(&self, _ctx: ServerHandlerContext, req: ServerRequestSingle<SimpleRequest>, mut resp: ServerResponseUnarySink<SimpleResponse>) -> grpc::Result<()> {
        if req.message.get_response_status().get_code() != 0 {
            debug!("requested to send grpc error {}", req.message.get_response_status().get_code());
            return resp.send_grpc_error(
                GrpcStatus::from_code_or_unknown(req.message.get_response_status().get_code() as u32),
                req.message.get_response_status().message.clone(),
            );
        }

        let mut payload = Payload::new();
        payload.set_body(make_string(req.message.get_response_size() as usize));
        let mut response = SimpleResponse::new();
        response.set_payload(payload);
        resp.send_metadata(echo_custom_metadata(&req.metadata))?;
        resp.finish_with_trailers(response, echo_custom_trailing(&req.metadata))
    }

    // One request followed by one response. Response has cache control
    // headers set such that a caching HTTP proxy (such as GFE) can
    // satisfy subsequent requests.
    fn cacheable_unary_call(&self, _ctx: ServerHandlerContext, _req: ServerRequestSingle<SimpleRequest>, resp: ServerResponseUnarySink<SimpleResponse>) -> grpc::Result<()> {
        // TODO: implement fully
        resp.finish(SimpleResponse::new())
    }

    // One request followed by a sequence of responses (streamed download).
    // The server returns the payload with client desired type and sizes.
    fn streaming_output_call(&self, o: ServerHandlerContext, mut req: ServerRequestSingle<StreamingOutputCallRequest>, resp: ServerResponseSink<StreamingOutputCallResponse>) -> grpc::Result<()> {
        let sizes = req
            .message
            .take_response_parameters()
            .into_iter()
            .map(|res| res.get_size() as usize);
        let output = stream::iter_ok(sizes).map(|size| {
            let mut response = StreamingOutputCallResponse::new();
            let mut payload = Payload::new();
            payload.set_body(make_string(size));
            response.set_payload(payload);
            response
        });
        o.pump(output, resp);
        Ok(())
    }

    // A sequence of requests followed by one response (streamed upload).
    // The server returns the aggregated size of client payload as the result.
    fn streaming_input_call(&self, _ctx: ServerHandlerContext, req: ServerRequest<StreamingInputCallRequest>, resp: ServerResponseUnarySink<StreamingInputCallResponse>) -> grpc::Result<()> {
        let mut resp = Some(resp);
        let mut aggregate_size = 0;
        req.register_stream_handler_basic(move |message| {
            Ok(match message {
                Some(m) => {
                    aggregate_size += m.get_payload().body.len() as i32;
                }
                None => {
                    let mut response = StreamingInputCallResponse::new();
                    response.set_aggregated_payload_size(aggregate_size);
                    resp.take().unwrap().finish(response)?;
                }
            })
        });
        Ok(())
    }

    // A sequence of requests with each request served by the server immediately.
    // As one request could lead to multiple responses, this interface
    // demonstrates the idea of full duplexing.
    fn full_duplex_call(&self, o: ServerHandlerContext, req: ServerRequest<StreamingOutputCallRequest>, mut resp: ServerResponseSink<StreamingOutputCallResponse>) -> grpc::Result<()> {
        let metadata = req.metadata();
        debug!("sending custom metadata");
        resp.send_metadata(echo_custom_metadata(&metadata))?;
        let mut req = req.into_stream();
        o.spawn_poll_fn(move || {
            loop {
                if let Async::NotReady = resp.poll()? {
                    return Ok(Async::NotReady);
                }
                match req.poll()? {
                    Async::Ready(Some(m)) => {
                        if m.get_response_status().get_code() != 0 {
                            debug!("requested to send grpc error {}", m.get_response_status().get_code());
                            resp.send_grpc_error(
                                GrpcStatus::from_code_or_unknown(m.get_response_status().code as u32),
                                m.get_response_status().message.clone(),
                            )?;
                            return Ok(Async::Ready(()));
                        }

                        for p in &m.response_parameters {
                            debug!("requested to send data of size {}", p.size);
                            resp.send_data({
                                let mut response = StreamingOutputCallResponse::new();
                                let mut payload = Payload::new();
                                payload.set_body(make_string(p.size as usize));
                                response.set_payload(payload);
                                response
                            })?;
                        }
                    }
                    Async::Ready(None) => {
                        debug!("sending custom trailers");
                        resp.send_trailers(echo_custom_trailing(&metadata))?;
                        return Ok(Async::Ready(()));
                    }
                    Async::NotReady => {
                        return Ok(Async::NotReady)
                    }
                }
            }
        });
        Ok(())
    }

    // TODO: implement this if we find an interop client that needs it.
    // A sequence of requests followed by a sequence of responses.
    // The server buffers all the client requests and then serves them in order. A
    // stream of responses are returned to the client when the server starts with
    // first request.
    fn half_duplex_call(&self, _ctx: ServerHandlerContext, _req: ServerRequest<StreamingOutputCallRequest>, mut resp: ServerResponseSink<StreamingOutputCallResponse>) -> grpc::Result<()> {
        resp.send_trailers(Metadata::new())
    }
}

fn main() {
    env_logger::init();

    let mut server = ServerBuilder::new_plain();
    server.http.set_port(DEFAULT_PORT);
    server.add_service(TestServiceServer::new_service_def(TestServerImpl {}));
    let _server = server.build().expect("server");

    loop {
        thread::park();
    }
}
<|endoftext|>