[−][src]Crate sval
A small, no-std, object-safe, serialization-only framework.
The sval
API is built around two key traits:
Value
is a trait for data with a streamable structure. It's likeserde::Serialize
.Stream
is a trait for receiving the structure of a value. It's likeserde::Serializer
.
Getting started
Add sval
to your Cargo.toml
:
[dependencies.sval]
version = "1.0.0-alpha.5"
Supported formats
- JSON, the ubiquitous JavaScript Object Notation used by many HTTP APIs.
Streaming values
The structure of a Value
can be streamed to a Stream
.
in a single call
For simple use-cases, use the stream
function to stream the structure of a value:
sval::stream(MyStream, 42)?;
where 42
is a Value
and MyStream
is a Stream
.
over multiple calls
More involved use-cases may want to build up structure over time. Use a stream::OwnedStream
to hang on to a stream and pass it values over time.
The following example wraps up a stream in an API that lets callers treat it like a map:
// Create a `Map` stream that wraps up another one let mut stream = Map::new(my_stream)?; // Stream it some entries stream.entry("a", 42)?; stream.entry("b", 17)?; // Eventually we end the wrapper and return the original stream let my_stream = stream.end()?; }
An implementation of Map
could then look like this:
use sval::{ value::Value, stream::{self, OwnedStream}, }; struct Map { // Using `OwnedStream<MyStream>` instead of just `MyStream` // gives us better ergonomics and validation stream: OwnedStream<MyStream>, } impl Map { fn new(stream: MyStream) -> Result<Self, sval::Error> { let mut stream = OwnedStream::new(stream); stream.map_begin(None)?; Ok(Map { stream, }) } fn entry(&mut self, k: impl Value, v: impl Value) -> Result<(), sval::Error> { self.stream.map_key(k)?; self.stream.map_value(v)?; Ok(()) } fn end(mut self) -> Result<MyStream, sval::Error> { self.stream.map_end()?; Ok(self.stream.into_inner()) } }
serde
integration
Use the serde
Cargo feature to enable integration with serde
:
[dependencies.sval]
features = ["serde"]
When serde
is available, the Value
trait can also be derived
based on an existing Serialize
implementation:
#[macro_use] extern crate sval; #[derive(Serialize, Value)] #[sval(derive_from = "serde")] pub enum Data { Variant(i32, String), }
std::fmt
integration
Use the fmt
Cargo feature to enable extended integration with std::fmt
:
[dependencies.sval]
features = ["fmt"]
When fmt
is available, arbitrary Value
s can be treated like std::fmt::Debug
:
fn with_value(value: impl Value) { dbg!(sval::fmt::to_debug(&value)); // Do something with the value }
Modules
fmt | Integration between |
serde | Integration between |
stream | A stream for datastructures. |
test | Helpers for testing value implementations. |
value | A streamable value. |
Structs
Error | An error encountered while visiting a value. |
Functions
stream |
Derive Macros
Value |