mmrath
July 15, 2017, 12:47pm
1
use std::result;
use std::str::FromStr;
Obviously the above two use statements are coming twice when macro is invoked twice, how do I avoid it?
macro_rules! sql_string_enum {
( $enumname: ident {
$($enumval: ident,)*
} ) => {
use std::result;
use std::str::FromStr;
#[derive(Debug)]
pub enum $enumname {
$($enumval,)*
}
impl FromStr for $enumname {
type Err = &'static str;
fn from_str(s: &str) -> result::Result<Self, Self::Err> {
match s {
//FIXME: This is where I need to enum identifiers
$( stringify!($enumval) => Ok($enumname::$enumval),)*
_ => {
let msg = stringify!(Not a valid $enumname value);
Err(msg)
},
}
}
}
}
}
fn main() {
sql_string_enum!(Resource { ROLE, USER, });
sql_string_enum!(Access { READ, WRITE, });
println!("{:?}", Resource::from_str("rere").unwrap());
}
1 Like
Put it outside to avoid repetition.
use std::str::FromStr;
macro_rules! sql_string_enum {
( $enumname: ident {
$($enumval: ident,)*
} ) => {
#[derive(Debug)]
pub enum $enumname {
$($enumval,)*
}
impl FromStr for $enumname {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
//FIXME: This is where I need to enum identifiers
$( stringify!($enumval) => Ok($enumname::$enumval),)*
_ => {
let msg = stringify!(Not a valid $enumname value);
Err(msg)
},
}
}
}
}
}
sql_string_enum!(Resource { ROLE, USER, });
sql_string_enum!(Access { READ, WRITE, });
fn main() {
println!("{:?}", Resource::from_str("USER").unwrap());
}
mmrath
July 15, 2017, 2:27pm
3
That does not work as the macro is in a different file.
But I can keep the use statement completely of macro and keep them where it is used. That works but a bit uglier.
1 Like
Common solution, as I see reading rust code, is using full names,
like
impl ::std::str::FromStr for $enumname
so why not just not use using
?
Phaiax
July 15, 2017, 9:50pm
5
Serde puts it's generated impls into a zero sized const:
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _IMPL_SERIALIZE_FOR_Newtype: () =
{
extern crate serde as _serde;
#[automatically_derived]
impl _serde::Serialize for Newtype {
....
}
};
Edit: I just remember that concating identifiers is impossible. So it is impossible to generate unique names for the consts. I think the best idea is to use Dushistov method.