Token Trees in Macros (Processing Argument Lists)
Currently, the only way to add extension methods to a type in another module (even if that module is in a submodule) is to define a new trait and implement it for the type. This is very cumbersome, however, as the number of methods gets large:
trait Ops {
fn parse_list_item(&self, current_item: ListItemInfo)
-> ParseResult<(Document, ListItemInfo)>;
fn parse_list_item_content(&self) -> ParseResult<Document>;
}
impl<'a> Ops for MarkdownParser<'a> {
fn parse_list_item(&self, current_item: ListItemInfo)
-> ParseResult<(Document, ListItemInfo)> {
// ...
}
fn parse_list_item_content(&self) -> ParseResult<Document> {
// ...
}
}
You must write the method signature twice. If it changes, you also need to update it in several places. It also adds a lot of noise.
I though these macros would help, but I don't know how to write the correct template macro_rules!
for argument lists in functions. Here's what I have so far:
#![feature(macro_rules)]
struct Foo;
macro_rules! ops (
($(fn $name:ident($($args:tt)*) -> $ret:ty $body:block)+) => (
trait Ops {
$(fn $name($($args)*) -> $ret;)+
}
impl Ops for Foo {
$(fn $name($($args)*) -> $ret $body)+
}
)
)
mod ops {
ops! {
fn method1(&self) -> int {
10
}
fn method2(&self, i: int) -> () {
println!("{}", i + self.method1());
}
}
pub fn run_test() {
Foo.method2(22);
}
}
fn main() {
ops::run_test();
}
It fails with a rather nasty message:
/tmp/rs/ops/src/main.rs:8:27: 8:31 error: expected type, found token INTERPOLATED(NtTT(ptr::P<ast::TokenTree>{ptr: box TTTok(codemap::Span{lo: codemap::BytePos(337u32), hi: codemap::BytePos(338u32), expn_id: codemap::ExpnId(4294967295u32)}, BINOP(AND))}))
/tmp/rs/ops/src/main.rs:8 $(fn $name($($args)*) -> $ret;)+
^~~~
It probably deserves a bug report as the error message is quite intimidating, however I see no other way to pass the arguments as is. It seems to be related to this issue , however I hope there is a workaround, for example in this case .
Any suggestions?
source to share
No one has answered this question yet
Check out similar questions: