A type fragment specifier, written `ty`, matches Rust type syntax inside a declarative macro matcher. It lets a macro accept a caller-provided type, bind it to a metavariable, and reuse that type in generated code. section 2.4
Selecting the generated return type
A getter macro can provide a default `String` case and a second arm for other types: macro_rules! generate_get_value { ($struct_type:ident) => { generate_get_value!($struct_type, String); }; ($struct_type:ident, $return_type:ty) => { impl $struct_type { pub fn get_value(&self) -> &$return_type { &self.value } } } } `generate_get_value!(FirstName)` delegates to the `String` form, while `generate_get_value!(Age, i32)` captures `i32` with `ty` and inserts it into the generated method signature. section 2.2.3
Listing 2.9 Making it work for types other than Strings
struct Age {
value: i32,
}
struct Pay {
value: i32,
}
macro_rules! generate_get_value {
($struct_type:ident) => {
impl $struct_type {
pub fn get_value(&self) -> &String {
&self.value
}
}
};
($struct_type:ident,$return_type:ty) => { #1
impl $struct_type {
pub fn get_value(&self) -> &$return_type {
&self.value
}
}
}
}
generate_get_value!(FirstName);
generate_get_value!(LastName);
generate_get_value!(Age,i32);
generate_get_value!(Pay,i32);
Compare the two macro arms and their invocations for `String` and `i32`; the second arm shows the `ty` capture in context. section 2.2.3
