Как распространить действие конструкции #[...] на несколько строк?

Рейтинг: 0Ответов: 2Опубликовано: 17.03.2023

В Rust есть конструкция #[cfg(...)].

Например, есть набор констант, хранящих кода цветов в терминале Linux:

#[cfg(target_os="linux")]
const BLACK: &str = "\033[0;30m";

#[cfg(target_os="linux")]
const RED: &str = "\033[0;31m";

#[cfg(target_os="linux")]
const GREEN: &str = "\033[0;32m";

Вопрос: можно ли как-нибудь сделать так, чтобы не нужно было перед каждой строкой писать #[cfg(target_os="linux")]?

Ответы

▲ 1Принят

Выделите платформозависимую часть в отдельный модуль. За вдохновением можно пойти подглядеть реализацию модуля std::sys:

cfg_if::cfg_if! {
    if #[cfg(unix)] {
        mod unix;
        pub use self::unix::*;
    } else if #[cfg(windows)] {
        mod windows;
        pub use self::windows::*;
    } else if #[cfg(target_os = "solid_asp3")] {
        mod solid;
        pub use self::solid::*;
    } else if #[cfg(target_os = "hermit")] {
        mod hermit;
        pub use self::hermit::*;
    } else if #[cfg(target_os = "wasi")] {
        mod wasi;
        pub use self::wasi::*;
    } else if #[cfg(target_family = "wasm")] {
        mod wasm;
        pub use self::wasm::*;
    } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
        mod sgx;
        pub use self::sgx::*;
    } else {
        mod unsupported;
        pub use self::unsupported::*;
    }
}
▲ 2

Обратите внимание на макрос cfg-if:

cfg_if::cfg_if! {
    if #[cfg(unix)] {
        fn foo() { /* unix specific functionality */ }
    } else if #[cfg(target_pointer_width = "32")] {
        fn foo() { /* non-unix, 32-bit functionality */ }
    } else {
        fn foo() { /* fallback implementation */ }
    }
}