Macro dominator::apply_methods
source · macro_rules! apply_methods { ($($args:tt)*) => { ... }; }
Expand description
Utility to apply methods to an object.
Normally you would chain method calls like this:
foo
.bar()
.qux(5)
.corge("yes", "no")
But with apply_methods!
you can instead do this:
apply_methods!(foo, {
.bar()
.qux(5)
.corge("yes", "no")
})
In addition to looking nicer, it has another benefit, which is that it supports macros:
apply_methods!(foo, {
.bar!()
.qux!(5)
.corge!("yes", "no")
})
If you didn’t use apply_methods!
then you would have to write
this instead, which is a lot less readable:
corge!(qux!(bar!(foo), 5), "yes", "no")
It also supports macro paths:
apply_methods!(foo, {
.some_crate::bar!()
.other_crate::qux!(5)
.nested::sub_crate::corge!("yes", "no")
})
And it supports specifying the type for method calls:
apply_methods!(foo, {
.bar::<String>()
.qux::<i32, i32>(5)
.corge::<Vec<CustomType>>("yes", "no")
})
Creating custom macros
When using macros inside of apply_methods!
, the object is
always passed as the first argument to the macro:
macro_rules! my_macro {
($this:ident, $first:expr, $second:expr) => {
...
};
}
// This is the same as doing `my_macro!(foo, 5, 10)`
//
// That means `$this` is a reference to `foo`
apply_methods!(foo, {
.my_macro!(5, 10)
})
The first argument is always an ident
, regardless of what the object is.
If the macro doesn’t accept any arguments, then it must be written like this, with a trailing comma:
macro_rules! my_macro {
($this:ident,) => {
...
};
}
In addition to foo!()
macros, you can also use foo![]
and foo! {}
macros.
And the macro can have whatever syntax it wants, because it’s a macro:
apply_methods!(foo, {
.my_macro!(5; 10 => 15)
.my_macro![5; 10 => 15]
.my_macro! {
foo = 5,
bar = 10,
}
})
Using $crate
Rust has a limitation where you cannot use $crate
inside of macros, which means this does not work:
apply_methods!(foo, {
.$crate::my_macro!(5, 10)
})
Instead you can workaround that by doing this:
extern crate self as my_crate;
apply_methods!(foo, {
.my_crate::my_macro!(5, 10)
})
Alternatively, if you are using the html!
or svg!
macros then you can use the apply
method:
html!("div", {
.apply(|dom| $crate::my_macro!(dom, 5, 10))
})