Skip to main content

datavalue_rs/
lib.rs

1//! datavalue-rs — bump-allocated JSON value type.
2//!
3//! [`DataValue<'a>`] mirrors the shape of `serde_json::Value`, but every
4//! composite payload (string bytes, array elements, object pairs) lives in
5//! a [`bumpalo::Bump`] arena. Designed for hot paths where per-value heap
6//! allocation is the bottleneck and the same arena handles many values
7//! before being reset.
8//!
9//! ## Quickstart
10//!
11//! ```
12//! use bumpalo::Bump;
13//! use datavalue_rs::DataValue;
14//!
15//! let arena = Bump::new();
16//! let v = DataValue::from_str(r#"{"name":"alice","ages":[30,31]}"#, &arena).unwrap();
17//! assert_eq!(v["name"].as_str(), Some("alice"));
18//! assert_eq!(v["ages"][1].as_i64(), Some(31));
19//! ```
20
21mod emit;
22mod number;
23mod owned;
24mod parser;
25pub mod simd;
26mod value;
27
28#[cfg(feature = "datetime")]
29mod datetime;
30
31#[cfg(feature = "serde")]
32mod ser;
33
34#[cfg(feature = "serde_json")]
35mod serde_json_bridge;
36
37pub use number::NumberValue;
38pub use owned::{OwnedDataValue, OwnedValueIndex};
39pub use parser::{ParseError, ParseErrorKind};
40pub use value::{DataValue, ValueIndex};
41
42#[cfg(feature = "datetime")]
43pub use datetime::{DataDateTime, DataDuration};
44
45#[cfg(feature = "serde")]
46pub use ser::DataValueSeed;
47
48pub use emit::Pretty;
49
50/// Construct an [`OwnedDataValue`] from a JSON-shaped literal.
51///
52/// Modeled on `serde_json::json!`. Each `null`, `true`, `false`, array,
53/// or object literal maps to the corresponding variant; any other token
54/// is forwarded through `OwnedDataValue::from(...)` so the [`From`] impls
55/// on this crate (`i32`, `String`, `Vec<T>`, `Option<T>`, `HashMap`, etc.)
56/// determine the variant.
57///
58/// Each array element and each object value must be a single token tree.
59/// Non-trivial expressions need to be parenthesised:
60/// `owned_json!([(1 + 2), (compute())])`.
61///
62/// ```
63/// use datavalue_rs::owned_json;
64///
65/// let v = owned_json!({
66///     "name": "alice",
67///     "ages": [30, 31],
68///     "active": true,
69///     "tags": null,
70/// });
71/// assert_eq!(v["name"].as_str(), Some("alice"));
72/// assert_eq!(v["ages"][1].as_i64(), Some(31));
73/// ```
74#[macro_export]
75macro_rules! owned_json {
76    (null) => { $crate::OwnedDataValue::Null };
77    (true) => { $crate::OwnedDataValue::Bool(true) };
78    (false) => { $crate::OwnedDataValue::Bool(false) };
79
80    ([]) => { $crate::OwnedDataValue::Array(::std::vec::Vec::new()) };
81    ([ $( $elem:tt ),+ $(,)? ]) => {
82        $crate::OwnedDataValue::Array(::std::vec![
83            $( $crate::owned_json!($elem) ),+
84        ])
85    };
86
87    ({}) => { $crate::OwnedDataValue::Object(::std::vec::Vec::new()) };
88    ({ $( $key:tt : $val:tt ),+ $(,)? }) => {
89        $crate::OwnedDataValue::Object(::std::vec![
90            $( (
91                ::std::string::ToString::to_string(&$key),
92                $crate::owned_json!($val),
93            ) ),+
94        ])
95    };
96
97    ($other:expr) => { $crate::OwnedDataValue::from($other) };
98}