serde_tagged/ser/
internal.rs

1//! Serialization of internally tagged values.
2//!
3//! Tagging values internally will embed the tag in the value. As the tag is
4//! being embedded in the value, not all types can be supported by this format
5//! (see section below).
6//!
7//! This format is similar to the internally-tagged enum format provided by
8//! serde, however allows for various tag types (not only `str` and `u32`).
9//!
10//! # Warning
11//!
12//! Deserialization of internally tagged values requires a self-describing
13//! data format.
14//!
15//! Furthermore, neither [`serialize`](serialize) nor the
16//! [`Serializer`](Serializer) check for collision of the tag-key with
17//! field-names or map-keys of the value with the tag-key. It is up to the
18//! caller to make sure that such collisions do not occur.
19//!
20//! # Supported types
21//!
22//! Only the following types (of [Serde's data model][datamodel]) are supported
23//! by this tagging format:
24//!
25//! - __seq__
26//!   * Dynamically sized sequences.
27//!   * The tag will be the first element of the sequence.
28//! - __tuple__
29//!   * Statically sized sequences.
30//!   * The tag will be the first element of the tuple.
31//! - __map__
32//!   * Dynamically sized mappings.
33//!   * The tag-key and tag pair will be added as (first) entry of the mapping:
34//! - __struct__
35//!   * Any normal struct (e.g. `struct Name { ... }`).
36//!   * The tag will be added as first field under the specified name.
37//! - __unit struct__
38//!   * A struct without content (e.g. `struct Unit;`).
39//!   * The struct will be serialized as normal struct and the tag will be added
40//!     as first (and only) field under the specified name.
41//! - __newtype struct__ _only if it contains a value that can be serialized
42//!   with this format_
43//!   * A tuple struct contianing only a single value (e.g.
44//!     `struct Newtype(i32)`).
45//!   * The struct will be serialized as tuple struct and the tag will be added
46//!     as first element of the tuple.
47//! - __tuple struct__
48//!   * A struct contianing multiple unnamed members (e.g.
49//!     `struct Tuple(i32, i32)`).
50//!   * The tag will be added as first element of the tuple.
51//! - __internally tagged enum__: any variant
52//!   * An enum with the `#[serde(tag="<tag-key>")]` attribute.
53//!   * The tag will be added as first field under the specified name.
54//! - __adjacently tagged enum__: any variant
55//!   * An enum with the `#[serde(tag="<tag-key>", content="<content-key>")]`
56//!     attribute.
57//!   * The tag will be added as entry with the specified name as key to the
58//!     generated mapping.
59//! - __untagged enum__: _tuple_, _non-primitive newtype_, and _struct_
60//!   variants only
61//!   * An enum with the `#[serde(untagged)]` attribute.
62//!   * The tag will be embedded using the previously elaborated rules
63//!     corresponding to the respective variant type.
64//!
65//! Primitive types and externally tagged enums are not supported.
66//!
67//! # Examples serializing to JSON
68//!
69//! ## A Simple struct
70//!
71//! Serializing a value `foo` with
72//!
73//! ```
74//! # #[macro_use]
75//! # extern crate serde_derive;
76//! # extern crate serde_json;
77//! # extern crate serde_tagged;
78//! #
79//! #[derive(Serialize)]
80//! struct Foo {
81//!     bar: &'static str,
82//! }
83//!
84//! # fn main() {
85//! let foo = Foo { bar: "baz" };
86//!
87//! let mut serializer = serde_json::Serializer::new(std::io::stdout());
88//! serde_tagged::ser::internal::serialize(&mut serializer, "tag-key", "my-tag", &foo).unwrap();
89//! # }
90//! ```
91//!
92//! with a tag-value of `"my-tag"` and a tag-field-name of `"tag-key"` will
93//! produce the following JSON output:
94//!
95//! ```json
96//! {
97//!     "tag-key": "my-tag",
98//!     "bar": "baz"
99//! }
100//! ```
101//!
102//!
103//! [datamodel]: https://serde.rs/data-model.html
104//!
105
106use serde;
107
108use ser::HasDelegate;
109
110
111/// Embeds a tag into the specified value and then serializes it using the
112/// provided serializer.
113///
114/// Due to the tag being embedded into the value, not all value-types are
115/// supported. The specified serializer performs the actual serialization and
116/// thus controls the data format. For more information on this trag-format and
117/// the supported values, see the [module documentation](::ser::internal).
118///
119/// This method is a convenience function that creates and uses the
120/// [`Serializer`](Serializer) internally.
121/// 
122/// # Warning
123/// 
124/// This function does not provide any checks regarding collisions of the
125/// `tag_key` with field-names or map-keys. The responsibility for such checks
126/// reside with the caller.
127pub fn serialize<S, T: ?Sized, V: ?Sized>(
128    serializer: S,
129    tag_key: &'static str,
130    tag: &T,
131    value: &V,
132) -> Result<S::Ok, S::Error>
133where
134    S: serde::Serializer,
135    T: serde::Serialize,
136    V: serde::Serialize,
137{
138    value.serialize(Serializer::new(serializer, tag_key, tag))
139}
140
141
142/// A serializer that embeds a tag into to the provided value and then
143/// serializes it.
144///
145/// Due to the tag being embedded into the value, not all value-types are
146/// supported. The provided serializer performs the actual serialization and
147/// thus controls the data format. For more information on this trag-format and
148/// the supported values, see the [module documentation](::ser::internal).
149///
150/// Due to the tag being embedded into the value, not all value-types are
151/// supported. For more details see the [module documentation](::ser::internal).
152/// 
153/// # Warning
154/// 
155/// This serializer does not provide any checks regarding collisions of the
156/// `tag_key` with field-names or map-keys. The responsibility for such checks
157/// reside with the caller.
158pub struct Serializer<'a, S, T: ?Sized + 'a> {
159    delegate: S,
160    tag_key:  &'static str,
161    tag:      &'a T,
162}
163
164impl<'a, S, T: ?Sized> Serializer<'a, S, T>
165where
166    S: serde::Serializer,
167    T: serde::Serialize + 'a,
168{
169    /// Creates a new Serializer with the specified tag-key, tag and underlying
170    /// serializer.
171    pub fn new(delegate: S, tag_key: &'static str, tag: &'a T) -> Self {
172        Serializer {
173            delegate,
174            tag_key,
175            tag,
176        }
177    }
178
179    fn unsupported(&self, what: &'static str) -> S::Error {
180        serde::ser::Error::custom(format_args!("cannot serialize {} as tagged value", what))
181    }
182}
183
184impl<'a, S, T: ?Sized> HasDelegate for Serializer<'a, S, T>
185where
186    S: serde::Serializer,
187    T: serde::Serialize,
188{
189    type Ok = S::Ok;
190    type Error = S::Error;
191    type Delegate = S;
192
193    fn delegate(self) -> S {
194        self.delegate
195    }
196}
197
198impl<'a, S, T: ?Sized> serde::Serializer for Serializer<'a, S, T>
199where
200    S: serde::Serializer,
201    T: serde::Serialize + 'a,
202{
203    type Ok = S::Ok;
204    type Error = S::Error;
205
206    type SerializeSeq = S::SerializeSeq;
207    type SerializeTuple = S::SerializeTuple;
208    type SerializeTupleStruct = S::SerializeTupleStruct;
209    type SerializeMap = S::SerializeMap;
210    type SerializeStruct = S::SerializeStruct;
211    type SerializeTupleVariant = serde::ser::Impossible<Self::Ok, Self::Error>;
212    type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>;
213
214    fn serialize_bool(self, _value: bool) -> Result<Self::Ok, Self::Error> {
215        Err(self.unsupported("a boolean"))
216    }
217
218    fn serialize_i8(self, _value: i8) -> Result<Self::Ok, Self::Error> {
219        Err(self.unsupported("an integer"))
220    }
221
222    fn serialize_i16(self, _value: i16) -> Result<Self::Ok, Self::Error> {
223        Err(self.unsupported("an integer"))
224    }
225
226    fn serialize_i32(self, _value: i32) -> Result<Self::Ok, Self::Error> {
227        Err(self.unsupported("an integer"))
228    }
229
230    fn serialize_i64(self, _value: i64) -> Result<Self::Ok, Self::Error> {
231        Err(self.unsupported("an integer"))
232    }
233
234    fn serialize_u8(self, _value: u8) -> Result<Self::Ok, Self::Error> {
235        Err(self.unsupported("an integer"))
236    }
237
238    fn serialize_u16(self, _value: u16) -> Result<Self::Ok, Self::Error> {
239        Err(self.unsupported("an integer"))
240    }
241
242    fn serialize_u32(self, _value: u32) -> Result<Self::Ok, Self::Error> {
243        Err(self.unsupported("an integer"))
244    }
245
246    fn serialize_u64(self, _value: u64) -> Result<Self::Ok, Self::Error> {
247        Err(self.unsupported("an integer"))
248    }
249
250    fn serialize_f32(self, _value: f32) -> Result<Self::Ok, Self::Error> {
251        Err(self.unsupported("a float"))
252    }
253
254    fn serialize_f64(self, _value: f64) -> Result<Self::Ok, Self::Error> {
255        Err(self.unsupported("a float"))
256    }
257
258    fn serialize_char(self, _value: char) -> Result<Self::Ok, Self::Error> {
259        Err(self.unsupported("a char"))
260    }
261
262    fn serialize_str(self, _value: &str) -> Result<Self::Ok, Self::Error> {
263        Err(self.unsupported("a string"))
264    }
265
266    fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> {
267        Err(self.unsupported("a byte array"))
268    }
269
270    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
271        Err(self.unsupported("an optional"))
272    }
273
274    fn serialize_some<V: ?Sized>(self, _value: &V) -> Result<Self::Ok, Self::Error>
275    where
276        V: serde::Serialize,
277    {
278        Err(self.unsupported("an optional"))
279    }
280
281    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
282        Err(self.unsupported("a unit"))
283    }
284
285    fn serialize_unit_variant(
286        self,
287        _name: &'static str,
288        _variant_index: u32,
289        _variant: &'static str,
290    ) -> Result<Self::Ok, Self::Error> {
291        Err(self.unsupported("a unit-variant"))
292    }
293
294    fn serialize_newtype_variant<V: ?Sized>(
295        self,
296        _name: &'static str,
297        _variant_index: u32,
298        _variant: &'static str,
299        _value: &V,
300    ) -> Result<Self::Ok, Self::Error>
301    where
302        V: serde::Serialize,
303    {
304        Err(self.unsupported("a newtype-variant"))
305    }
306
307    fn serialize_tuple_variant(
308        self,
309        _name: &'static str,
310        _variant_index: u32,
311        _variant: &'static str,
312        _len: usize,
313    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
314        Err(self.unsupported("a tuple-variant"))
315    }
316
317    fn serialize_struct_variant(
318        self,
319        _name: &'static str,
320        _variant_index: u32,
321        _variant: &'static str,
322        _len: usize,
323    ) -> Result<Self::SerializeStructVariant, Self::Error> {
324        Err(self.unsupported("a struct-variant"))
325    }
326
327    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
328        use serde::ser::SerializeTuple;
329
330        let mut state = self.delegate.serialize_tuple(len + 1)?;
331        state.serialize_element(self.tag)?;
332        Ok(state)
333    }
334
335    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
336        use serde::ser::SerializeSeq;
337
338        let mut state = self.delegate.serialize_seq(len.map(|len| len + 1))?;
339        state.serialize_element(self.tag)?;
340        Ok(state)
341    }
342
343    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
344        use serde::ser::SerializeMap;
345
346        let mut state = self.delegate.serialize_map(len.map(|len| len + 1))?;
347        state.serialize_entry(self.tag_key, self.tag)?;
348        Ok(state)
349    }
350
351    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
352        use serde::ser::SerializeStruct;
353
354        let mut state = self.delegate.serialize_struct(name, 1)?;
355        state.serialize_field(self.tag_key, self.tag)?;
356        state.end()
357    }
358
359    fn serialize_newtype_struct<V: ?Sized>(
360        self,
361        _name: &'static str,
362        value: &V,
363    ) -> Result<Self::Ok, Self::Error>
364    where
365        V: serde::Serialize,
366    {
367        value.serialize(self)
368    }
369
370    fn serialize_tuple_struct(
371        self,
372        name: &'static str,
373        len: usize,
374    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
375        use serde::ser::SerializeTupleStruct;
376
377        let mut state = self.delegate.serialize_tuple_struct(name, len + 1)?;
378        state.serialize_field(self.tag)?;
379        Ok(state)
380    }
381
382    fn serialize_struct(
383        self,
384        name: &'static str,
385        len: usize,
386    ) -> Result<Self::SerializeStruct, Self::Error> {
387        use serde::ser::SerializeStruct;
388
389        let mut state = self.delegate.serialize_struct(name, len + 1)?;
390        state.serialize_field(self.tag_key, self.tag)?;
391        Ok(state)
392    }
393
394    fn is_human_readable(&self) -> bool {
395        self.delegate.is_human_readable()
396    }
397}