attr 0.1.0

`attr` is a library to provide external access to a datastructure through a typed path object, using all type information known about the data structure at hand.
Documentation
extern crate attr;

use attr::Attr;

pub struct Foo {
    bar: String,
    batz: i32
}

pub struct Bar {
    batz: String,
}

#[test]
fn simple_access() {
    #[derive(Default)]
    struct FooAttributeBar;
    #[derive(Default)]
    struct FooAttributeBatz;

    trait Attributes<AttributeType> {
        fn attrs() -> AttributeType;
    }

    #[derive(Default)]
    struct FooAttributes {
        bar: FooAttributeBar,
        batz: FooAttributeBatz
    }

    impl Attributes<FooAttributes> for Foo {
        fn attrs() -> FooAttributes {
            FooAttributes::default()
        }
    }

    impl<'a> Attr<&'a Foo> for FooAttributeBar {
        type Output = &'a str;

        fn get(&self, i: &'a Foo) -> &'a str {
            i.bar.as_ref()
        }

        fn name(&self) -> &'static str {
            "bar"
        }
    }

    impl<'a> Attr<&'a Foo> for FooAttributeBatz {
        type Output = i32;

        fn get(&self, i: &'a Foo) -> i32 {
            i.batz
        }

        fn name(&self) -> &'static str {
            "batz"
        }
    }

    #[derive(Default)]
    struct BarAttributeBatz;

    #[derive(Default)]
    struct BarAttributes {
        batz: BarAttributeBatz,
    }

    impl Attributes<BarAttributes> for Bar {
        fn attrs() -> BarAttributes {
            BarAttributes::default()
        }
    }

    impl<'a> Attr<&'a Bar> for BarAttributeBatz {
        type Output = &'a str;

        fn get(&self, i: &'a Bar) -> Self::Output {
            i.batz.as_ref()
        }

        fn name(&self) -> &'static str {
            "batz"
        }
    }

    impl<'a> Attr<&'a mut Bar> for BarAttributeBatz {
        type Output = &'a mut String;

        fn get(&self, i: &'a mut Bar) -> Self::Output {
             &mut i.batz
        }

        fn name(&self) -> &'static str {
            "batz"
        }
    }

    let f = Foo { bar: "foobar".into(), batz: 20 };
    Foo::attrs().bar.get(&f);
    Foo::attrs().batz.get(&f);

    let f = Bar { batz: "foobar".into() };
    Bar::attrs().batz.get(&f);

    let mut f = Bar { batz: "foobar".into() };

    let mut batz = Bar::attrs().batz.get(&mut f);
    batz.push('b');
}