[][src]Macro photonix::zoom

macro_rules! zoom {
    ($outer:ty => $first:ty => $second:ty) => { ... };
    ($outer:ty => $first:ty => $second:ty => $third:ty) => { ... };
    ($outer:ty => $first:ty => $second:ty => $third:ty => $fourth:ty) => { ... };
    ($outer:ty => $first:ty => $second:ty => $third:ty => $fourth:ty => $fifth:ty) => { ... };
}

Auto-implements composites of setters and modifiers.

The requirement is that the elements should have an implementation of Modify and Set with the target type at the next level (see definitions of composites for details).

You can use this macro with both structs and enums.

Examples

 #[derive(GetOption, Set, Modify)]
 pub enum User {
     Admin,
     RegularUser(Employee),
 }

 #[derive(Get, Set, Modify)]
 pub struct Employee { pub name: String, pub company: Company }

 #[derive(Get, Set, Modify)]
 pub struct Company { pub name: String, pub address: Address }

 #[derive(Get, Set, Modify)]
 pub struct Address(String);

 let john_doe = || Employee {
     name: String::from("John Doe"),
     company: Company {
         name: String::from("Acme Corporation"),
         address: Address(String::from("4 Foo Road, Bar City")),
         }
     };

 let john_as_user = || User::RegularUser(john_doe());

 //  Parent type   Level 1   Level 2    Level 3    Level 4
 //      |           |          |         |         |
 zoom![User => Employee => Company => Address => String];

 let john_at_new_address = john_as_user().modify_fourth(|s| s.replace("4", "5"));

 let maybe_john = john_at_new_address.get_option();

 assert_eq!(
     Some(String::from("5 Foo Road, Bar City")),
     maybe_john.map(|john| john.company.address.0)
 );

 //  Parent type   Level 1   Level 2
 //      |           |        |
 zoom![User => Employee => String];

 let frank_doe_as_user = john_as_user().set_second(String::from("Frank Doe"));

 assert_eq!(
     Some(String::from("Frank Doe")),
     frank_doe_as_user.get_option().map(|employee| employee.name)
 );