[][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 like serde::Serialize.
  • Stream is a trait for receiving the structure of a value. It's like serde::Serializer.

Getting started

Add sval to your Cargo.toml:

[dependencies.sval]
version = "0.5.2"

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:

use sval::{
    Value,
    stream::{self, OwnedStream},
};

// We begin the wrapper over `MyStream`
let mut stream = StreamPairs::new()?;

// Pairs can be streamed independently
stream.pair("a", 42)?;
stream.pair("b", 17)?;

// Eventually we end the wrapper and return the underlying `MyStream`
let my_stream = stream.end()?;

struct StreamPairs {
    // Using `OwnedStream<MyStream>` instead of just `MyStream`
    // gives us better ergonomics and validation
    stream: OwnedStream<MyStream>,
}

impl StreamPairs {
    fn new() -> Result<Self, stream::Error> {
        let mut stream = OwnedStream::new(MyStream);
        stream.map_begin(None)?;

        Ok(StreamPairs {
            stream,
        })
    }

    fn pair(&mut self, k: impl Value, v: impl Value) -> Result<(), stream::Error> {
        self.stream.map_key(k)?;
        self.stream.map_value(v)?;

        Ok(())
    }

    fn end(mut self) -> Result<MyStream, stream::Error> {
        self.stream.map_end()?;

        Ok(self.stream.into_inner())
    }
}

The above example captures an OwnedStream<MyStream> and then allows multiple key-value pairs to be streamed through it before finishing.

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:

This example is not tested
use sval::Value;

#[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 Values can be treated like std::fmt::Debug:

fn with_value(value: impl sval::Value) {
    dbg!(sval::fmt::to_debug(&value));

    // Do something with the value
}

Re-exports

pub use self::stream::Stream;
pub use self::value::Value;

Modules

fmt

Integration between sval and std::fmt.

serde

Integration between sval and serde.

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

Stream the structure of a Value using the given Stream.

Derive Macros

Value