A lightweight, no-std, object-safe, serialization-only API for structured values with serde
support.
Producers of structured values use the value
module. Consumers of structured values use the stream
module. sval
offers a json-like data model, which is more limiting than serde
's, but capable enough to represent Rust datastructures in one form or another.
This library is designed to plug a no-std-object-safe sized hole in Rust's current serialization ecosystem. The driving use-case is structured logging, where individual events are typically small, and there's no complete schema that can tie values in any one event to values in another.
sval_json
and sval_derive
are mostly pilfered from dtolnay's excellent miniserde
project.
This library requires Rust 1.31.0
.
sval
has the following optional features that can be enabled in your Cargo.toml
:
std
: assumestd
is available and add support forstd
types.derive
: add support for#[derive(Value)]
.serde
: enable integration withserde
.arbitrary-depth
: support stateful values with any depth.test
: add helpers for testing implementations ofValue
.
Add sval
to your crate dependencies:
[dependencies.sval]
version = "0.1.4"
Simple struct-like datastructures can derive sval::Value
:
[dependencies.sval]
features = ["derive"]
#[macro_use]
extern crate sval;
#[derive(Value)]
struct MyData {
id: u64,
name: String,
}
Other datastructures can implement sval::Value
manually:
use sval::value::{self, Value};
struct MyId(u64);
impl Value for MyId {
fn stream(&self, stream: &mut value::Stream) -> Result<(), value::Error> {
stream.u64(self.0)
}
}
The sval_json
crate can format any sval::Value
as json:
[dependencies.sval_json]
version = "0.1.4"
features = ["std"]
let my_json = sval_json::to_string(my_data)?;
sval
has out-of-the-box serde
integration between sval::Value
s and serde::Serialize
s. Add the serde
feature to sval
to enable it:
[dependencies.sval]
features = ["serde"]
Use the to_serialize
function to turn any sval::Value
into a serde::Serialize
:
let my_serialize = sval::serde::to_serialize(my_data);
Use the to_value
function to turn any serde::Serialize
into a sval::Value
:
let my_value = sval::serde::to_value(my_data);
When the serde
feature is available, structures that already derive Serialize
can also always derive Value
. The Value
implementation will behave the same as Serialize
:
#[derive(Serialize, Value)]
#[sval(derive_from = "serde")]
struct MyData {
id: u64,
name: String,
#[serde(flatten)]
props: serde_json::Map<String, serde_json::Value>,
}
sval
can provide a compatible Debug
implementation for any sval::Value
. Add the fmt
feature to sval
to enable it:
[dependencies.sval]
features = ["fmt"]
Use the to_debug
function to turn any sval::Value
into a std::fmt::Debug
:
fn with_value(value: impl Value) {
dbg!(sval::fmt::to_debug(&value));
..
}