#![deny(unused_extern_crates)]
#![deny(clippy::missing_docs_in_private_items)]
#![allow(deprecated)]
use std::io;
use std::str::FromStr;
macro_rules! rust_target_def {
( $( $( #[$attr:meta] )* => $release:ident => $value:expr; )* ) => {
#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Hash)]
#[allow(non_camel_case_types)]
pub enum RustTarget {
$(
$(
#[$attr]
)*
$release,
)*
}
impl Default for RustTarget {
fn default() -> RustTarget {
LATEST_STABLE_RUST
}
}
impl FromStr for RustTarget {
type Err = io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.as_ref() {
$(
stringify!($value) => Ok(RustTarget::$release),
)*
_ => Err(
io::Error::new(
io::ErrorKind::InvalidInput,
concat!(
"Got an invalid rust target. Accepted values ",
"are of the form ",
"\"1.0\" or \"nightly\"."))),
}
}
}
impl From<RustTarget> for String {
fn from(target: RustTarget) -> Self {
match target {
$(
RustTarget::$release => stringify!($value),
)*
}.into()
}
}
}
}
macro_rules! rust_target_values_def {
( $( $( #[$attr:meta] )* => $release:ident => $value:expr; )* ) => {
pub static RUST_TARGET_STRINGS: &'static [&str] = &[
$(
stringify!($value),
)*
];
}
}
macro_rules! rust_target_base {
( $x_macro:ident ) => {
$x_macro!(
#[deprecated = "This rust target is deprecated. If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues"] => Stable_1_0 => 1.0;
#[deprecated = "This rust target is deprecated. If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues"] => Stable_1_17 => 1.17;
#[deprecated = "This rust target is deprecated. If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues"] => Stable_1_19 => 1.19;
#[deprecated = "This rust target is deprecated. If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues"] => Stable_1_20 => 1.20;
#[deprecated = "This rust target is deprecated. If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues"] => Stable_1_21 => 1.21;
#[deprecated = "This rust target is deprecated. If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues"] => Stable_1_25 => 1.25;
#[deprecated = "This rust target is deprecated. If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues"] => Stable_1_26 => 1.26;
#[deprecated = "This rust target is deprecated. If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues"] => Stable_1_27 => 1.27;
#[deprecated = "This rust target is deprecated. If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues"] => Stable_1_28 => 1.28;
#[deprecated = "This rust target is deprecated. If you have a good reason to use this target please report it at https://github.com/rust-lang/rust-bindgen/issues"] => Stable_1_30 => 1.30;
=> Stable_1_33 => 1.33;
=> Stable_1_36 => 1.36;
=> Stable_1_40 => 1.40;
=> Stable_1_47 => 1.47;
=> Stable_1_59 => 1.59;
=> Stable_1_64 => 1.64;
=> Stable_1_68 => 1.68;
=> Nightly => nightly;
);
}
}
rust_target_base!(rust_target_def);
rust_target_base!(rust_target_values_def);
pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_68;
macro_rules! rust_feature_def {
(
$( $rust_target:ident {
$( $( #[$attr:meta] )* => $feature:ident; )*
} )*
) => {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[allow(missing_docs)] pub(crate) struct RustFeatures {
$( $(
$(
#[$attr]
)*
pub $feature: bool,
)* )*
}
impl RustFeatures {
fn new() -> Self {
RustFeatures {
$( $(
$feature: false,
)* )*
}
}
}
impl From<RustTarget> for RustFeatures {
fn from(rust_target: RustTarget) -> Self {
let mut features = RustFeatures::new();
$(
if rust_target >= RustTarget::$rust_target {
$(
features.$feature = true;
)*
}
)*
features
}
}
}
}
rust_feature_def!(
Stable_1_17 {
=> static_lifetime_elision;
}
Stable_1_19 {
=> untagged_union;
}
Stable_1_20 {
=> associated_const;
}
Stable_1_21 {
=> builtin_clone_impls;
}
Stable_1_25 {
=> repr_align;
}
Stable_1_26 {
=> i128_and_u128;
}
Stable_1_27 {
=> must_use_function;
}
Stable_1_28 {
=> repr_transparent;
}
Stable_1_30 {
=> min_const_fn;
=> core_ffi_c_void;
}
Stable_1_33 {
=> repr_packed_n;
}
Stable_1_36 {
=> maybe_uninit;
}
Stable_1_40 {
=> non_exhaustive;
}
Stable_1_47 {
=> larger_arrays;
}
Stable_1_59 {
=> const_cstr;
}
Stable_1_64 {
=> core_ffi_c;
}
Stable_1_68 {
=> abi_efiapi;
}
Nightly {
=> thiscall_abi;
=> vectorcall_abi;
=> c_unwind_abi;
}
);
impl Default for RustFeatures {
fn default() -> Self {
let default_rust_target: RustTarget = Default::default();
Self::from(default_rust_target)
}
}
#[cfg(test)]
mod test {
#![allow(unused_imports)]
use super::*;
#[test]
fn target_features() {
let f_1_0 = RustFeatures::from(RustTarget::Stable_1_0);
assert!(
!f_1_0.static_lifetime_elision &&
!f_1_0.core_ffi_c_void &&
!f_1_0.untagged_union &&
!f_1_0.associated_const &&
!f_1_0.builtin_clone_impls &&
!f_1_0.repr_align &&
!f_1_0.thiscall_abi &&
!f_1_0.vectorcall_abi
);
let f_1_21 = RustFeatures::from(RustTarget::Stable_1_21);
assert!(
f_1_21.static_lifetime_elision &&
!f_1_21.core_ffi_c_void &&
f_1_21.untagged_union &&
f_1_21.associated_const &&
f_1_21.builtin_clone_impls &&
!f_1_21.repr_align &&
!f_1_21.thiscall_abi &&
!f_1_21.vectorcall_abi
);
let f_nightly = RustFeatures::from(RustTarget::Nightly);
assert!(
f_nightly.static_lifetime_elision &&
f_nightly.core_ffi_c_void &&
f_nightly.untagged_union &&
f_nightly.associated_const &&
f_nightly.builtin_clone_impls &&
f_nightly.maybe_uninit &&
f_nightly.repr_align &&
f_nightly.thiscall_abi &&
f_nightly.vectorcall_abi &&
f_nightly.c_unwind_abi
);
}
fn test_target(target_str: &str, target: RustTarget) {
let target_string: String = target.into();
assert_eq!(target_str, target_string);
assert_eq!(target, RustTarget::from_str(target_str).unwrap());
}
#[test]
fn str_to_target() {
test_target("1.0", RustTarget::Stable_1_0);
test_target("1.17", RustTarget::Stable_1_17);
test_target("1.19", RustTarget::Stable_1_19);
test_target("1.21", RustTarget::Stable_1_21);
test_target("1.25", RustTarget::Stable_1_25);
test_target("nightly", RustTarget::Nightly);
}
}