I want to write macro, that convert this:
tag_def!("tagname", (isize, String))
Into this:
TagDefinition::new("tagname", ParamGroup(vec![
TagParam::Int(0),
TagParam::String(String::new())
]))
I tried to find some way to do that with macro but found nothing. usual macro can't parse type, procedural requires struct to parse. Is the non-over-complicated way exists?
TagParam is a enum:
pub enum TagParam {
Int(isize),
String(String),
Color(Color),
Tag(Tag),
Float(f64),
ParamGroup(Vec<TagParam>)
}
One way you can make this simpler is if all of the values stored in the enum implement Default
, the macro can provide Default::default()
as the value. My suggestion would be to take this approach. (All of the enum payloads in your example implement Default
, with the possible exception of Tag
and Color
-- I don't know what those types are, but they might implement Default
.)
Then, you just need a way to map an identifier (the type name) to an enum variant name, which we can do with another macro:
macro_rules! tag_def_type_variant {
( isize ) => { TagParam::Int };
( f64 ) => { TagParam::Float };
// Everything else passes through as-is.
( $e:ident ) => { TagParam::$e };
}
Now we can build tag_def
in terms of this macro:
macro_rules! tag_def {
( $name:literal , ( $( $ty:ident ),+ ) ) => {
TagDefinition::new($name, TagParam::ParamGroup(vec![
$(tag_def_type_variant!($ty)(Default::default())),+
]))
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.