[][src]Macro structural::field_path_aliases

macro_rules! field_path_aliases {
    (
        $(#[$attr:meta])*
        $vis:vis mod $mod_name:ident{
            $($mod_contents:tt)*
        }
    ) => { ... };
    (
        $($mod_contents:tt)*
    ) => { ... };
}

Declares aliases for field paths,used to access fields.

Every one of these aliases are types and constants of the same name.

Variants

Inline

Where the aliases are declared at the scope that the macro is invoked.

This variant cannot be invoked within functions.

Small example:

use structural::field_path_aliases;

field_path_aliases!{
    a,
    b=b,
    c=(0,1,2),
    d=(::Foo=>bar,baz),
}

Module

Where the aliases are declared inside a nested module.

This variant can be invoked within functions.

Small example:

use structural::field_path_aliases;

fn hello(){
    field_path_aliases!{
        mod hello{
            a,
            b=b,
            d=(a,b,c,"#D"),
            e=::Foo,
            f=(::Foo=>a,b,c),
        }
    }
}

Example

use structural::{ GetField, StructuralExt, IntoVariantFieldMut, Structural, field_path_aliases };
use structural::enums::VariantProxy;

field_path_aliases!{
    // Equivalent to hello = hello
    hello,
    // Equivalent to world = world
    world,

    // `?` allows you to access the value inside an `Option`.
    //
    // It is syntactic sugar for `::Some.0`,
    // making it usable with any other type implementing
    // the `GetVariantField<TS!(Some),TS!(0))` trait and subtraits.
    zero_a=0?.0,
    zero_b=0?.1,
    zero=0,
    one=1,
    two=2,

    // Used to access the `0`,`1`,and `2` fields
    // with the fields or fields_mut method.
    FirstThree=(0,1,2),

    h=(a,b,c),

    j=(p), // The identifier can also be parenthesised

    boom=Boom,
    path_a=a,
    path_b=b,

    // Accesses the `Boom` variant,if the enum is currently that variant
    boom_variant=::Boom,

    boom_a=::Boom.a,
    boom_b=::Boom.b,

    // Accesses the a,and b fields inside of the `Boom` variant,
    // roughly returning a `Option<(_,_)>`.
    boom_both=(::Boom=>a,b),

    // Accesses the a,and b fields inside of the `Boom` variant separately,
    // roughly returning a `(Option<_>,Option<_>)`.
    boom_both_individually=(::Boom.a,::Boom.b),
}


fn main(){
    assert_fields(&(Some((8,13)),3,5));
    assert_fields(&(Some((8,13)),3,5,8));
    assert_fields(&(Some((8,13)),3,5,8,13));
    assert_fields(&(Some((8,13)),3,5,8,13,21));

    assert_variant(&Variants::Boom {
        a: b"hello",
        b: &[0,1,2,3],
    })
}

fn assert_fields<T>(this:&T)
where
    T:GetField<zero,Ty=Option<(u16,u16)>>+
        GetField<one,Ty=i32>+
        GetField<two,Ty=i32>
{
    assert_eq!( this.field_(zero), &Some((8,13)) );
    assert_eq!( this.field_(zero_a), Some(&8) );
    assert_eq!( this.field_(zero_b), Some(&13) );
    assert_eq!( this.field_(one), &3 );
    assert_eq!( this.field_(two), &5 );
    assert_eq!( this.fields(FirstThree), (&Some((8,13)),&3,&5) );
}

fn assert_variant<T>(this:&T)
where
    T: IntoVariantFieldMut<boom,path_a,Ty= &'static [u8]> +
        IntoVariantFieldMut<boom,path_b,Ty= &'static [u16]>,
{
    let _:&VariantProxy<T,boom>=this.field_(boom_variant).unwrap();

    // Accessing individual enum fields
    assert_eq!( this.field_(boom_a), Some(&&b"hello"[..]) );
    assert_eq!( this.field_(boom_b), Some(&&[0,1,2,3][..]) );

    // Accessing multiple enum fields.
    assert_eq!(
        this.fields(boom_both),
        Some(( &&b"hello"[..], &&[0,1,2,3][..] ))
    );

    // Accessing multiple enum fields,individually.
    // Note how you have to match on multiple options,
    // even though all of them are Some or None at the same time,
    // this is why `fp!(::Foo=>a,b,c)` was created.
    assert_eq!(
        this.fields(boom_both_individually),
        ( Some(&&b"hello"[..]), Some(&&[0,1,2,3][..]) )
    );

}

#[derive(Structural, Copy, Clone, Debug, PartialEq)]
pub enum Variants {
    Boom {
        a: &'static [u8],
        b: &'static [u16],
    },
}

Example

This demonstrates defining aliases inside a module.

use structural::{field_path_aliases,make_struct,structural_alias,StructuralExt};

field_path_aliases!{
    pub mod names{
        a=0.0, // This is for accessing the `.0.0` nested field.
        b=0.1, // This is for accessing the `.0.1` nested field.
        c=foo.boo, // This is for accessing the `.foo.bar` nested field.
        d=foo.bar.baz, // This is for accessing the `.foo.bar.baz` nested field.
    }
}

structural_alias!{
    trait Foo<T>{
        foo:T,
    }

    trait Bar<T>{
        boo:u32,
        bar:T,
    }

    trait Baz<T>{
        baz:T,
    }
}

fn assert_nested<A,B,C>(this:&A)
where
    A:Foo<B>,
    B:Bar<C>,
    C:Baz<u32>,
{
    assert_eq!( this.field_(names::c), &100 );
    assert_eq!( this.field_(names::d), &101 );
}

fn main(){
    assert_nested(&make_struct!{
        foo:make_struct!{
            boo:100,
            bar:make_struct!{
                baz:101,
            }
        }
    });
}

Example

This example demonstrates syntax not used in other examples

use structural::field_path_aliases;

field_path_aliases!{
    // This is a `b_str` alias with the same value as the `b` alias
    b_str="b",

    // strings allow for arbitrary identifiers.
    at_me="@me",

    // Accesses the a,b,and c fields inside of the `ñ` variant.
    g=(::"ñ"=>a,b,c),
}