Skip to content
This repository was archived by the owner on Aug 15, 2021. It is now read-only.

Commit 9899e3d

Browse files
committed
Add the cbor!() macro
The cbor!() macro is inspired by serde_json::json!(), but the implementation is simpler and the macro should be more useful. In particular, the cbor!() macro returns Result<Value, Error>, so it can be used in places that need careful error handling.
1 parent a218403 commit 9899e3d

File tree

4 files changed

+495
-0
lines changed

4 files changed

+495
-0
lines changed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ serde = { version = "1.0.14", default-features = false }
2222

2323
[dev-dependencies]
2424
serde_derive = { version = "1.0.14", default-features = false }
25+
serde_bytes = { version = "0.11", default-features = false }
2526

2627
[features]
2728
default = ["std"]

src/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ extern crate std;
325325
#[cfg(feature = "alloc")]
326326
extern crate alloc;
327327

328+
#[cfg(feature = "std")]
329+
#[macro_use]
330+
mod macros;
331+
328332
pub mod de;
329333
pub mod error;
330334
mod read;

src/macros.rs

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/// Build a `Value` conveniently.
2+
///
3+
/// The syntax should be intuitive if you are familiar with JSON. You can also
4+
/// inline simple Rust expressions, including custom values that implement
5+
/// `serde::Serialize`. Note that this macro returns `Result<Value, Error>`,
6+
/// so you should handle the error appropriately.
7+
///
8+
/// ```
9+
/// use serde_cbor::cbor;
10+
///
11+
/// let bytes = serde_bytes::Bytes::new(b"\x00\x01\x02");
12+
/// let value = cbor!({
13+
/// "code" => 415,
14+
/// "message" => null,
15+
/// "continue" => false,
16+
/// "extra" => { "numbers" => [8.2341e+4, 0.251425] },
17+
/// "data" => bytes,
18+
/// }).unwrap();
19+
/// ```
20+
21+
#[macro_export]
22+
macro_rules! cbor {
23+
(@map {$($key:expr => $val:expr),*} $(,)?) => {{
24+
#[allow(unused_mut)]
25+
let mut map = ::std::collections::BTreeMap::new();
26+
27+
$(
28+
map.insert(
29+
$crate::value::to_value(cbor!( $key )?)?,
30+
$crate::value::to_value(cbor!( $val )?)?,
31+
);
32+
)*
33+
34+
$crate::Value::Map(map)
35+
}};
36+
37+
(@map {$($key:expr => $val:expr),*} { $($nkey:tt)* } => $($next:tt)*) => {
38+
cbor!(
39+
@map
40+
{ $($key => $val),* }
41+
cbor!({ $($nkey)* })? =>
42+
$($next)*
43+
)
44+
};
45+
46+
(@map {$($key:expr => $val:expr),*} [ $($nkey:tt)* ] => $($next:tt)*) => {
47+
cbor!(
48+
@map
49+
{ $($key => $val),* }
50+
cbor!([ $($nkey)* ])? =>
51+
$($next)*
52+
)
53+
};
54+
55+
(@map {$($key:expr => $val:expr),*} $nkey:expr => { $($nval:tt)* }, $($next:tt)*) => {
56+
cbor!(
57+
@map
58+
{ $($key => $val,)* $nkey => cbor!({ $($nval)* })? }
59+
$($next)*
60+
)
61+
};
62+
63+
(@map {$($key:expr => $val:expr),*} $nkey:expr => [ $($nval:tt)* ], $($next:tt)*) => {
64+
cbor!(
65+
@map
66+
{ $($key => $val,)* $nkey => cbor!([ $($nval)* ])? }
67+
$($next)*
68+
)
69+
};
70+
71+
(@map {$($key:expr => $val:expr),*} $nkey:expr => $nval:expr, $($next:tt)*) => {
72+
cbor!(
73+
@map
74+
{ $($key => $val,)* $nkey => cbor!($nval)? }
75+
$($next)*
76+
)
77+
};
78+
79+
(@array [$($val:expr),*] $(,)?) => {
80+
$crate::Value::Array(
81+
vec![$( cbor!($val)? ),*]
82+
)
83+
};
84+
85+
(@array [$($val:expr),*] { $($item:tt)* }, $($next:tt)*) => {
86+
cbor!(
87+
@array
88+
[ $($val,)* cbor!({ $($item)* })? ]
89+
$($next)*
90+
)
91+
};
92+
93+
(@array [$($val:expr),*] [ $($item:tt)* ], $($next:tt)*) => {
94+
cbor!(
95+
@array
96+
[ $($val,)* cbor!([ $($item)* ])? ]
97+
$($next)*
98+
)
99+
};
100+
101+
(@array [$($val:expr),*] $item:expr, $($next:tt)*) => {
102+
cbor!(
103+
@array
104+
[ $($val,)* $item ]
105+
$($next)*
106+
)
107+
};
108+
109+
({ $($next:tt)* }) => {(||{
110+
::core::result::Result::<_, $crate::Error>::from(Ok(cbor!(@map {} $($next)* ,)))
111+
})()};
112+
113+
([ $($next:tt)* ]) => {(||{
114+
::core::result::Result::<_, $crate::Error>::from(Ok(cbor!(@array [] $($next)* ,)))
115+
})()};
116+
117+
($val:expr) => {{
118+
#[allow(unused_imports)]
119+
use $crate::Value::Null as null;
120+
$crate::value::to_value(&$val)
121+
}};
122+
}

0 commit comments

Comments
 (0)