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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//! Serde adapters for reading historical schemas and writing schema values.
//!
//! Enable the crate's `serde` feature to use these helpers. Deserialization
//! first lets Serde build the requested schema type, then migrates it to its
//! latest version and converts it into the associated application model.
//! Serialization converts a model into a chosen schema representation before
//! asking Serde to write it.
//!
//! Use [`deserialize_into_model`] on a field in a type that derives
//! [`Deserialize`](::serde::Deserialize). For a complete value, deserialize
//! the schema and convert it with [`TryIntoModel::try_into_model`]. Use
//! [`serialize_into_schema`] for a field in a type that derives
//! [`Serialize`](::serde::Serialize). When you
//! own the model value, [`IntoSchema::into_schema`] avoids the clone required
//! by the borrowed serialization helper.
//!
//! Conversion errors must implement [`Display`](core::fmt::Display) so they
//! can be reported as Serde errors. This requirement applies only to these
//! adapters; the conversion traits themselves do not require displayable
//! errors.
use crate;
/// Deserializes a schema value and converts it into its associated model.
///
/// Use this with Serde's `deserialize_with` attribute when a containing type
/// derives `Deserialize` normally.
///
/// `T` is the schema type decoded by Serde. Its value is migrated to its latest
/// representation before conversion to `T::Model`.
///
/// # Example
///
/// ```rust
/// # use thisversion::{VersionBoundary};
/// #
/// # #[derive(Deserialize, Serialize)]
/// # struct UserV1 { name: String }
/// #
/// # #[derive(Deserialize, Serialize, VersionBoundary)]
/// # #[thisversion(model = User)]
/// # struct UserV2 { name: String }
/// #
/// # impl From<UserV1> for UserV2 {
/// # fn from(previous: UserV1) -> Self {
/// # Self { name: previous.name }
/// # }
/// # }
/// #
/// #
/// use serde::{Deserialize, Serialize};
/// use thisversion::serde::deserialize_into_model;
/// use thisversion::VersionFamily;
///
/// #[derive(Deserialize, Serialize, VersionFamily)]
/// #[serde(tag = "version", content = "data")]
/// enum UserVersions {
/// V1(UserV1),
/// V2(UserV2),
/// //...
/// }
///
/// // ...
///
/// #[derive(Debug, PartialEq, Eq)]
/// struct User { name: String }
///
/// #[derive(Deserialize)]
/// struct Record {
/// #[serde(deserialize_with = "deserialize_into_model::<UserVersions, _>")]
/// user: User,
/// }
///
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let record: Record = serde_json::from_str(
/// r#"{"user":{"version":"V1","data":{"name":"Ada"}}}"#,
/// )?;
///
/// assert_eq!(record.user.name, "Ada");
///
/// # Ok(())
/// # }
/// ```
/// Converts a model into the requested schema representation and serializes it.
///
/// `T` selects the schema representation, including a bare schema or version
/// family. Conversion follows its `IntoSchema<T>` implementation.
///
/// Use this with Serde's `serialize_with` attribute when a containing type
/// derives `Serialize` normally.
///
/// `T::Model` must implement `Clone` because Serde passes fields to
/// `serialize_with` by shared reference, while `IntoSchema` intentionally
/// consumes the model. The model is therefore cloned before conversion. When
/// ownership is available, prefer calling `IntoSchema::into_schema` directly to
/// avoid the clone.
///
/// # Example
///
/// ```rust
/// # use thisversion::{VersionBoundary};
/// #
/// # #[derive(Deserialize, Serialize)]
/// # struct UserV1 { name: String }
/// #
/// # #[derive(Deserialize, Serialize, VersionBoundary)]
/// # #[thisversion(model = User)]
/// # struct UserV2 { name: String }
/// #
/// # impl From<UserV1> for UserV2 {
/// # fn from(previous: UserV1) -> Self {
/// # Self { name: previous.name }
/// # }
/// # }
/// #
/// #
/// use serde::{Deserialize, Serialize};
/// use thisversion::serde::serialize_into_schema;
/// use thisversion::VersionFamily;
///
/// #[derive(Deserialize, Serialize, VersionFamily)]
/// #[serde(tag = "version", content = "data")]
/// enum UserVersions {
/// V1(UserV1),
/// V2(UserV2),
/// //...
/// }
///
/// // ...
///
/// #[derive(Debug, PartialEq, Eq, Clone)]
/// struct User { name: String }
///
/// #[derive(Serialize)]
/// struct Record {
/// #[serde(serialize_with = "serialize_into_schema::<UserVersions, _>")]
/// user: User,
/// }
///
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let record = Record { user: User { name: "Ada".into() } };
///
/// let json = serde_json::to_string(&record)?;
///
/// assert_eq!( json, r#"{"user":{"version":"V2","data":{"name":"Ada"}}}"# );
///
/// # Ok(())
/// # }
/// ```