diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a531681b..b48cad1a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,3 +49,9 @@ jobs: cargo build ${{ matrix.features }} --verbose cargo test --no-fail-fast ${{ matrix.features }} --verbose -- --nocapture cargo doc + + - name: no_std tests crate + run: | + cd derive_builder_no_std_tests + cargo build ${{ matrix.features }} --verbose + cargo test --no-fail-fast ${{ matrix.features }} --verbose -- --nocapture diff --git a/Cargo.toml b/Cargo.toml index 3a0eccc6..0e0d0bd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ["derive_builder", "derive_builder_macro", "derive_builder_core"] +members = ["derive_builder", "derive_builder_macro", "derive_builder_core", "derive_builder_no_std_tests"] diff --git a/derive_builder/src/lib.rs b/derive_builder/src/lib.rs index ab48ecb2..a3630157 100644 --- a/derive_builder/src/lib.rs +++ b/derive_builder/src/lib.rs @@ -541,6 +541,9 @@ #![deny(warnings)] #![cfg_attr(not(feature = "std"), no_std)] +#[cfg(not(feature = "std"))] +extern crate alloc; + extern crate derive_builder_core; extern crate derive_builder_macro; @@ -552,6 +555,8 @@ pub use derive_builder_core::UninitializedFieldError; #[doc(hidden)] pub mod export { pub mod core { + #[cfg(not(feature = "std"))] + pub use alloc::*; #[cfg(not(feature = "std"))] pub use core::*; #[cfg(feature = "std")] diff --git a/derive_builder_core/src/block.rs b/derive_builder_core/src/block.rs index a1ce0576..76fff518 100644 --- a/derive_builder_core/src/block.rs +++ b/derive_builder_core/src/block.rs @@ -67,7 +67,7 @@ mod test { use super::*; #[test] - #[should_panic(expected = r#"LexError"#)] + #[should_panic(expected = r#"lex error"#)] fn block_invalid_token_trees() { Block::from_str("let x = 2; { x+1").unwrap(); } diff --git a/derive_builder_core/src/builder.rs b/derive_builder_core/src/builder.rs index cbabb946..41cb8c7c 100644 --- a/derive_builder_core/src/builder.rs +++ b/derive_builder_core/src/builder.rs @@ -48,7 +48,7 @@ use Setter; /// /// Uninitialized field /// UninitializedField(&'static str), /// /// Custom validation error -/// ValidationError(String), +/// ValidationError(::derive_builder::export::core::string::String), /// } /// /// impl ::derive_builder::export::core::convert::From<&'static str> for FooBuilderError { @@ -57,8 +57,8 @@ use Setter; /// } /// } /// -/// impl ::derive_builder::export::core::convert::From for FooBuilderError { -/// fn from(s: String) -> Self { +/// impl ::derive_builder::export::core::convert::From<::derive_builder::export::core::string::String> for FooBuilderError { +/// fn from(s: ::derive_builder::export::core::string::String) -> Self { /// Self::ValidationError(s) /// } /// } @@ -139,6 +139,8 @@ pub struct Builder<'a> { pub doc_comment: Option, /// Emit deprecation notes to the user. pub deprecation_notes: DeprecationNotes, + /// Whether or not a libstd is used. + pub std: bool, } impl<'a> ToTokens for Builder<'a> { @@ -219,7 +221,7 @@ impl<'a> ToTokens for Builder<'a> { /// Uninitialized field UninitializedField(&'static str), /// Custom validation error - ValidationError(String), + ValidationError(::derive_builder::export::core::string::String), } impl ::derive_builder::export::core::convert::From<::derive_builder::UninitializedFieldError> for #builder_error_ident { @@ -228,8 +230,8 @@ impl<'a> ToTokens for Builder<'a> { } } - impl ::derive_builder::export::core::convert::From for #builder_error_ident { - fn from(s: String) -> Self { + impl ::derive_builder::export::core::convert::From<::derive_builder::export::core::string::String> for #builder_error_ident { + fn from(s: ::derive_builder::export::core::string::String) -> Self { Self::ValidationError(s) } } @@ -242,10 +244,13 @@ impl<'a> ToTokens for Builder<'a> { } } } + )); - #[cfg(not(no_std))] - impl std::error::Error for #builder_error_ident {} - )); + if self.std { + tokens.append_all(quote!( + impl std::error::Error for #builder_error_ident {} + )); + } } } } @@ -327,6 +332,7 @@ macro_rules! default_builder { must_derive_clone: true, doc_comment: None, deprecation_notes: DeprecationNotes::default(), + std: true, } }; } @@ -346,7 +352,7 @@ mod tests { /// Uninitialized field UninitializedField(&'static str), /// Custom validation error - ValidationError(String), + ValidationError(::derive_builder::export::core::string::String), } impl ::derive_builder::export::core::convert::From<::derive_builder::UninitializedFieldError> for FooBuilderError { @@ -355,8 +361,8 @@ mod tests { } } - impl ::derive_builder::export::core::convert::From for FooBuilderError { - fn from(s: String) -> Self { + impl ::derive_builder::export::core::convert::From<::derive_builder::export::core::string::String> for FooBuilderError { + fn from(s: ::derive_builder::export::core::string::String) -> Self { Self::ValidationError(s) } } @@ -370,7 +376,6 @@ mod tests { } } - #[cfg(not(no_std))] impl std::error::Error for FooBuilderError {} )); } diff --git a/derive_builder_core/src/macro_options/darling_opts.rs b/derive_builder_core/src/macro_options/darling_opts.rs index 97e40efa..551d0f08 100644 --- a/derive_builder_core/src/macro_options/darling_opts.rs +++ b/derive_builder_core/src/macro_options/darling_opts.rs @@ -401,6 +401,10 @@ impl Options { must_derive_clone: self.requires_clone(), doc_comment: None, deprecation_notes: Default::default(), + std: { + let no_std: bool = self.no_std.into(); + !no_std + }, } } diff --git a/derive_builder_no_std_tests/Cargo.toml b/derive_builder_no_std_tests/Cargo.toml new file mode 100644 index 00000000..2e74055f --- /dev/null +++ b/derive_builder_no_std_tests/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "derive_builder_no_std_tests" +version = "0.1.0" +authors = ["Andrey Kutejko "] +edition = "2018" + +[dependencies] +derive_builder = { path = "../derive_builder", default-features = false } diff --git a/derive_builder_no_std_tests/src/main.rs b/derive_builder_no_std_tests/src/main.rs new file mode 100644 index 00000000..9ba077ac --- /dev/null +++ b/derive_builder_no_std_tests/src/main.rs @@ -0,0 +1,18 @@ +#![no_std] +#![allow(unused)] + +#[macro_use] +extern crate derive_builder; + +extern crate alloc; + +#[derive(Builder)] +#[builder(no_std)] +struct Foo { + bar: i32, +} + +fn main() { + let foo = FooBuilder::default().build(); + assert!(foo.is_err()); +}