[][src]Macro structural::ts

macro_rules! ts {
    ($anything:tt) => { ... };
}

Constructs a TStr value,a type-level string used for identifiers in field paths.

Input

This macro can take any one of these as input:

  • A string literal,eg: ts!("bar baz")

  • An integer,eg: ts!(99) (equivalent to ts!("99"))

  • An identifier,eg: ts!(foo) (equivalent to ts!("foo"))

Example

Here are examples of constructing field paths using this macro, they are paired up with the fp macro for comparison.

use structural::{StructuralExt, Structural, ts, fp, field_path_aliases};
use structural::enums::VariantProxy;
use structural::path::{
    VariantField, VariantName, NestedFieldPath, FieldPathSet, NestedFieldPathSet,
};

let tuple=( 3, 5, (8,80,800), (13,21,(34,55)), Some(('a','b','c')) );

////////////////////////////////////////////////////////////////////
////               Constructing `NestedFieldPath`

let path_0=ts!(0);
assert_eq!( tuple.field_(path_0), &3 );
assert_eq!( tuple.field_(fp!(0)), &3 );

let path_1=ts!(1);
assert_eq!( tuple.field_(path_1), &5 );
assert_eq!( tuple.field_(fp!(1)), &5 );

let path_2_0=NestedFieldPath::many((ts!(2), ts!(0)));
assert_eq!( tuple.field_(path_2_0), &8 );
assert_eq!( tuple.field_(fp!(2.0)), &8 );

let path_2_1=NestedFieldPath::many((ts!(2), ts!(1)));
assert_eq!( tuple.field_(path_2_1), &80 );
assert_eq!( tuple.field_(fp!(2.1)), &80 );

let path_2_2=NestedFieldPath::many((ts!(2), ts!(2)));
assert_eq!( tuple.field_(path_2_2), &800 );
assert_eq!( tuple.field_(fp!(2.2)), &800 );

let path_3_2_0=NestedFieldPath::many((ts!(3), ts!(2), ts!(0)));
assert_eq!( tuple.field_(path_3_2_0), &34 );
assert_eq!( tuple.field_(fp!(3.2.0)), &34 );

let path_3_2_1=NestedFieldPath::many((ts!(3), ts!(2), ts!(1)));
assert_eq!( tuple.field_(path_3_2_1), &55 );
assert_eq!( tuple.field_(fp!(3.2.1)), &55 );

////////////////////////////////////////////////////////////////////
////            Constructing VariantName

#[derive(Debug,Structural,PartialEq)]
enum Binary{
    Left(u32,u32),
    Right{
        c: char,
        is_true: bool,
    },
}

let left=Binary::Left(3,5);
let right=Binary::Right{c: 'a', is_true: false};

field_path_aliases!{
    mod paths{Left,Right}
}

let _:&VariantProxy<Binary, paths::Left>=
    left.field_(VariantName::new(ts!(Left))).unwrap();
let _:&VariantProxy<Binary, paths::Left>=
    left.field_(fp!(::Left)).unwrap();

assert_eq!( left.field_(VariantName::new(ts!(Right))), None);
assert_eq!( left.field_(fp!(::Right)), None);


let _:&VariantProxy<Binary, paths::Right>=
    right.field_(VariantName::new(ts!(Right))).unwrap();
let _:&VariantProxy<Binary, paths::Right>=
    right.field_(fp!(::Right)).unwrap();

assert_eq!( right.field_(VariantName::new(ts!(Left))), None);
assert_eq!( right.field_(fp!(::Left)), None);


////////////////////////////////////////////////////////////////////
////            Constructing VariantField

assert_eq!( left.field_(VariantField::new(ts!(Left),ts!(0))), Some(&3) );
assert_eq!( left.field_(fp!(::Left.0)), Some(&3) );
assert_eq!( left.field_(VariantField::new(ts!(Right),ts!(c))), None );
assert_eq!( left.field_(fp!(::Right.c)), None );

assert_eq!( right.field_(VariantField::new(ts!(Right),ts!(c))), Some(&'a') );
assert_eq!( right.field_(fp!(::Right.c)), Some(&'a') );
assert_eq!( right.field_(VariantField::new(ts!(Left),ts!(0))), None );
assert_eq!( right.field_(fp!(::Left.0)), None );


////////////////////////////////////////////////////////////////////
////               Constructing `FieldPathSet`
////
//// Note that you can't safely construct a FieldPathSet to
//// access multiple fields mutably (which might access overlapping fields),
//// it requires calling the unsafe `upgrade_unchecked` method after
//// constructing the FieldPathSet.

// These don't have an equivalent syntax in the `fp` macro.
assert_eq!( tuple.fields(FieldPathSet::one(path_0)), (&3,) );
assert_eq!( tuple.fields(FieldPathSet::one(path_1)), (&5,) );
assert_eq!( tuple.fields(FieldPathSet::one(path_2_0)), (&8,) );
assert_eq!( tuple.fields(FieldPathSet::one(path_2_1)), (&80,) );
assert_eq!( tuple.fields(FieldPathSet::one(path_2_2)), (&800,) );

assert_eq!( tuple.fields(FieldPathSet::many((path_0, path_1))), (&3,&5) );
assert_eq!( tuple.fields(fp!(0, 1)), (&3,&5) );

assert_eq!( tuple.fields(FieldPathSet::many((path_1, path_2_0))), (&5,&8) );
assert_eq!( tuple.fields(fp!(1, 2.0)), (&5,&8) );

assert_eq!(
    tuple.fields(FieldPathSet::many((path_2_0, path_2_1, path_2_2))),
    (&8, &80, &800),
);
assert_eq!( tuple.fields(fp!(2.0, 2.1, 2.2)), (&8, &80, &800));


////////////////////////////////////////////////////////////////////
////               Constructing `NestedFieldPathSet`
////
//// Note that you can't safely construct a NestedFieldPathSet to
//// access multiple fields mutably(which might access overlapping fields),
//// it requires calling the unsafe `upgrade_unchecked` method after
//// constructing the `NestedFieldPathSet`.

let left=Binary::Left(3,5);
let right=Binary::Right{c: 'a', is_true: false};

let nested_a=NestedFieldPathSet::new(
    VariantName::new(ts!(Left)),
    FieldPathSet::many(( ts!(0), ts!(1) )),
);
let nested_b=NestedFieldPathSet::new(
    VariantName::new(ts!(Right)),
    FieldPathSet::many(( ts!(c), ts!(is_true) )),
);

assert_eq!( left.cloned_fields(nested_a), Some((3,5)) );
assert_eq!( left.cloned_fields(fp!(::Left=>0,1)), Some((3,5)) );

assert_eq!( left.cloned_fields(nested_b), None );
assert_eq!( left.cloned_fields(fp!(::Right=>c,is_true)), None );


assert_eq!( right.cloned_fields(nested_a), None );
assert_eq!( right.cloned_fields(fp!(::Left=>0,1)), None );

assert_eq!( right.cloned_fields(nested_b), Some(('a',false)) );
assert_eq!( right.cloned_fields(fp!(::Right=>c,is_true)), Some(('a',false)) );