Skip to content

Commit d872771

Browse files
authored
Merge pull request tafia#304 from fwcd/unit-variants-as-string
Add $primitive for serializing unit variants as string
2 parents 4c9c759 + f168143 commit d872771

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

README.md

+17
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,23 @@ struct Root {
243243
}
244244
```
245245

246+
### Serializing unit variants as primitives
247+
248+
The `$primitive` prefix lets you serialize enum variants without associated values (internally referred to as _unit variants_) as primitive strings rather than self-closing tags. Consider the following definitions:
249+
250+
```rust,ignore
251+
enum Foo {
252+
#[serde(rename = "$primitive=Bar")]
253+
Bar
254+
}
255+
256+
struct Root {
257+
foo: Foo
258+
}
259+
```
260+
261+
Serializing `Root { foo: Foo::Bar }` will then yield `<Root foo="Bar"/>` instead of `<Root><Bar/></Root>`.
262+
246263
### Performance
247264

248265
Note that despite not focusing on performance (there are several unecessary copies), it remains about 10x faster than serde-xml-rs.

src/de/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ use std::io::BufRead;
128128

129129
pub(crate) const INNER_VALUE: &str = "$value";
130130
pub(crate) const UNFLATTEN_PREFIX: &str = "$unflatten=";
131+
pub(crate) const PRIMITIVE_PREFIX: &str = "$primitive=";
131132

132133
/// Simplified event which contains only these variants that used by deserializer
133134
#[derive(Debug, PartialEq)]

src/se/mod.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod var;
44

55
use self::var::{Map, Seq, Struct, Tuple};
66
use crate::{
7+
de::PRIMITIVE_PREFIX,
78
errors::serialize::DeError,
89
events::{BytesEnd, BytesStart, BytesText, Event},
910
writer::Writer,
@@ -232,7 +233,12 @@ impl<'r, 'w, W: Write> ser::Serializer for &'w mut Serializer<'r, W> {
232233
_variant_index: u32,
233234
variant: &'static str,
234235
) -> Result<Self::Ok, DeError> {
235-
self.write_self_closed(variant)
236+
if variant.starts_with(PRIMITIVE_PREFIX) {
237+
let variant = variant.split_at(PRIMITIVE_PREFIX.len()).1;
238+
self.write_primitive(variant, false)
239+
} else {
240+
self.write_self_closed(variant)
241+
}
236242
}
237243

238244
fn serialize_newtype_struct<T: ?Sized + Serialize>(
@@ -634,6 +640,8 @@ mod tests {
634640
#[derive(Serialize)]
635641
enum Node {
636642
Unit,
643+
#[serde(rename = "$primitive=PrimitiveUnit")]
644+
PrimitiveUnit,
637645
Newtype(bool),
638646
Tuple(f64, String),
639647
Struct {
@@ -666,6 +674,21 @@ mod tests {
666674
assert_eq!(got, should_be);
667675
}
668676

677+
#[test]
678+
fn primitive_unit() {
679+
let mut buffer = Vec::new();
680+
let should_be = "PrimitiveUnit";
681+
682+
{
683+
let mut ser = Serializer::with_root(Writer::new(&mut buffer), Some("root"));
684+
let node = Node::PrimitiveUnit;
685+
node.serialize(&mut ser).unwrap();
686+
}
687+
688+
let got = String::from_utf8(buffer).unwrap();
689+
assert_eq!(got, should_be);
690+
}
691+
669692
#[test]
670693
fn newtype() {
671694
let mut buffer = Vec::new();

0 commit comments

Comments
 (0)