From f8332ac3fa8a9b2a9ba76c0d66d68d37aab3bce8 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Fri, 8 May 2020 21:56:59 +0100 Subject: [PATCH] Fix no_std support if serde is depended on The proc-macro-crate depends on toml, which in turn depends on serde _with_ std. Only depend on proc-macro-crate if std is enabled. This means that no_std consumer of num_enum cannot rename their num_enum dependency. This seems like a reasonable restriction. Works around https://github.com/rust-lang/cargo/issues/5730 --- .travis.yml | 2 ++ Cargo.toml | 4 ++-- num_enum_derive/Cargo.toml | 8 ++++++-- num_enum_derive/src/lib.rs | 27 ++++++++++++++++++--------- serde_example/Cargo.toml | 15 +++++++++++++++ serde_example/src/lib.rs | 11 +++++++++++ 6 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 serde_example/Cargo.toml create mode 100644 serde_example/src/lib.rs diff --git a/.travis.yml b/.travis.yml index 3c67ac3..d730943 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,8 @@ matrix: # Need to cd because of https://github.com/rust-lang/cargo/issues/5364 - (cd num_enum && cargo build --target=thumbv6m-none-eabi --no-default-features -p num_enum) - (cd renamed_num_enum && cargo build --target=thumbv6m-none-eabi --no-default-features -p renamed_num_enum --lib) + # Regression test for https://github.com/illicitonion/num_enum/issues/18 + - (cd serde_example && cargo build --target=thumbv6m-none-eabi -p serde_example --lib) - name: "cargo fmt" rust: stable script: diff --git a/Cargo.toml b/Cargo.toml index 8628fc5..2aad9a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["num_enum", "num_enum_derive", "renamed_num_enum"] +members = ["num_enum", "num_enum_derive", "renamed_num_enum", "serde_example"] # Exclude num_enum_derive because its useful doc comments import num_enum, which the crate doesn't do (because it would # cause a circular dependency), so the doc tests don't actually compile. -default-members = ["num_enum", "renamed_num_enum"] +default-members = ["num_enum", "renamed_num_enum", "serde_example"] diff --git a/num_enum_derive/Cargo.toml b/num_enum_derive/Cargo.toml index 5b70b05..5e3303c 100644 --- a/num_enum_derive/Cargo.toml +++ b/num_enum_derive/Cargo.toml @@ -16,7 +16,11 @@ license = "BSD-3-Clause" proc-macro = true [features] -std = [] +# Don't depend on proc-macro-crate in no_std environments because it causes an awkward depndency +# on serde with std. +# +# See https://github.com/illicitonion/num_enum/issues/18 +std = ["proc-macro-crate"] complex-expressions = ["syn/full"] external_doc = [] @@ -27,6 +31,6 @@ features = ["external_doc"] [dependencies] proc-macro2 = "1" -proc-macro-crate = "0.1.4" +proc-macro-crate = { version = "0.1.4", optional = true } quote = "1" syn = "1" diff --git a/num_enum_derive/src/lib.rs b/num_enum_derive/src/lib.rs index 200bb3f..8b6a3d8 100644 --- a/num_enum_derive/src/lib.rs +++ b/num_enum_derive/src/lib.rs @@ -183,15 +183,7 @@ pub fn derive_try_from_primitive(input: TokenStream) -> TokenStream { let (match_const_exprs, enum_keys): (Vec, Vec) = value_expressions_to_enum_keys.into_iter().unzip(); - let krate = Ident::new( - &::proc_macro_crate::crate_name("num_enum") - .map(::std::borrow::Cow::from) - .unwrap_or_else(|err| { - eprintln!("Warning: {}\n => defaulting to `num_enum`", err,); - "num_enum".into() - }), - Span::call_site(), - ); + let krate = Ident::new(&get_crate_name(), Span::call_site()); TokenStream::from(quote! { impl ::#krate::TryFromPrimitive for #name { @@ -244,6 +236,23 @@ pub fn derive_try_from_primitive(input: TokenStream) -> TokenStream { }) } +#[cfg(feature = "proc-macro-crate")] +fn get_crate_name() -> String { + ::proc_macro_crate::crate_name("num_enum").unwrap_or_else(|err| { + eprintln!("Warning: {}\n => defaulting to `num_enum`", err,); + String::from("num_enum") + }) +} + +// Don't depend on proc-macro-crate in no_std environments because it causes an awkward depndency +// on serde with std. +// +// See https://github.com/illicitonion/num_enum/issues/18 +#[cfg(not(feature = "proc-macro-crate"))] +fn get_crate_name() -> String { + String::from("num_enum") +} + /// Generates a `unsafe fn from_unchecked (number: Primitive) -> Self` /// associated function. /// diff --git a/serde_example/Cargo.toml b/serde_example/Cargo.toml new file mode 100644 index 0000000..327ed03 --- /dev/null +++ b/serde_example/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "serde_example" +version = "0.1.0" +authors = [ + "Daniel Wagner-Hall ", + "Daniel Henry-Mantilla ", +] +description = "Example crate using num_enum and serde. Regression test for https://github.com/illicitonion/num_enum/issues/18." +edition = "2018" +repository = "https://github.com/illicitonion/num_enum" +publish = false + +[dependencies] +num_enum = { path = "../num_enum", default-features = false } +serde = { version = "1", default_features = false, features = ["derive"] } diff --git a/serde_example/src/lib.rs b/serde_example/src/lib.rs new file mode 100644 index 0000000..76093c1 --- /dev/null +++ b/serde_example/src/lib.rs @@ -0,0 +1,11 @@ +#![no_std] + +use num_enum::{IntoPrimitive, TryFromPrimitive, UnsafeFromPrimitive}; +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, IntoPrimitive, Serialize, TryFromPrimitive, UnsafeFromPrimitive)] +#[repr(u8)] +pub enum Number { + Zero, + One, +}