nson/
lib.rs

1//! NSON is short for NEW JSON, a binary encoded serialization of JSON-like documents. Similar to JSON, NSON supports embedding maps and arrays within other maps and arrays. Unlike JSON, NSON also includes int32/uint32, int64/uint64, f32/f64, binary, timestamp, id types.
2//!
3//! NSON borrows from BSON and can be thought of as a streamlined version of BSON, removing some of the less common or mongodb-proprietary types. NSON also categorizes Double into f32 and f64, considering that f64 is not needed in most cases for high-precision floating-point numbers. Also added uint32 and uint64 to make it clear that values cannot be complex.
4//!
5//! In the rust language, NSON can be easily written without necessarily serializing/unserializing to structures, thanks to the macro.
6//!
7//! In addition, NSON is convenient to parse from binary, and the library implements "no_std", which can be used on microcontrollers.
8//!
9//! ## Example
10//!
11//! ```rust
12//! use nson::{m, a};
13//!
14//!
15//! let mut value = m!{
16//!     "code": 200,
17//!     "success": true,
18//!     "payload": {
19//!         "some": [
20//!             "pay",
21//!             "loads",
22//!         ]
23//!     }
24//! };
25//!
26//! println!("{:?}", value);
27//! // print: Map{"code": I32(200), "success": Bool(true), "payload":
28//! // Map{"some": Array([String("pay"), String("loads")])}}
29//!
30//! println!("{:?}", value.get("code"));
31//! // print: Some(I32(200))
32//!
33//! // insert new key, value
34//! value.insert("hello", "world");
35//!
36//! println!("{:?}", value.get("hello"));
37//! // print: Some(String("world"))
38//!
39//! // Using a! macro to create arrays (or use [...] auto-detection)
40//! let tags = a!["rust", "nson", "binary"];
41//! value.insert("tags", tags);
42//!
43//! ```
44//!
45
46#![cfg_attr(not(feature = "std"), no_std)]
47
48#[cfg(not(any(feature = "std", feature = "alloc")))]
49compile_error!("nson requires that either `std` (default) or `alloc` feature is enabled");
50
51extern crate alloc;
52
53#[doc(hidden)]
54pub use alloc::vec;
55
56mod macros;
57
58pub mod decode;
59pub mod encode;
60
61pub use array::Array;
62pub use id::Id;
63pub use map::Map;
64pub use value::{Binary, TimeStamp, Value};
65pub mod array;
66
67pub mod id;
68pub mod map;
69pub mod spec;
70pub mod value;
71
72#[cfg(feature = "serde")]
73pub mod serde;
74
75#[cfg(feature = "json")]
76mod json;
77
78#[cfg(not(feature = "std"))]
79pub mod io;
80
81pub const MAX_NSON_SIZE: u32 = 64 * 1024 * 1024; // 64 MB
82pub const MIN_NSON_SIZE: u32 = 4 + 1;
83
84#[cfg(all(test, feature = "alloc", feature = "serde"))]
85mod tests {
86    use alloc::{
87        string::{String, ToString},
88        vec::Vec,
89    };
90
91    use crate::id::Id;
92    use serde::{Deserialize, Serialize};
93
94    use crate::decode::{from_bytes, from_nson};
95    use crate::encode::{to_bytes, to_nson};
96    use crate::m;
97    use crate::value::{Binary, TimeStamp};
98
99    #[derive(Serialize, Deserialize, Debug, PartialEq)]
100    pub struct Foo {
101        a: i32,
102        b: i64,
103        c: f64,
104        d: String,
105        #[serde(with = "serde_bytes")]
106        e: Vec<u8>,
107        t: TimeStamp,
108        i: Id,
109        j: Binary,
110        k: NewType,
111        l: NewType2,
112        m: NewType3,
113        n: NewType4,
114        o: E,
115        p: Vec<i32>,
116    }
117
118    #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
119    pub struct NewType(u64);
120
121    #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
122    pub struct NewType2(u32, u64);
123
124    #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
125    pub struct NewType3 {
126        a: i32,
127        b: i64,
128    }
129
130    #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
131    pub struct NewType4;
132
133    #[derive(Serialize, Deserialize, Debug, PartialEq)]
134    enum E {
135        M(String),
136        N(u8),
137    }
138
139    #[test]
140    fn serialize_and_deserialize() {
141        let foo = Foo {
142            a: 1,
143            b: 2,
144            c: 3.0,
145            d: "4".to_string(),
146            e: alloc::vec![1, 2, 3, 4],
147            t: TimeStamp(123),
148            i: Id::new_raw(123, 45, 678),
149            j: alloc::vec![5, 6, 7, 8].into(),
150            k: NewType(123),
151            l: NewType2(456, 789),
152            m: NewType3 { a: 111, b: 222 },
153            n: NewType4,
154            o: E::N(123),
155            p: alloc::vec![111, 222],
156        };
157
158        let nson = to_nson(&foo).unwrap();
159
160        let foo2: Foo = from_nson(nson).unwrap();
161
162        assert_eq!(foo, foo2);
163
164        let bytes = to_bytes(&foo).unwrap();
165
166        let foo3: Foo = from_bytes(&bytes).unwrap();
167
168        assert_eq!(foo, foo3);
169    }
170
171    #[test]
172    fn binary() {
173        let byte = alloc::vec![1u8, 2, 3, 4];
174        let msg = m! {"aa": "bb", "byte": byte.clone()};
175        let byte2 = msg.get_binary("byte").unwrap();
176
177        assert_eq!(byte, byte2.0);
178
179        let mut msg2 = m! {"aa": "bb"};
180        msg2.insert("byte", byte);
181
182        assert_eq!(msg, msg2);
183    }
184}