Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

put macros and traits of each type behind individual feature flags #70

Merged
merged 1 commit into from
May 12, 2024
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
52 changes: 52 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,58 @@ 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",
]

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 }}

no_std_features:
name: Test Individual Features NoStd
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
feature: [
"binary",
"json",
"ron",
"toml",
]

steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
target: x86_64-unknown-linux-gnu
override: true

- uses: actions-rs/cargo@v1
with:
command: test
args: --no-default-features --features "no_std, ${{ matrix.feature }}"

test:
name: Test
runs-on: ${{ matrix.config.os }}
Expand Down
10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "nanoserde"
version = "0.1.37"
version = "0.2.0"
authors = ["makepad <[email protected]>", "Fedor <[email protected]>"]
license = "MIT OR Apache-2.0"
description = """
Expand All @@ -22,9 +22,13 @@ edition = "2018"
repository = "https://github.com/not-fl3/nanoserde"

[features]
default = []
default = ["json", "binary", "ron", "toml"]
json = ["dep:nanoserde-derive", "nanoserde-derive/json"]
binary = ["dep:nanoserde-derive", "nanoserde-derive/binary"]
ron = ["dep:nanoserde-derive", "nanoserde-derive/ron"]
toml = []
no_std = ["dep:hashbrown"]

[dependencies]
hashbrown = { version = "0.12.3", optional = true }
nanoserde-derive = { path = "derive", version = "=0.1.22" }
nanoserde-derive = { path = "derive", version = "=0.2.0", optional = true }
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,17 @@ For more examples take a look at [tests](/tests)
| container attribute: `#[nserde(proxy = "")]` | yes | yes | no | no |
| container attribute: `#[nserde(transparent)]` | yes | no | no | no |

## Crate features:

All features are enabled by default. To enable only specific formats, import nanoserde using
```toml
nanoserde = { version = "*", default-features = false, features = [] }
```
in your `Cargo.toml` and add one or more of the following crate features:

| Format | Feature Name |
| ----------| -------------- |
| Binary | `binary` |
| JSON | `json` |
| RON | `ron` |
| TOML | `toml` |
5 changes: 4 additions & 1 deletion derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "nanoserde-derive"
version = "0.1.22"
version = "0.2.0"
authors = ["Makepad <[email protected]>", "Fedor <[email protected]>"]
edition = "2018"
description = "Fork of makepad-tinyserde derive without any external dependencies"
Expand All @@ -11,6 +11,9 @@ proc-macro = true

[features]
default = []
json = []
binary = []
ron = []
no_std = ["dep:hashbrown"]

[dependencies]
Expand Down
15 changes: 13 additions & 2 deletions derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,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);
Expand All @@ -37,6 +43,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);
Expand All @@ -57,6 +64,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);
Expand All @@ -76,6 +84,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);
Expand All @@ -95,6 +104,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);
Expand All @@ -114,6 +124,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);
Expand Down
3 changes: 3 additions & 0 deletions derive/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

#[derive(Debug, Clone)]
pub struct Attribute {
pub name: String,

Check warning on line 19 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test Individual Features NoStd (binary)

field `name` is never read

Check warning on line 19 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test Individual Features NoStd (ron)

field `name` is never read

Check warning on line 19 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test Individual Features NoStd (json)

field `name` is never read

Check warning on line 19 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test No Std (ubuntu-latest, x86_64-unknown-linux-gnu)

field `name` is never read

Check warning on line 19 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test No Std (ubuntu-latest, x86_64-unknown-linux-gnu)

field `name` is never read
pub tokens: Vec<String>,
}

Expand All @@ -37,7 +37,7 @@
#[derive(Debug, Clone)]
pub struct Field {
pub attributes: Vec<Attribute>,
pub vis: Visibility,

Check warning on line 40 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test Individual Features NoStd (binary)

field `vis` is never read

Check warning on line 40 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test Individual Features NoStd (ron)

field `vis` is never read

Check warning on line 40 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test Individual Features NoStd (json)

field `vis` is never read

Check warning on line 40 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test No Std (ubuntu-latest, x86_64-unknown-linux-gnu)

field `vis` is never read

Check warning on line 40 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test No Std (ubuntu-latest, x86_64-unknown-linux-gnu)

field `vis` is never read
pub field_name: Option<String>,
pub ty: Type,
}
Expand Down Expand Up @@ -131,7 +131,7 @@
pub named: bool,
pub fields: Vec<Field>,
pub attributes: Vec<Attribute>,
pub generics: Vec<Generic>,

Check warning on line 134 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test Individual Features NoStd (ron)

field `generics` is never read
}

#[derive(Debug)]
Expand All @@ -139,7 +139,7 @@
pub name: String,
pub variants: Vec<Field>,
pub attributes: Vec<Attribute>,
pub generics: Vec<Generic>,

Check warning on line 142 in derive/src/parse.rs

View workflow job for this annotation

GitHub Actions / Test Individual Features NoStd (ron)

field `generics` is never read
}

#[allow(dead_code)]
Expand Down Expand Up @@ -195,10 +195,12 @@
}
}

#[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(" + "),
Expand Down Expand Up @@ -412,6 +414,7 @@
}

impl Type {
#[cfg(any(feature = "ron", feature = "json"))]
pub fn base(&self) -> String {
let mut base = match &self.ref_type {
Some(inner) => match inner {
Expand Down
8 changes: 8 additions & 0 deletions derive/src/shared.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use alloc::string::String;

#[cfg(any(feature = "binary", feature = "json"))]
use crate::parse::{Enum, Struct};

macro_rules! l {
Expand All @@ -22,6 +23,7 @@ pub fn attrs_proxy(attributes: &[crate::parse::Attribute]) -> Option<String> {
})
}

#[cfg(any(feature = "ron", feature = "json"))]
pub fn attrs_rename(attributes: &[crate::parse::Attribute]) -> Option<String> {
attributes.iter().find_map(|attr| {
if attr.tokens.len() == 2 && attr.tokens[0] == "rename" {
Expand All @@ -32,6 +34,7 @@ pub fn attrs_rename(attributes: &[crate::parse::Attribute]) -> Option<String> {
})
}

#[cfg(any(feature = "ron", feature = "json"))]
pub fn attrs_default(attributes: &[crate::parse::Attribute]) -> Option<Option<String>> {
attributes.iter().find_map(|attr| {
if attr.tokens.len() == 1 && attr.tokens[0] == "default" {
Expand All @@ -44,6 +47,7 @@ pub fn attrs_default(attributes: &[crate::parse::Attribute]) -> Option<Option<St
})
}

#[cfg(any(feature = "ron", feature = "json"))]
pub fn attrs_default_with(attributes: &[crate::parse::Attribute]) -> Option<String> {
attributes.iter().find_map(|attr| {
if attr.tokens.len() == 2 && attr.tokens[0] == "default_with" {
Expand All @@ -54,18 +58,21 @@ pub fn attrs_default_with(attributes: &[crate::parse::Attribute]) -> Option<Stri
})
}

#[cfg(feature = "json")]
pub fn attrs_transparent(attributes: &[crate::parse::Attribute]) -> 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;

Expand All @@ -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;

Expand Down
12 changes: 10 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//!
Expand All @@ -20,20 +18,30 @@
#![cfg_attr(feature = "no_std", no_std)]
// Possibly stable in 1.65.
// See: https://github.com/rust-lang/rust/pull/99917
// and https://github.com/rust-lang/rust/issues/103765
#![cfg_attr(feature = "no_std", feature(error_in_core))]

extern crate alloc;

#[cfg(any(feature = "binary", feature = "json", feature = "ron"))]
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::*;
2 changes: 1 addition & 1 deletion tests/bin.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![cfg(feature = "binary")]
use std::{
array,
collections::{BTreeSet, LinkedList},
Expand All @@ -6,7 +7,6 @@ use std::{

#[cfg(feature = "no_std")]
use hashbrown::{HashMap, HashSet};

#[cfg(not(feature = "no_std"))]
use std::collections::{HashMap, HashSet};

Expand Down
1 change: 1 addition & 0 deletions tests/json.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![cfg(feature = "json")]
use nanoserde::{DeJson, SerJson};

use std::{
Expand Down Expand Up @@ -71,7 +72,7 @@
fn de_illegal_inline_comment() {
#[derive(DeJson)]
pub struct Test {
pub a: f32,

Check warning on line 75 in tests/json.rs

View workflow job for this annotation

GitHub Actions / Test Individual Features NoStd (json)

field `a` is never read

Check warning on line 75 in tests/json.rs

View workflow job for this annotation

GitHub Actions / Test No Std (ubuntu-latest, x86_64-unknown-linux-gnu)

field `a` is never read

Check warning on line 75 in tests/json.rs

View workflow job for this annotation

GitHub Actions / Test No Std (ubuntu-latest, x86_64-unknown-linux-gnu)

field `a` is never read
}

let jsons = vec![
Expand All @@ -94,7 +95,7 @@
fn de_illegal_multiline_comment() {
#[derive(DeJson)]
pub struct Test {
pub a: f32,

Check warning on line 98 in tests/json.rs

View workflow job for this annotation

GitHub Actions / Test Individual Features NoStd (json)

field `a` is never read

Check warning on line 98 in tests/json.rs

View workflow job for this annotation

GitHub Actions / Test No Std (ubuntu-latest, x86_64-unknown-linux-gnu)

field `a` is never read

Check warning on line 98 in tests/json.rs

View workflow job for this annotation

GitHub Actions / Test No Std (ubuntu-latest, x86_64-unknown-linux-gnu)

field `a` is never read
}

let jsons = vec![
Expand Down
1 change: 1 addition & 0 deletions tests/parse.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![cfg(all(feature = "binary", feature = "json", feature = "ron"))]
use nanoserde::{DeBin, DeJson, DeRon, SerBin, SerJson, SerRon};

// https://github.com/not-fl3/nanoserde/issues/83
Expand Down
1 change: 1 addition & 0 deletions tests/ron.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![cfg(feature = "ron")]
use nanoserde::{DeRon, SerRon};

use std::{
Expand Down
40 changes: 29 additions & 11 deletions tests/ser_de.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
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};

#[cfg(feature = "no_std")]
use hashbrown::HashMap;
Expand All @@ -8,7 +14,10 @@ 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,
Expand All @@ -32,15 +41,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);
}
}
2 changes: 2 additions & 0 deletions tests/toml.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg(feature = "toml")]

#[cfg(feature = "no_std")]
use hashbrown::HashMap;
#[cfg(not(feature = "no_std"))]
Expand Down
Loading