Я использую макросы для настройки множества повторяющихся структур данных, функций, типов и т. Д. c ... для каждого из сигналов прерывания POSIX.
Я заметил, что копирую и вставляю свой список много сигналов, и я хотел, чтобы все было DRY, создав макрос, который расширился до списка сигналов.
Так что работает :
/* Empty trait used for typing addy::for<S: Signal>() */
trait Signal {}
/* Turns a list of identifiers into structs that 'implement' the Signal
* trait so they can be used to type addy::for<S: Signal>()
*/
macro_rules! setup_signals {
($( $signal_name:ident),*) => {
$(
struct $signal_name {}
impl Signal for $signal_name {}
)*
};
}
/* The supported POSIX signals for addy */
setup_signals!(
SIGABRT, SIGALRM, SIGBUS, SIGCHLD,
SIGCONT, SIGFPE, SIGHUP, SIGILL,
SIGINT, SIGKILL, SIGPIPE, SIGPOLL,
SIGPROF, SIGQUIT, SIGSEGV, SIGSTOP,
SIGSYS, SIGTERM, SIGTRAP, SIGTSTP,
SIGTTIN, SIGTTOU, SIGUSR1, SIGUSR2,
SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ,
SIGWINCH
);
Однако, когда я пытаюсь создать макрос с этим списком идентификаторов, он терпит неудачу.
trait Signal {}
macro_rules! list_of_signals {
() => {
SIGABRT, SIGALRM, SIGBUS, SIGCHLD,
SIGCONT, SIGFPE, SIGHUP, SIGILL,
SIGINT, SIGKILL, SIGPIPE, SIGPOLL,
SIGPROF, SIGQUIT, SIGSEGV, SIGSTOP,
SIGSYS, SIGTERM, SIGTRAP, SIGTSTP,
SIGTTIN, SIGTTOU, SIGUSR1, SIGUSR2,
SIGURG, SIGVTALRM, SIGXCPU, SIGXFSZ,
SIGWINCH
};
}
macro_rules! setup_signals {
($( $signal_name:ty),*) => {
$(
struct $signal_name {}
impl Signal for $signal_name {}
)*
};
}
setup_signals!(
list_of_signals!()
);
Это смущает меня, потому что я раньше использовал вложенные макросы.
macro_rules! GET_CURSOR_POSITION_SCAN_STR { () => { "\x1b[{d};{d}R" };}
/* ---///--- */
// Parse the result from the buffer: ESC [ rows ; cols R
let position = scan_fmt!(buffer, GET_CURSOR_POSITION_SCAN_STR!(), u16, u16)
.chain_err(|| "Failed to parse cursor position")?;
Я вижу, что одно отличие состоит в том, что в этом примере вложенный макрос расширяется до &str
, а мой текущий вложенный макрос расширяется до списка идентификаторов.
Как я могу иметь list_of_signals!()
развернуть аналогичным образом, чтобы я мог сохранить свой код DRY?