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
142
143
144
//! Serde serializer generating Rust code.
//!
//! This crate can be used to "embed" something into code, having only some serialized
//! data, like JSON or YAML. This way, you'll mostly escape runtime cost of deserialization,
//! nearly as if you've written the same data directly in code by hand.
//! Of course, in most cases this cost is already negligible, but for crates which use
//! large blobs of data this crate can come in handy, improving startup times, and can
//! eliminate the need for `serde` as runtime dependency.
//!
//! ## Usage
//! In general, to embed some code into crate, you have to use the build script
//! and [`include!`][include] macro. Inside the build script, you'll generate
//! some code with one of the [functions][funcs] provided by `uneval`,
//! and then include the generated file, like this:
//! ```ignore
//! static VALUE: Type = include!(concat!(env!(OUT_DIR), "/file_name.rs"));
//! ```
//!
//! ## How does it work?
//!
//! Of course, we can't always directly construct the code for the desired value (more on this
//! in the [Limitations](#limitations) section below).
//! However, in many cases the information provided by Serde is enough.
//!
//! For every case, we'll provide an example of how the generated code can look like, as a sequence of
//! assignment statements, representing both the definition of your target struct field and the literal
//! value that will be assigned to it.
//!
//! ### Primitives
//!
//! Number literals, such as `i8` or `f32`, are directly written into the output. The only tricky part
//! is that we have to use suffixed literals, e.g. `1u8` or `1.1f64` - otherwise we'd run into the problem
//! with the float values which are in fact integers, since they would be output as integer literals,
//! not as float ones (i.e. `1` and not `1.0`) and so wouldn't typecheck.
//!
//! Boolean and character literals are also simply written directly - no surprises here.
//!
//! Example:
//! ```
//! let _: i8 = 12i8;
//! let _: u128 = 12345u128;
//! let _: f32 = -1f32;
//! let _: f64 = 12345.6789f64;
//! let _: char = 'c';
//! let _: bool = true;
//! ```
//!
//! ### Strings
//! Strings are output as string literals; your struct field should be of type `&'static str` to hold it.
//!
//! Example:
//! ```
//! let _: &'static str = "string value";
//! ```
//!
//! Byte strings are handled as byte sequences, [as recommended by Serde itself][::serde::Serializer::serialize_bytes],
//! and so we'll discuss them [below](#vec-like-types-sequences).
//!
//! ### Tuple structs and unit values
//!
//! Unit type (`()`), unit structs and unit variants (including `None`) are emitted simply by using
//! the type name. Tuple structs and variants (and newtype-flavored ones, including `Some`)
//! are emitted by writing their name (with the enum name, if necessary), parenthesis,
//! and serializing the inner values.
//!
//! Example:
//! ```
//! struct TupleStruct((), Option<u8>, Option<u8>);
//! let _: TupleStruct = TupleStruct((), None, Some(1u8));
//! ```
//!
//! ### Vec-like types (sequences)
//!
//! If the input data contains a variably-typed sequence such as Vec<T>, the target struct should have
//! a field of type `&'static [T]`.
//!
//! Example:
//! ```
//! let _: &'static [u32] = &[1u32, 2u32, 3u32];
//! ```
//!
//! ### Tuples and arrays
//!
//! The problem is that Serde doesn't distinguish between this two kinds of values: they both are treated
//! as sequences with known length, called "tuples" internally. Thus you will need to declare any fixed-length
//! sequence fields in your target struct as tuples, even if all elements are the same type. If necessary,
//! a feature flag could be added to convert them all to arrays instead.
//! ```
//! struct SourceStruct([u32; 3]);
//! struct TargetStruct((u32, u32, u32));
//! let _ = TargetStruct((1u32, 2u32, 3u32));
//! ```
//!
//! #### Zero-sized arrays
//!
//! Likewise, arrays of length zero are output as the unit type.
//! ```
//! struct SourceStruct([u32; 0]);
//! struct TargetStruct(());
//! let _ = TargetStruct(());
//! ```
//!
//! ### Maps
//!
//! Maps are generated with [phf_codegen]. If your data includes a map you will need to add [phf] to your dependencies.
//! Currently only string keys are implemented; other primitive types could be added, but that would require a refactor.
//!
//! Example:
//! ```
//! # type T = ();
//! # let phf_internals = phf::Map::new();
//! let _: phf::Map<&'static str, T> = ::phf::Map { ..phf_internals };
//! ```
//!
//! ### Structs
//!
//! Last but not the least, this case is relatively simple. Emitted code is simply the struct construction -
//! i.e. the struct name, the curly braces and a list of pairs of the form `{field name}: {serialized value}`.
//!
//! Example:
//! ```
//! struct Struct { boolean: bool, number: i32, string: &'static str }
//! let _: Struct = Struct {
//! boolean: true,
//! number: 1i32,
//! string: "string"
//! };
//! ```
//!
//! ## Limitations
//! There are some cases when `uneval` will be unable to generate valid code. Namely:
//! 1. Since Serde doesn't provide us the full path to the type in question (and in most cases it's simply unable to),
//! all the structs and enums used during value construction must be in scope.
//! As a consequence, all of them must have distinct names - otherwise, there will be name clashes.
//! 2. This serializer is intended for use with derived implementation. It may return bogus results
//! when used with customized `Serialize`.
//!
//! [include]: https://doc.rust-lang.org/stable/std/macro.include.html
pub use ;