diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index a59d814..011873f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -56,6 +56,33 @@ jobs: command: build args: --all-targets --target=${{ matrix.config.target }} + features: + name: Test Individual Features + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + feature: [ + "binary", + "json", + "ron", + "toml", + "no_std" + ] + + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: x86_64-unknown-linux-gnu + override: true + + - uses: actions-rs/cargo@v1 + with: + command: test + args: --no-default-features --features ${{ matrix.feature }} + test: name: Test runs-on: ${{ matrix.config.os }} diff --git a/Cargo.toml b/Cargo.toml index 6286935..1b468c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,11 @@ edition = "2018" repository = "https://github.com/not-fl3/nanoserde" [features] -default = [] +default = ["json", "binary", "ron", "toml"] +json = ["nanoserde-derive/json"] +binary = ["nanoserde-derive/binary"] +ron = ["nanoserde-derive/ron"] +toml = [] no_std = ["dep:hashbrown"] [dependencies] diff --git a/derive/Cargo.toml b/derive/Cargo.toml index 4bfe2ac..563e0bd 100644 --- a/derive/Cargo.toml +++ b/derive/Cargo.toml @@ -11,6 +11,10 @@ proc-macro = true [features] default = [] +json = [] +binary = [] +ron = [] +toml = [] no_std = ["dep:hashbrown"] [dependencies] diff --git a/derive/src/lib.rs b/derive/src/lib.rs index 46ab935..27dc04f 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(features = "no_std", no_std)] +#![cfg(any(feature = "binary", feature = "json", feature = "ron"))] extern crate alloc; extern crate proc_macro; @@ -6,18 +7,24 @@ extern crate proc_macro; #[macro_use] mod shared; +#[cfg(feature = "binary")] mod serde_bin; +#[cfg(feature = "binary")] use crate::serde_bin::*; +#[cfg(feature = "ron")] mod serde_ron; +#[cfg(feature = "ron")] use crate::serde_ron::*; +#[cfg(feature = "json")] mod serde_json; +#[cfg(feature = "json")] +use crate::serde_json::*; mod parse; -use crate::serde_json::*; - +#[cfg(feature = "binary")] #[proc_macro_derive(SerBin, attributes(nserde))] pub fn derive_ser_bin(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse::parse_data(input); @@ -37,6 +44,7 @@ pub fn derive_ser_bin(input: proc_macro::TokenStream) -> proc_macro::TokenStream ts } +#[cfg(feature = "binary")] #[proc_macro_derive(DeBin, attributes(nserde))] pub fn derive_de_bin(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse::parse_data(input); @@ -57,6 +65,7 @@ pub fn derive_de_bin(input: proc_macro::TokenStream) -> proc_macro::TokenStream ts } +#[cfg(feature = "ron")] #[proc_macro_derive(SerRon, attributes(nserde))] pub fn derive_ser_ron(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse::parse_data(input); @@ -76,6 +85,7 @@ pub fn derive_ser_ron(input: proc_macro::TokenStream) -> proc_macro::TokenStream ts } +#[cfg(feature = "ron")] #[proc_macro_derive(DeRon, attributes(nserde))] pub fn derive_de_ron(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse::parse_data(input); @@ -95,6 +105,7 @@ pub fn derive_de_ron(input: proc_macro::TokenStream) -> proc_macro::TokenStream ts } +#[cfg(feature = "json")] #[proc_macro_derive(SerJson, attributes(nserde))] pub fn derive_ser_json(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse::parse_data(input); @@ -114,6 +125,7 @@ pub fn derive_ser_json(input: proc_macro::TokenStream) -> proc_macro::TokenStrea ts } +#[cfg(feature = "json")] #[proc_macro_derive(DeJson, attributes(nserde))] pub fn derive_de_json(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = parse::parse_data(input); diff --git a/derive/src/parse.rs b/derive/src/parse.rs index 6505d0d..26faf5c 100644 --- a/derive/src/parse.rs +++ b/derive/src/parse.rs @@ -196,10 +196,12 @@ impl Generic { } } + #[cfg(any(feature = "binary", feature = "json"))] pub fn ident_only(&self) -> String { format!("{}{}", self.lifetime_prefix(), self.full()) } + #[cfg(any(feature = "binary", feature = "json"))] pub fn full_with_const(&self, extra_bounds: &[&str], bounds: bool) -> String { let bounds = match (bounds, &self) { (true, Generic::Lifetime { .. }) => self.get_bounds().join(" + "), @@ -414,6 +416,7 @@ impl Category { } impl Type { + #[cfg(any(feature = "ron", feature = "json"))] pub fn base(&self) -> String { let mut base = match &self.ref_type { Some(inner) => match inner { diff --git a/derive/src/shared.rs b/derive/src/shared.rs index f5ddb2c..3617b23 100644 --- a/derive/src/shared.rs +++ b/derive/src/shared.rs @@ -1,5 +1,6 @@ use alloc::string::String; +#[cfg(any(feature = "binary", feature = "json"))] use crate::parse::{Enum, Struct}; macro_rules! l { @@ -22,6 +23,7 @@ pub fn attrs_proxy(attributes: &[crate::parse::Attribute]) -> Option { }) } +#[cfg(any(feature = "ron", feature = "json"))] pub fn attrs_rename(attributes: &[crate::parse::Attribute]) -> Option { attributes.iter().find_map(|attr| { if attr.tokens.len() == 2 && attr.tokens[0] == "rename" { @@ -32,6 +34,7 @@ pub fn attrs_rename(attributes: &[crate::parse::Attribute]) -> Option { }) } +#[cfg(any(feature = "ron", feature = "json"))] pub fn attrs_default(attributes: &[crate::parse::Attribute]) -> Option> { attributes.iter().find_map(|attr| { if attr.tokens.len() == 1 && attr.tokens[0] == "default" { @@ -44,6 +47,7 @@ pub fn attrs_default(attributes: &[crate::parse::Attribute]) -> Option Option { attributes.iter().find_map(|attr| { if attr.tokens.len() == 2 && attr.tokens[0] == "default_with" { @@ -54,18 +58,21 @@ pub fn attrs_default_with(attributes: &[crate::parse::Attribute]) -> Option bool { attributes .iter() .any(|attr| attr.tokens.len() == 1 && attr.tokens[0] == "transparent") } +#[cfg(feature = "json")] pub fn attrs_skip(attributes: &[crate::parse::Attribute]) -> bool { attributes .iter() .any(|attr| attr.tokens.len() == 1 && attr.tokens[0] == "skip") } +#[cfg(any(feature = "binary", feature = "json"))] pub(crate) fn struct_bounds_strings(struct_: &Struct, bound_name: &str) -> (String, String) { let generics: &Vec<_> = &struct_.generics; @@ -90,6 +97,7 @@ pub(crate) fn struct_bounds_strings(struct_: &Struct, bound_name: &str) -> (Stri return (generic_w_bounds, generic_no_bounds); } +#[cfg(any(feature = "binary", feature = "json"))] pub(crate) fn enum_bounds_strings(enum_: &Enum, bound_name: &str) -> (String, String) { let generics: &Vec<_> = &enum_.generics; diff --git a/src/lib.rs b/src/lib.rs index 621e4f9..3a4263b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,8 +7,6 @@ //! //! Data serialization library with zero dependencies. No more syn/proc_macro2/quote in the build tree! //! -//! `nanoserde` also almost do not use any generics, so build size is not going to be bloated with monomorphizated code. -//! //! The main difference with "serde" and the reason why "nanoserde" is possible: there is no intermediate data model //! For each serialisation datatype there is a special macro. //! @@ -26,14 +24,22 @@ extern crate alloc; pub use nanoserde_derive::*; +#[cfg(feature = "binary")] mod serde_bin; +#[cfg(feature = "binary")] pub use crate::serde_bin::*; +#[cfg(feature = "ron")] mod serde_ron; +#[cfg(feature = "ron")] pub use crate::serde_ron::*; +#[cfg(feature = "json")] mod serde_json; +#[cfg(feature = "json")] pub use crate::serde_json::*; +#[cfg(feature = "toml")] mod toml; +#[cfg(feature = "toml")] pub use crate::toml::*; diff --git a/tests/bin.rs b/tests/bin.rs index af83d4a..a0fa50d 100644 --- a/tests/bin.rs +++ b/tests/bin.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "binary")] use std::collections::{BTreeSet, HashMap, HashSet, LinkedList}; use nanoserde::{DeBin, SerBin}; diff --git a/tests/json.rs b/tests/json.rs index ae821c7..b2d07e3 100644 --- a/tests/json.rs +++ b/tests/json.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "json")] use nanoserde::{DeJson, SerJson}; use std::collections::{BTreeSet, HashMap, HashSet, LinkedList}; diff --git a/tests/ron.rs b/tests/ron.rs index 1ad6f84..cb2b815 100644 --- a/tests/ron.rs +++ b/tests/ron.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "ron")] use nanoserde::{DeRon, SerRon}; use std::collections::{BTreeSet, HashMap, HashSet, LinkedList}; diff --git a/tests/ser_de.rs b/tests/ser_de.rs index 34a9c09..13e755f 100644 --- a/tests/ser_de.rs +++ b/tests/ser_de.rs @@ -1,10 +1,19 @@ -use nanoserde::{DeBin, DeJson, DeRon, SerBin, SerJson, SerRon}; +#![cfg(any(feature = "binary", feature = "json", feature = "ron"))] +#[cfg(feature = "binary")] +use nanoserde::{DeBin, SerBin}; +#[cfg(feature = "json")] +use nanoserde::{DeJson, SerJson}; +#[cfg(feature = "ron")] +use nanoserde::{DeRon, SerRon}; use std::collections::HashMap; #[test] fn ser_de() { - #[derive(DeBin, SerBin, DeJson, SerJson, DeRon, SerRon, PartialEq, Debug)] + #[derive(PartialEq, Debug)] + #[cfg_attr(feature = "binary", derive(DeBin, SerBin))] + #[cfg_attr(feature = "json", derive(DeJson, SerJson))] + #[cfg_attr(feature = "ron", derive(DeRon, SerRon))] pub struct Test { pub a: i32, pub b: f32, @@ -28,15 +37,24 @@ fn ser_de() { g: (), }; - let bytes = SerBin::serialize_bin(&test); - let test_deserialized = DeBin::deserialize_bin(&bytes).unwrap(); - assert_eq!(test, test_deserialized); + #[cfg(feature = "binary")] + { + let bytes = SerBin::serialize_bin(&test); + let test_deserialized = DeBin::deserialize_bin(&bytes).unwrap(); + assert_eq!(test, test_deserialized); + } - let bytes = SerJson::serialize_json(&test); - let test_deserialized = DeJson::deserialize_json(&bytes).unwrap(); - assert_eq!(test, test_deserialized); + #[cfg(feature = "json")] + { + let bytes = SerJson::serialize_json(&test); + let test_deserialized = DeJson::deserialize_json(&bytes).unwrap(); + assert_eq!(test, test_deserialized); + } - let bytes = SerRon::serialize_ron(&test); - let test_deserialized = DeRon::deserialize_ron(&bytes).unwrap(); - assert_eq!(test, test_deserialized); + #[cfg(feature = "ron")] + { + let bytes = SerRon::serialize_ron(&test); + let test_deserialized = DeRon::deserialize_ron(&bytes).unwrap(); + assert_eq!(test, test_deserialized); + } } diff --git a/tests/toml.rs b/tests/toml.rs index ab153b6..cab1baa 100644 --- a/tests/toml.rs +++ b/tests/toml.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "toml")] use nanoserde::TomlParser; #[test]