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
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
use Serializer;
use crateReader;
/// Reader-aware serialization, the counterpart to [`DeserializeIn`](crate::de::DeserializeIn).
///
/// Serde's [`serde::Serialize`] carries no context for resolving a
/// [`Sym`](crate::Sym) against its interner. `SerializeIn` instead receives a
/// [`Reader`] and resolves every [`Sym`](crate::Sym) to the string it stands for,
/// producing a
/// self-describing encoding: serialize with `SerializeIn` threading a
/// [`Reader`], then deserialize with
/// [`DeserializeIn`](crate::de::DeserializeIn) threading a fresh interner to
/// recover a value whose resolved strings compare identically to the original.
///
/// The round trip preserves *strings*, not numeric handles. A fresh interner
/// assigns handles in value-traversal order — which need not match the source
/// insertion order, and is nondeterministic for the `HashMap`/`HashSet` impls —
/// so a reconstructed [`Sym`](crate::Sym) generally has a different numeric
/// value. To rebuild a corpus with *identical* handles, serialize the whole
/// [`Reader`] with [`SerializeReader`](crate::se::SerializeReader), which emits
/// every string in handle order.
///
/// Most users derive [`SerializeIn`](derive@crate::se::SerializeIn) on their structs. To
/// serialize a value through an ordinary Serde entry point, wrap it in
/// [`SerializeInWith`](crate::se::SerializeInWith).
///
/// ```
/// use internity::se::{SerializeIn, SerializeInWith};
/// use internity::{LocalLexicon, Reader};
///
/// #[derive(SerializeIn)]
/// struct Record {
/// name: internity::Sym,
/// count: u64,
/// }
///
/// let mut lexicon = LocalLexicon::new();
/// let record = Record {
/// name: lexicon.intern("widget"),
/// count: 3,
/// };
/// let reader = lexicon.freeze();
/// let json = serde_json::to_string(&SerializeInWith::new(&record, &reader)).unwrap();
/// assert_eq!(json, r#"{"name":"widget","count":3}"#);
/// ```