/// A serializer used to serialize element with specified name. Unlike the [`ContentSerializer`], /// this serializer never uses variant names of enum variants, and because of that /// it is unable to serialize any enum values, except unit variants. /// /// Returns the classification of the last written type. /// /// This serializer is used for an ordinary fields in structs, which are not special /// fields named `$text` ([`TEXT_KEY`]) or `$value` ([`VALUE_KEY`]). `$text` field /// should be serialized using [`SimpleTypeSerializer`] and `$value` field should be /// serialized using [`ContentSerializer`]. /// /// This serializer does the following: /// - numbers converted to a decimal representation and serialized as `<key>value</key>`; /// - booleans serialized ether as `<key>true</key>` or `<key>false</key>`; /// - strings and characters are serialized as `<key>value</key>`. In particular, /// an empty string is serialized as `<key/>`; /// - `None` is serialized as `<key/>`; /// - `Some` and newtypes are serialized as an inner type using the same serializer; /// - units (`()`) and unit structs are serialized as `<key/>`; /// - sequences, tuples and tuple structs are serialized as repeated `<key>` tag. /// In particular, empty sequence is serialized to nothing; /// - structs are serialized as a sequence of fields wrapped in a `<key>` tag. Each /// field is serialized recursively using either `ElementSerializer`, [`ContentSerializer`] /// (`$value` fields), or [`SimpleTypeSerializer`] (`$text` fields). /// In particular, the empty struct is serialized as `<key/>`; /// - maps are serialized as a sequence of entries wrapped in a `<key>` tag. If key is /// serialized to a special name, the same rules as for struct fields are applied. /// In particular, the empty map is serialized as `<key/>`; /// - enums: /// - unit variants are serialized as `<key>variant</key>`; /// - other variants are not supported ([`SeError::Unsupported`] is returned); /// /// Usage of empty tags depends on the [`ContentSerializer::expand_empty_elements`] setting. pubstruct ElementSerializer<'w, 'k, W: Write> { /// The inner serializer that contains the settings and mostly do the actual work pub ser: ContentSerializer<'w, 'k, W>, /// Tag name used to wrap serialized types except enum variants which uses the variant name pub(super) key: XmlName<'k>,
}
impl<'w, 'k, W: Write> Serializer for ElementSerializer<'w, 'k, W> { type Ok = WriteResult; type Error = SeError;
type SerializeSeq = Self; type SerializeTuple = Self; type SerializeTupleStruct = Self; type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>; type SerializeMap = Map<'w, 'k, W>; type SerializeStruct = Struct<'w, 'k, W>; type SerializeStructVariant = Struct<'w, 'k, W>;
/// By serde contract we should serialize key of [`None`] values. If someone /// wants to skip the field entirely, he should use /// `#[serde(skip_serializing_if = "Option::is_none")]`. /// /// In XML when we serialize field, we write field name as: /// - element name, or /// - attribute name /// /// and field value as /// - content of the element, or /// - attribute value /// /// So serialization of `None` works the same as [serialization of `()`](#method.serialize_unit) fn serialize_none(self) -> Result<Self::Ok, Self::Error> { self.serialize_unit()
}
/// Writes a tag with name [`Self::key`] and content of unit variant inside. /// If variant is a special `$text` value, then empty tag `<key/>` is written. /// Otherwise a `<key>variant</key>` is written. fn serialize_unit_variant( self,
name: &'static str,
variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> { if variant == TEXT_KEY { self.ser.write_empty(self.key)
} else { self.ser.write_wrapped(self.key, |ser| {
ser.serialize_unit_variant(name, variant_index, variant)
})
}
}
/// A serializer for tuple variants. Tuples can be serialized in two modes: /// - wrapping each tuple field into a tag /// - without wrapping, fields are delimited by a space pubenum Tuple<'w, 'k, W: Write> { /// Serialize each tuple field as an element
Element(ElementSerializer<'w, 'k, W>), /// Serialize tuple as an `xs:list`: space-delimited content of fields
Text(SimpleSeq<&'w mut W>),
}
impl<'w, 'k, W: Write> SerializeTupleVariant for Tuple<'w, 'k, W> { type Ok = WriteResult; type Error = SeError;
#[inline] fn end(self) -> Result<Self::Ok, Self::Error> { matchself { Self::Element(ser) => SerializeTuple::end(ser), // Do not write indent after `$text` fields because it may be interpreted as // part of content when deserialize Self::Text(ser) => SerializeTuple::end(ser).map(|_| WriteResult::SensitiveText),
}
}
}
/// A serializer for struct variants, which serializes the struct contents inside /// of wrapping tags (`<${tag}>...</${tag}>`). /// /// Returns the classification of the last written type. /// /// Serialization of each field depends on it representation: /// - attributes written directly to the higher serializer /// - elements buffered into internal buffer and at the end written into higher /// serializer pubstructStruct<'w, 'k, W: Write> {
ser: ElementSerializer<'w, 'k, W>, /// Buffer to store serialized elements // TODO: Customization point: allow direct writing of elements, but all // attributes should be listed first. Fail, if attribute encountered after // element. Use feature to configure
children: String, /// Whether need to write indent after the last written field
write_indent: bool,
}
impl<'w, 'k, W: Write> Struct<'w, 'k, W> { #[inline] fn write_field<T>(&mutself, key: &str, value: &T) -> Result<(), SeError> where
T: ?Sized + Serialize,
{ //TODO: Customization point: allow user to determine if field is attribute or not iflet Some(key) = key.strip_prefix('@') { let key = XmlName::try_from(key)?; self.write_attribute(key, value)
} else { self.write_element(key, value)
}
}
/// Writes `value` as an attribute #[inline] fn write_attribute<T>(&mutself, key: XmlName, value: &T) -> Result<(), SeError> where
T: ?Sized + Serialize,
{ //TODO: Customization point: each attribute on new line self.ser.ser.writer.write_char(' ')?; self.ser.ser.writer.write_str(key.0)?; self.ser.ser.writer.write_char('=')?;
/// Writes `value` either as a text content, or as an element. /// /// If `key` has a magic value [`TEXT_KEY`], then `value` serialized as a /// [simple type]. /// /// If `key` has a magic value [`VALUE_KEY`], then `value` serialized as a /// [content] without wrapping in tags, otherwise it is wrapped in /// `<${key}>...</${key}>`. /// /// [simple type]: SimpleTypeSerializer /// [content]: ContentSerializer fn write_element<T>(&mutself, key: &str, value: &T) -> Result<(), SeError> where
T: ?Sized + Serialize,
{ let ser = ContentSerializer {
writer: &mutself.children,
level: self.ser.ser.level,
indent: self.ser.ser.indent.borrow(), // If previous field does not require indent, do not write it
write_indent: self.write_indent,
allow_primitive: true,
expand_empty_elements: self.ser.ser.expand_empty_elements,
};
if key == TEXT_KEY {
value.serialize(TextSerializer(ser.into_simple_type_serializer()?))?; // Text was written so we don't need to indent next field self.write_indent = false;
} elseif key == VALUE_KEY { // If element was written then we need to indent next field unless it is a text field self.write_indent = value.serialize(ser)?.allow_indent();
} else {
value.serialize(ElementSerializer {
key: XmlName::try_from(key)?,
ser,
})?; // Element was written so we need to indent next field unless it is a text field self.write_indent = true;
}
Ok(())
}
}
impl<'w, 'k, W: Write> SerializeStruct forStruct<'w, 'k, W> { type Ok = WriteResult; type Error = SeError;
#[cfg(test)] mod tests { usesuper::*; usecrate::se::content::tests::*; usecrate::se::{Indent, QuoteLevel}; usecrate::utils::Bytes; use serde::Serialize; use std::collections::BTreeMap;
let result = $data.serialize(ser).unwrap();
assert_eq!(buffer, $expected);
assert_eq!(result, WriteResult::Element);
}
};
}
/// Checks that attempt to serialize given `$data` results to a /// serialization error `$kind` with `$reason`
macro_rules! err {
($name:ident: $data:expr => $kind:ident($reason:literal)) => { #[test] fn $name() { letmut buffer = String::new(); let ser = ElementSerializer {
ser: ContentSerializer {
writer: &mut buffer,
level: QuoteLevel::Full,
indent: Indent::None,
write_indent: false,
allow_primitive: true,
expand_empty_elements: false,
},
key: XmlName("root"),
};
match $data.serialize(ser).unwrap_err() {
SeError::$kind(e) => assert_eq!(e, $reason),
e => panic!( "Expected `Err({}({}))`, but got `{:?}`",
stringify!($kind),
$reason,
e
),
} // We can write something before fail // assert_eq!(buffer, "");
}
};
}
text!(newtype: Newtype(42) => "42"); // We have no space where name of a variant can be stored
err!(enum_newtype:
Text {
before: "answer",
content: Enum::Newtype(42),
after: "answer",
}
=> Unsupported("cannot serialize enum newtype variant `Enum::Newtype` as text content value"));
// Sequences are serialized separated by spaces, all spaces inside are escaped
text!(seq: vec![1, 2, 3] => "1 2 3");
text!(seq_empty: Vec::<usize>::new());
text!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "<"&'> \
with	 &'color:turquoise'>#13; spaces \ 3");
text!(tuple_struct: Tuple("first", 42) => "first 42"); // We have no space where name of a variant can be stored
err!(enum_tuple:
Text {
before: "answer",
content: Enum::Tuple("first", 42),
after: "answer",
}
=> Unsupported("cannot serialize enum tuple variant `Enum::Tuple` as text content value"));
// Complex types cannot be serialized in `$text` field
err!(map:
Text {
before: "answer",
content: BTreeMap::from([("_1", 2), ("_3", 4)]),
after: "answer",
}
=> Unsupported("cannot serialize map as text content value"));
err!(struct_:
Text {
before: "answer",
content: Struct { key: "answer", val: (42, 42) },
after: "answer",
}
=> Unsupported("cannot serialize struct `Struct` as text content value"));
err!(enum_struct:
Text {
before: "answer",
content: Enum::Struct { key: "answer", val: (42, 42) },
after: "answer",
}
=> Unsupported("cannot serialize enum struct variant `Enum::Struct` as text content value"));
}
/// `$text` field inside a struct mod struct_ { usesuper::*; use pretty_assertions::assert_eq;
text!(newtype: Newtype(42) => "42"); // We have no space where name of a variant can be stored
err!(enum_newtype:
Text {
before: "answer",
content: Enum::Newtype(42),
after: "answer",
}
=> Unsupported("cannot serialize enum newtype variant `Enum::Newtype` as text content value"));
// Sequences are serialized separated by spaces, all spaces inside are escaped
text!(seq: vec![1, 2, 3] => "1 2 3");
text!(seq_empty: Vec::<usize>::new() => "");
text!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "<"&'> \
with	 &'color:turquoise'>#13; spaces \ 3");
text!(tuple_struct: Tuple("first", 42) => "first 42"); // We have no space where name of a variant can be stored
err!(enum_tuple:
Text {
before: "answer",
content: Enum::Tuple("first", 42),
after: "answer",
}
=> Unsupported("cannot serialize enum tuple variant `Enum::Tuple` as text content value"));
// Complex types cannot be serialized in `$text` field
err!(map:
Text {
before: "answer",
content: BTreeMap::from([("_1", 2), ("_3", 4)]),
after: "answer",
}
=> Unsupported("cannot serialize map as text content value"));
err!(struct_:
Text {
before: "answer",
content: Struct { key: "answer", val: (42, 42) },
after: "answer",
}
=> Unsupported("cannot serialize struct `Struct` as text content value"));
err!(enum_struct:
Text {
before: "answer",
content: Enum::Struct { key: "answer", val: (42, 42) },
after: "answer",
}
=> Unsupported("cannot serialize enum struct variant `Enum::Struct` as text content value"));
}
}
/// Special field name `$value` should be serialized using name, provided /// by the type of value instead of a key. Sequences serialized as a list /// of tags with that name (each element can have their own name) mod value_field { usesuper::*;
/// `$value` key in a map mod map { usesuper::*; use pretty_assertions::assert_eq;
value!(enum_unit: Enum::Unit => "<Unit/>");
err!(enum_unit_escaped:
BTreeMap::from([("$value", Enum::UnitEscaped)])
=> Unsupported("character `<` is not allowed at the start of an XML name `<\"&'>`"));
// Note that sequences of primitives serialized without delimiters!
err!(seq:
BTreeMap::from([("$value", vec![1, 2, 3])])
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
value!(seq_empty: Vec::<usize>::new());
err!(tuple:
BTreeMap::from([("$value", ("<\"&'>", "with\t\n\r spaces", 3usize))])
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
err!(tuple_struct:
BTreeMap::from([("$value", Tuple("first", 42))])
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
value!(enum_tuple: Enum::Tuple("first", 42)
=> "<Tuple>first</Tuple>\
<Tuple>42</Tuple>");
// We cannot wrap map or struct in any container and should not // flatten it, so it is impossible to serialize maps and structs
err!(map:
BTreeMap::from([("$value", BTreeMap::from([("_1", 2), ("_3", 4)]))])
=> Unsupported("serialization of map types is not supported in `$value` field"));
err!(struct_:
BTreeMap::from([("$value", Struct { key: "answer", val: (42, 42) })])
=> Unsupported("serialization of struct `Struct` is not supported in `$value` field"));
value!(enum_struct: Enum::Struct { key: "answer", val: (42, 42) }
=> "<Struct>\
<key>answer</key>\
<val>42</val>\
<val>42</val>\
</Struct>");
}
/// `$value` field inside a struct mod struct_ { usesuper::*; use pretty_assertions::assert_eq;
value!(enum_unit: Enum::Unit => "<Unit/>");
err!(enum_unit_escaped:
Value {
before: "answer",
content: Enum::UnitEscaped,
after: "answer",
}
=> Unsupported("character `<` is not allowed at the start of an XML name `<\"&'>`"));
// Note that sequences of primitives serialized without delimiters!
err!(seq:
Value {
before: "answer",
content: vec![1, 2, 3],
after: "answer",
}
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
value!(seq_empty: Vec::<usize>::new() => "");
err!(tuple:
Value {
before: "answer",
content: ("<\"&'>", "with\t\n\r spaces", 3usize),
after: "answer",
}
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
err!(tuple_struct:
Value {
before: "answer",
content: Tuple("first", 42),
after: "answer",
}
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
value!(enum_tuple: Enum::Tuple("first", 42)
=> "<Tuple>first</Tuple>\
<Tuple>42</Tuple>");
// We cannot wrap map or struct in any container and should not // flatten it, so it is impossible to serialize maps and structs
err!(map:
Value {
before: "answer",
content: BTreeMap::from([("_1", 2), ("_3", 4)]),
after: "answer",
}
=> Unsupported("serialization of map types is not supported in `$value` field"));
err!(struct_:
Value {
before: "answer",
content: Struct { key: "answer", val: (42, 42) },
after: "answer",
}
=> Unsupported("serialization of struct `Struct` is not supported in `$value` field"));
value!(enum_struct: Enum::Struct { key: "answer", val: (42, 42) }
=> "<Struct>\
<key>answer</key>\
<val>42</val>\
<val>42</val>\
</Struct>");
}
}
mod attributes { usesuper::*; use pretty_assertions::assert_eq;
mod with_indent { usesuper::*; usecrate::se::content::tests::Struct; usecrate::writer::Indentation; use pretty_assertions::assert_eq;
/// Checks that given `$data` successfully serialized as `$expected`. /// Writes `$data` using [`ElementSerializer`] with indent of two spaces.
macro_rules! serialize_as {
($name:ident: $data:expr => $expected:expr) => { #[test] fn $name() { letmut buffer = String::new(); let ser = ElementSerializer {
ser: ContentSerializer {
writer: &mut buffer,
level: QuoteLevel::Full,
indent: Indent::Owned(Indentation::new(b' ', 2)),
write_indent: false,
allow_primitive: true,
expand_empty_elements: false,
},
key: XmlName("root"),
};
let result = $data.serialize(ser).unwrap();
assert_eq!(buffer, $expected);
assert_eq!(result, WriteResult::Element);
}
};
}
/// Checks that attempt to serialize given `$data` results to a /// serialization error `$kind` with `$reason`
macro_rules! err {
($name:ident: $data:expr => $kind:ident($reason:literal)) => { #[test] fn $name() { letmut buffer = String::new(); let ser = ElementSerializer {
ser: ContentSerializer {
writer: &mut buffer,
level: QuoteLevel::Full,
indent: Indent::Owned(Indentation::new(b' ', 2)),
write_indent: false,
allow_primitive: true,
expand_empty_elements: false,
},
key: XmlName("root"),
};
match $data.serialize(ser).unwrap_err() {
SeError::$kind(e) => assert_eq!(e, $reason),
e => panic!( "Expected `Err({}({}))`, but got `{:?}`",
stringify!($kind),
$reason,
e
),
} // We can write something before fail // assert_eq!(buffer, "");
}
};
}
text!(newtype: Newtype(42) => "42"); // We have no space where name of a variant can be stored
err!(enum_newtype:
Text {
before: "answer",
content: Enum::Newtype(42),
after: "answer",
}
=> Unsupported("cannot serialize enum newtype variant `Enum::Newtype` as text content value"));
// Sequences are serialized separated by spaces, all spaces inside are escaped
text!(seq: vec![1, 2, 3] => "1 2 3");
text!(seq_empty: Vec::<usize>::new());
text!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "<"&'> \
with	 &'color:turquoise'>#13; spaces \ 3");
text!(tuple_struct: Tuple("first", 42) => "first 42"); // We have no space where name of a variant can be stored
err!(enum_tuple:
Text {
before: "answer",
content: Enum::Tuple("first", 42),
after: "answer",
}
=> Unsupported("cannot serialize enum tuple variant `Enum::Tuple` as text content value"));
// Complex types cannot be serialized in `$text` field
err!(map:
Text {
before: "answer",
content: BTreeMap::from([("_1", 2), ("_3", 4)]),
after: "answer",
}
=> Unsupported("cannot serialize map as text content value"));
err!(struct_:
Text {
before: "answer",
content: Struct { key: "answer", val: (42, 42) },
after: "answer",
}
=> Unsupported("cannot serialize struct `Struct` as text content value"));
err!(enum_struct:
Text {
before: "answer",
content: Enum::Struct { key: "answer", val: (42, 42) },
after: "answer",
}
=> Unsupported("cannot serialize enum struct variant `Enum::Struct` as text content value"));
}
/// `$text` field inside a struct mod struct_ { usesuper::*; use pretty_assertions::assert_eq;
macro_rules! text {
($name:ident: $data:expr => $expected:literal) => {
serialize_as!($name: // Serialization started from ElementSerializer::serialize_struct
Text {
before: "answer",
content: $data,
after: "answer",
}
=> concat!( "<root>\n <before>answer</before>",
$expected, "<after>answer</after>\n</root>",
));
};
}
text!(newtype: Newtype(42) => "42"); // We have no space where name of a variant can be stored
err!(enum_newtype:
Text {
before: "answer",
content: Enum::Newtype(42),
after: "answer",
}
=> Unsupported("cannot serialize enum newtype variant `Enum::Newtype` as text content value"));
// Sequences are serialized separated by spaces, all spaces inside are escaped
text!(seq: vec![1, 2, 3] => "1 2 3");
text!(seq_empty: Vec::<usize>::new() => "");
text!(tuple: ("<\"&'>", "with\t\n\r spaces", 3usize)
=> "<"&'> \
with	 &'color:turquoise'>#13; spaces \ 3");
text!(tuple_struct: Tuple("first", 42) => "first 42"); // We have no space where name of a variant can be stored
err!(enum_tuple:
Text {
before: "answer",
content: Enum::Tuple("first", 42),
after: "answer",
}
=> Unsupported("cannot serialize enum tuple variant `Enum::Tuple` as text content value"));
// Complex types cannot be serialized in `$text` field
err!(map:
Text {
before: "answer",
content: BTreeMap::from([("_1", 2), ("_3", 4)]),
after: "answer",
}
=> Unsupported("cannot serialize map as text content value"));
err!(struct_:
Text {
before: "answer",
content: Struct { key: "answer", val: (42, 42) },
after: "answer",
}
=> Unsupported("cannot serialize struct `Struct` as text content value"));
err!(enum_struct:
Text {
before: "answer",
content: Enum::Struct { key: "answer", val: (42, 42) },
after: "answer",
}
=> Unsupported("cannot serialize enum struct variant `Enum::Struct` as text content value"));
}
}
/// Special field name `$value` should be serialized using name, provided /// by the type of value instead of a key. Sequences serialized as a list /// of tags with that name (each element can have their own name) mod value_field { usesuper::*;
/// `$value` key in a map mod map { usesuper::*; use pretty_assertions::assert_eq;
macro_rules! value {
($name:ident: $data:expr) => {
serialize_as!($name: // Serialization started from ElementSerializer::serialize_map
BTreeMap::from([("$value", $data)])
=> "<root/>");
};
($name:ident: $data:expr => $expected:literal) => {
serialize_as!($name: // Serialization started from ElementSerializer::serialize_map
BTreeMap::from([("$value", $data)])
=> concat!("<root>", $expected,"</root>"));
};
}
value!(enum_unit: Enum::Unit => "\n <Unit/>\n");
err!(enum_unit_escaped:
BTreeMap::from([("$value", Enum::UnitEscaped)])
=> Unsupported("character `<` is not allowed at the start of an XML name `<\"&'>`"));
err!(seq:
BTreeMap::from([("$value", vec![1, 2, 3])])
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
value!(seq_empty: Vec::<usize>::new());
err!(tuple:
BTreeMap::from([("$value", ("<\"&'>", "with\t\n\r spaces", 3usize))])
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
err!(tuple_struct:
BTreeMap::from([("$value", Tuple("first", 42))])
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
value!(enum_tuple: Enum::Tuple("first", 42)
=> "\n \
<Tuple>first</Tuple>\n \
<Tuple>42</Tuple>\n");
// We cannot wrap map or struct in any container and should not // flatten it, so it is impossible to serialize maps and structs
err!(map:
BTreeMap::from([("$value", BTreeMap::from([("_1", 2), ("_3", 4)]))])
=> Unsupported("serialization of map types is not supported in `$value` field"));
err!(struct_:
BTreeMap::from([("$value", Struct { key: "answer", val: (42, 42) })])
=> Unsupported("serialization of struct `Struct` is not supported in `$value` field"));
value!(enum_struct: Enum::Struct { key: "answer", val: (42, 42) }
=> "\n \
<Struct>\n \
<key>answer</key>\n \
<val>42</val>\n \
<val>42</val>\n \
</Struct>\n");
}
/// `$value` field inside a struct mod struct_ { usesuper::*; use pretty_assertions::assert_eq;
macro_rules! value {
($name:ident: $data:expr => $expected:literal) => {
serialize_as!($name: // Serialization started from ElementSerializer::serialize_struct
Value {
before: "answer",
content: $data,
after: "answer",
}
=> concat!( "<root>\n <before>answer</before>",
$expected, "<after>answer</after>\n</root>",
));
};
}
value!(enum_unit: Enum::Unit => "\n <Unit/>\n ");
err!(enum_unit_escaped:
Value {
before: "answer",
content: Enum::UnitEscaped,
after: "answer",
}
=> Unsupported("character `<` is not allowed at the start of an XML name `<\"&'>`"));
err!(seq:
Value {
before: "answer",
content: vec![1, 2, 3],
after: "answer",
}
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
value!(seq_empty: Vec::<usize>::new() => "");
err!(tuple:
Value {
before: "answer",
content: ("<\"&'>", "with\t\n\r spaces", 3usize),
after: "answer",
}
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
err!(tuple_struct:
Value {
before: "answer",
content: Tuple("first", 42),
after: "answer",
}
=> Unsupported("consequent primitives would be serialized without delimiter and cannot be deserialized back"));
value!(enum_tuple: Enum::Tuple("first", 42)
=> "\n \
<Tuple>first</Tuple>\n \
<Tuple>42</Tuple>\n ");
// We cannot wrap map or struct in any container and should not // flatten it, so it is impossible to serialize maps and structs
err!(map:
Value {
before: "answer",
content: BTreeMap::from([("_1", 2), ("_3", 4)]),
after: "answer",
}
=> Unsupported("serialization of map types is not supported in `$value` field"));
err!(struct_:
Value {
before: "answer",
content: Struct { key: "answer", val: (42, 42) },
after: "answer",
}
=> Unsupported("serialization of struct `Struct` is not supported in `$value` field"));
value!(enum_struct: Enum::Struct { key: "answer", val: (42, 42) }
=> "\n \
<Struct>\n \
<key>answer</key>\n \
<val>42</val>\n \
<val>42</val>\n \
</Struct>\n ");
}
}
mod attributes { usesuper::*; use pretty_assertions::assert_eq;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.