1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*!
Structured, streaming values.

`sval` is a serialization framework that treats data as a flat stream of tokens.
The source of that data could be some Rust object or parsed from some encoding.
It's well suited to self-describing, text-based formats like JSON.

# A note on docs

Even though this library's API is stable, these docs themselves are still a
work-in-progress.

# Getting started

Add `sval` to your `Cargo.toml`:

```toml
[dependencies.sval]
version = "2.13.0"
```

By default, `sval` doesn't depend on Rust's standard library or integrate
with its collection types. To include them, add the `alloc` or `std` features:

```toml
[dependencies.sval]
version = "2.13.0"
features = ["std"]
```

# The `Value` trait

[`Value`] is a trait for data types to implement that surfaces their structure
through visitors called _streams_. `Value` is like `serde`'s `Serialize`. It
can also be used like `serde`'s `Deserialize`.

Many standard types in Rust implement the `Value` trait. It can be derived
on your own types using the `sval_derive` library.

# The `Stream` trait

[`Stream`] is a trait for data formats and visitors to implement that observes
the structure of _values_. `Stream` is like `serde`'s `Serializer`. It can
also be used like `serde`'s `Deserializer`.

# Data-model

`sval`'s data-model is defined by the [`Stream`] trait. It includes:

- Null
- Booleans (`true`, `false`)
- Text blobs
- Binary blobs
- Integers (`u8`-`u128`, `i8`-`i128`)
- Binary floating points (`f32`-`f64`)
- Maps
- Sequences
- Records
- Tuples
- Enums
- Tags

# Tags

[`Tag`] is a type for extending `sval`'s data-model with new kinds of values.
Rust's own `()` and `Option<T>` types are expressed as tags. Other examples of
tags include text that encodes RFC3339 timestamps or RFC4122 UUIDs.

The [`tags`] module contains built-in tags. Other libraries may define their own tags too.

# Buffering

Complex or arbitrarily-sized values like strings, maps, and sequences can all be
streamed as chunks across multiple calls to avoid intermediate buffering when it's not necessary.

# Object safety

The [`Value`] and [`Stream`] traits aren't object-safe themselves, but object-safe
wrappers are provided by the `sval_dynamic` crate. This wrapper works in no-std.
*/

#![no_std]
#![deny(missing_docs)]

#[cfg(feature = "std")]
extern crate std;

#[cfg(all(feature = "alloc", not(feature = "std")))]
extern crate alloc;
#[cfg(all(feature = "alloc", not(feature = "std")))]
extern crate core;

#[cfg(all(feature = "alloc", not(feature = "std")))]
mod std {
    pub use crate::{
        alloc::{borrow, boxed, collections, string, vec},
        core::{cmp, convert, fmt, hash, marker, mem, ops, result, str, write},
    };
}

#[cfg(all(not(feature = "alloc"), not(feature = "std")))]
extern crate core as std;

#[cfg(feature = "derive")]
#[doc(inline)]
pub use sval_derive_macros::*;

mod data;
mod result;
mod stream;
mod value;

#[doc(inline)]
pub use self::{data::*, result::*, stream::*, value::*};

/**
A generic streaming result.
*/
pub type Result<T = (), E = Error> = std::result::Result<T, E>;

/**
Stream a value through a stream.
*/
pub fn stream<'sval>(
    stream: &mut (impl Stream<'sval> + ?Sized),
    value: &'sval (impl Value + ?Sized),
) -> Result {
    stream.value(value)
}

/**
Stream a value through a stream with an arbitrarily short lifetime.
*/
pub fn stream_computed<'sval>(
    stream: &mut (impl Stream<'sval> + ?Sized),
    value: impl Value,
) -> Result {
    stream.value_computed(&value)
}

// NOTE: Tests for implementations of `Value` are in `sval_test`