aboutsummaryrefslogtreecommitdiff
path: root/src/ser/map.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ser/map.rs')
-rw-r--r--src/ser/map.rs124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/ser/map.rs b/src/ser/map.rs
new file mode 100644
index 0000000..b0793e6
--- /dev/null
+++ b/src/ser/map.rs
@@ -0,0 +1,124 @@
+use super::{plain::to_plain_string, Serializer};
+use crate::error::{Error, Result};
+use log::debug;
+use serde::ser::Serialize;
+use std::io::Write;
+
+pub struct MapSerializer<'ser, W: 'ser + Write> {
+ ser: &'ser mut Serializer<W>,
+ must_close_tag: bool,
+}
+
+impl<'ser, W: 'ser + Write> MapSerializer<'ser, W> {
+ pub fn new(ser: &'ser mut Serializer<W>, must_close_tag: bool) -> Self {
+ MapSerializer {
+ ser,
+ must_close_tag,
+ }
+ }
+}
+
+impl<'ser, W: Write> serde::ser::SerializeMap for MapSerializer<'ser, W> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_key<T>(&mut self, key: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ self.ser.open_tag(&to_plain_string(key)?)?;
+ Ok(())
+ }
+
+ fn serialize_value<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ value.serialize(&mut *self.ser)?;
+ Ok(())
+ }
+
+ fn end(self) -> Result<()> {
+ if self.must_close_tag {
+ self.ser.end_tag()?;
+ }
+ Ok(())
+ }
+}
+
+pub struct StructSerializer<'ser, W: 'ser + Write> {
+ ser: &'ser mut Serializer<W>,
+ must_close_tag: bool,
+}
+
+impl<'ser, W: 'ser + Write> StructSerializer<'ser, W> {
+ pub fn new(ser: &'ser mut Serializer<W>, must_close_tag: bool) -> Self {
+ StructSerializer {
+ ser,
+ must_close_tag,
+ }
+ }
+
+ fn serialize_struct_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ if key.starts_with("@") {
+ debug!("attribute {}", key);
+ self.ser.add_attr(&key[1..], to_plain_string(value)?)
+ } else if key == "$value" {
+ self.ser.build_start_tag()?;
+ debug!("body");
+ value.serialize(&mut *self.ser)?;
+ Ok(())
+ } else {
+ self.ser.build_start_tag()?;
+ self.ser.open_tag(key)?;
+ debug!("field {}", key);
+ value.serialize(&mut *self.ser)?;
+ debug!("end field");
+ Ok(())
+ }
+ }
+
+ fn after_fields(self) -> Result<()> {
+ self.ser.build_start_tag()?;
+ self.ser.end_tag()?;
+ if self.must_close_tag {
+ self.ser.end_tag()?;
+ }
+ Ok(())
+ }
+}
+
+impl<'ser, W: 'ser + Write> serde::ser::SerializeStruct for StructSerializer<'ser, W> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ self.serialize_struct_field(key, value)
+ }
+
+ fn end(self) -> Result<()> {
+ self.after_fields()
+ }
+}
+
+impl<'ser, W: 'ser + Write> serde::ser::SerializeStructVariant for StructSerializer<'ser, W> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ self.serialize_struct_field(key, value)
+ }
+
+ fn end(self) -> Result<()> {
+ self.after_fields()
+ }
+}