[][src]Macro summon::circle

macro_rules! circle {
    ($($arg_name:ty),* => $return_ty:tt) => { ... };
    ($($arg_name:tt $arg_pat:tt),* => $return_ty:tt $return_pat:tt) => { ... };
    (|$($arg_name:tt: &$arg_ty:ty),*| -> $return_ty:tt $body:tt) => { ... };
}

Use this to inscribe a transmutation between a set of input types and an output type.

Pattern form

This form allows seamless destructuring of input types and and type constructing the output. This is the prefered form, as it avoids the need to repeat yourself.

use summon::{Tome, circle};
#[derive(Clone)]
struct Normal(u32);
struct Double(u32);
struct Half(u32);
let mut tome = Tome::new();
tome.ether(Normal(4));
tome.inscribe(circle!(Normal(n) => Double(n * 2)));
tome.inscribe(circle!(Normal(n) => Half(n / 2)));
assert_eq!(8, tome.summon::<Double>().unwrap().0);
assert_eq!(2, tome.summon::<Half>().unwrap().0);

Closure form

This form offers the maximum flexibility, and looks like a normal closure. You can only use references as parameters. This form leads to some repitition, but it is currently the only way to combine tags with other data due to macro limitations.

use summon::{Tome, circle};
#[derive(Clone)]
struct Normal(u32);
struct Double(u32);
struct Half(u32);
let mut tome = Tome::new();
tome.ether(Normal(4));
tome.inscribe(circle!(|n: &Normal| -> Double { Double(n.0 * 2) }));
tome.inscribe(circle!(|n: &Normal| -> Half { Half(n.0 / 2) }));
assert_eq!(8, tome.summon::<Double>().unwrap().0);
assert_eq!(2, tome.summon::<Half>().unwrap().0);

Tag form

This form is useful when you have some logic you want to perform. Multiple ways to produce an output is equivalent to OR. Multiple arguments to produce a single output is equivalent to an AND. There is currently no NOT or XOR equivalent (coming soon).

use summon::{Tome, circle};
#[derive(Clone)]
struct A;
struct B;
let mut tome = Tome::new();
tome.ether(A);
tome.inscribe(circle!(A => B));
tome.summon::<B>().unwrap();