Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 1 addition & 42 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,13 @@
//! atomics and sets `cfg` flags accordingly.

use std::env;
use std::process::Command;
use std::str::{self, FromStr};
use std::str;

#[cfg(feature = "kv_unstable")]
#[path = "src/kv/value/internal/cast/primitive.rs"]
mod primitive;

fn main() {
let minor = match rustc_minor_version() {
Some(minor) => minor,
None => return,
};

let target = match rustc_target() {
Some(target) => target,
None => return,
Expand All @@ -28,11 +22,6 @@ fn main() {
println!("cargo:rustc-cfg=has_atomics");
}

// If the Rust version is at least 1.46.0 then we can use type ids at compile time
if minor >= 47 {
println!("cargo:rustc-cfg=const_type_id");
}

// Generate sorted type id lookup
#[cfg(feature = "kv_unstable")]
primitive::generate();
Expand Down Expand Up @@ -61,33 +50,3 @@ fn target_has_atomics(target: &str) -> bool {
fn rustc_target() -> Option<String> {
env::var("TARGET").ok()
}

// From the `serde` build script
fn rustc_minor_version() -> Option<u32> {
let rustc = match env::var_os("RUSTC") {
Some(rustc) => rustc,
None => return None,
};

let output = match Command::new(rustc).arg("--version").output() {
Ok(output) => output,
Err(_) => return None,
};

let version = match str::from_utf8(&output.stdout) {
Ok(version) => version,
Err(_) => return None,
};

let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return None;
}

let next = match pieces.next() {
Some(next) => next,
None => return None,
};

u32::from_str(next).ok()
}
79 changes: 2 additions & 77 deletions src/kv/value/internal/cast/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,83 +13,8 @@ In the future when `min_specialization` is stabilized we could use it instead an
the `'static` bound altogether.
*/

// Use consts to match a type with a conversion fn
#[cfg(all(srcbuild, const_type_id))]
pub(super) fn from_any<'v, T: ?Sized + 'static>(
value: &'v T,
) -> Option<crate::kv::value::internal::Primitive<'v>> {
use std::any::TypeId;

use crate::kv::value::internal::Primitive;

macro_rules! to_primitive {
($($ty:ty : ($const_ident:ident, $option_ident:ident),)*) => {
trait ToPrimitive
where
Self: 'static,
{
const CALL: fn(&Self) -> Option<Primitive> = {
$(
const $const_ident: TypeId = TypeId::of::<$ty>();
const $option_ident: TypeId = TypeId::of::<Option<$ty>>();
);*

match TypeId::of::<Self>() {
$(
$const_ident => |v| Some(Primitive::from(unsafe { *(v as *const Self as *const $ty) })),
$option_ident => |v| Some({
let v = unsafe { *(v as *const Self as *const Option<$ty>) };
match v {
Some(v) => Primitive::from(v),
None => Primitive::None,
}
}),
)*

_ => |_| None,
}
};

fn to_primitive(&self) -> Option<Primitive> {
(Self::CALL)(self)
}
}

impl<T: ?Sized + 'static> ToPrimitive for T {}
}
}

// NOTE: The types here *must* match the ones used below when `const_type_id` is not available
to_primitive![
usize: (USIZE, OPTION_USIZE),
u8: (U8, OPTION_U8),
u16: (U16, OPTION_U16),
u32: (U32, OPTION_U32),
u64: (U64, OPTION_U64),

isize: (ISIZE, OPTION_ISIZE),
i8: (I8, OPTION_I8),
i16: (I16, OPTION_I16),
i32: (I32, OPTION_I32),
i64: (I64, OPTION_I64),

f32: (F32, OPTION_F32),
f64: (F64, OPTION_F64),

char: (CHAR, OPTION_CHAR),
bool: (BOOL, OPTION_BOOL),
&'static str: (STR, OPTION_STR),
];

value.to_primitive()
}

#[cfg(all(not(src_build), const_type_id))]
#[allow(dead_code)]
pub fn generate() {}

// Use a build-time generated set of type ids to match a type with a conversion fn
#[cfg(all(srcbuild, not(const_type_id)))]
#[cfg(srcbuild)]
pub(super) fn from_any<'v>(
value: &'v (dyn std::any::Any + 'static),
) -> Option<crate::kv::value::internal::Primitive<'v>> {
Expand All @@ -107,7 +32,7 @@ pub(super) fn from_any<'v>(
}

// When the `src_build` config is not set then we're in the build script
#[cfg(all(not(srcbuild), not(const_type_id)))]
#[cfg(not(srcbuild))]
#[allow(dead_code)]
pub fn generate() {
use std::path::Path;
Expand Down