diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/de/mod.rs | 22 | ||||
-rw-r--r-- | src/error.rs | 6 | ||||
-rw-r--r-- | src/lib.rs | 14 | ||||
-rw-r--r-- | src/ser/map.rs | 124 | ||||
-rw-r--r-- | src/ser/mod.rs | 412 | ||||
-rw-r--r-- | src/ser/plain.rs | 196 | ||||
-rw-r--r-- | src/ser/seq.rs | 37 | ||||
-rw-r--r-- | src/ser/tuple.rs | 91 | ||||
-rw-r--r-- | src/ser/var.rs | 103 |
9 files changed, 686 insertions, 319 deletions
diff --git a/src/de/mod.rs b/src/de/mod.rs index 21240c5..486b38c 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -1,6 +1,6 @@ use std::{io::Read, marker::PhantomData}; -use log::debug; +use log::trace; use serde::de::{self, Unexpected}; use serde::forward_to_deserialize_any; use xml::name::OwnedName; @@ -21,10 +21,7 @@ mod var; /// A convenience method for deserialize some object from a string. /// /// ```rust -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde; -/// # extern crate serde_xml_rs; +/// # use serde::{Deserialize, Serialize}; /// # use serde_xml_rs::from_str; /// #[derive(Debug, Deserialize, PartialEq)] /// struct Item { @@ -44,10 +41,7 @@ pub fn from_str<'de, T: de::Deserialize<'de>>(s: &str) -> Result<T> { /// A convenience method for deserialize some object from a reader. /// /// ```rust -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde; -/// # extern crate serde_xml_rs; +/// # use serde::Deserialize; /// # use serde_xml_rs::from_reader; /// #[derive(Debug, Deserialize, PartialEq)] /// struct Item { @@ -108,12 +102,8 @@ impl<'de, R: Read> RootDeserializer<R> { /// default. Enabling this option may incur additional memory usage. /// /// ```rust - /// # #[macro_use] - /// # extern crate serde_derive; - /// # extern crate serde; - /// # extern crate serde_xml_rs; - /// # use serde_xml_rs::from_reader; /// # use serde::Deserialize; + /// # use serde_xml_rs::from_reader; /// #[derive(Debug, Deserialize, PartialEq)] /// struct Foo { /// bar: Vec<usize>, @@ -164,7 +154,7 @@ impl<'de, R: Read, B: BufferedXmlReader<R>> Deserializer<R, B> { fn peek(&mut self) -> Result<&XmlEvent> { let peeked = self.buffered_reader.peek()?; - debug!("Peeked {:?}", peeked); + trace!("Peeked {:?}", peeked); Ok(peeked) } @@ -181,7 +171,7 @@ impl<'de, R: Read, B: BufferedXmlReader<R>> Deserializer<R, B> { } _ => {} } - debug!("Fetched {:?}", next); + trace!("Fetched {:?}", next); Ok(next) } diff --git a/src/error.rs b/src/error.rs index 5061b52..50a15c0 100644 --- a/src/error.rs +++ b/src/error.rs @@ -47,6 +47,12 @@ pub enum Error { #[from] source: ::xml::reader::Error, }, + + #[error("Writer: {source}")] + Writer { + #[from] + source: ::xml::writer::Error, + }, } pub type Result<T> = std::result::Result<T, Error>; @@ -49,8 +49,7 @@ //! ## Basic example //! //! ```rust -//! use serde; -//! use serde_derive::{Deserialize, Serialize}; +//! use serde::{Deserialize, Serialize}; //! use serde_xml_rs::{from_str, to_string}; //! //! #[derive(Debug, Serialize, Deserialize, PartialEq)] @@ -60,7 +59,7 @@ //! } //! //! fn main() { -//! let src = r#"<Item><name>Banana</name><source>Store</source></Item>"#; +//! let src = r#"<?xml version="1.0" encoding="UTF-8"?><Item><name>Banana</name><source>Store</source></Item>"#; //! let should_be = Item { //! name: "Banana".to_string(), //! source: "Store".to_string(), @@ -77,8 +76,7 @@ //! ## Tag contents //! //! ```rust -//! # use serde; -//! # use serde_derive::{Deserialize, Serialize}; +//! # use serde::{Deserialize, Serialize}; //! # use serde_xml_rs::{from_str, to_string}; //! //! #[derive(Debug, Serialize, Deserialize, PartialEq)] @@ -102,8 +100,7 @@ //! ## Repeated tags //! //! ```rust -//! # use serde; -//! # use serde_derive::{Deserialize, Serialize}; +//! # use serde::{Deserialize, Serialize}; //! # use serde_xml_rs::{from_str, to_string}; //! //! #[derive(Debug, Serialize, Deserialize, PartialEq)] @@ -160,8 +157,7 @@ //! ## Custom EventReader //! //! ```rust -//! use serde::Deserialize; -//! use serde_derive::{Deserialize, Serialize}; +//! use serde::{Deserialize, Serialize}; //! use serde_xml_rs::{from_str, to_string, de::Deserializer}; //! use xml::reader::{EventReader, ParserConfig}; //! 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() + } +} diff --git a/src/ser/mod.rs b/src/ser/mod.rs index a29ca6f..8130a8d 100644 --- a/src/ser/mod.rs +++ b/src/ser/mod.rs @@ -1,22 +1,25 @@ -use std::fmt::Display; -use std::io::Write; - -use serde::ser::{self, Impossible, Serialize}; - -use self::var::{Map, Struct}; +mod map; +mod plain; +mod seq; +mod tuple; + +use self::{ + map::{MapSerializer, StructSerializer}, + seq::SeqSeralizer, + tuple::TupleSerializer, +}; use crate::error::{Error, Result}; - -mod var; +use log::debug; +use serde::ser::Serialize; +use std::{collections::HashMap, io::Write}; +use xml::writer::{EmitterConfig, EventWriter, XmlEvent}; /// A convenience method for serializing some object to a buffer. /// /// # Examples /// /// ```rust -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde; -/// # extern crate serde_xml_rs; +/// # use serde::Serialize; /// # use serde_xml_rs::to_writer; /// #[derive(Serialize)] /// struct Person { @@ -44,10 +47,7 @@ pub fn to_writer<W: Write, S: Serialize>(writer: W, value: &S) -> Result<()> { /// # Examples /// /// ```rust -/// # #[macro_use] -/// # extern crate serde_derive; -/// # extern crate serde; -/// # extern crate serde_xml_rs; +/// # use serde::Serialize; /// # use serde_xml_rs::to_string; /// #[derive(Serialize)] /// struct Person { @@ -77,266 +77,329 @@ pub struct Serializer<W> where W: Write, { - writer: W, + writer: EventWriter<W>, + root: bool, + current_tag: String, + current_tag_attrs: Option<HashMap<&'static str, String>>, } impl<W> Serializer<W> where W: Write, { + fn new_from_writer(writer: EventWriter<W>) -> Self { + Self { + writer, + root: true, + current_tag: "".into(), + current_tag_attrs: None, + } + } + pub fn new(writer: W) -> Self { - Self { writer: writer } + Self::new_from_writer(EmitterConfig::new().create_writer(writer)) } - fn write_primitive<P: Display>(&mut self, primitive: P) -> Result<()> { - write!(self.writer, "{}", primitive)?; + fn next(&mut self, event: XmlEvent) -> Result<()> { + self.writer.write(event)?; Ok(()) } - fn write_wrapped<S: Serialize>(&mut self, tag: &str, value: S) -> Result<()> { - write!(self.writer, "<{}>", tag)?; - value.serialize(&mut *self)?; - write!(self.writer, "</{}>", tag)?; + fn characters(&mut self, s: &str) -> Result<()> { + self.next(XmlEvent::characters(s)) + } + + fn start_document(&mut self) -> Result<()> { + self.next(XmlEvent::StartDocument { + encoding: Default::default(), + standalone: Default::default(), + version: xml::common::XmlVersion::Version10, + }) + } + + fn open_root_tag(&mut self, name: &'static str) -> Result<()> { + if self.root { + self.root = false; + self.start_document()?; + self.open_tag(name)?; + } + Ok(()) + } + + fn open_tag(&mut self, tag_name: &str) -> Result<()> { + self.current_tag = tag_name.into(); + self.current_tag_attrs = Some(HashMap::new()); + Ok(()) + } + + fn reopen_tag(&mut self) -> Result<()> { + self.current_tag_attrs = Some(HashMap::new()); Ok(()) } + + fn abandon_tag(&mut self) -> Result<()> { + self.current_tag = "".into(); + self.current_tag_attrs = None; + Ok(()) + } + + fn add_attr(&mut self, name: &'static str, value: String) -> Result<()> { + self.current_tag_attrs + .as_mut() + .ok_or(Error::Custom { + field: format!("Cannot add attribute {}", name), + }) + .map(|attrs| { + attrs.insert(name, value); + }) + } + + fn build_start_tag(&mut self) -> Result<bool> { + if let Some(attrs) = self.current_tag_attrs.take() { + self.start_tag(&self.current_tag(), attrs)?; + Ok(true) + } else { + Ok(false) + } + } + + fn start_tag(&mut self, tag_name: &str, attrs: HashMap<&str, String>) -> Result<()> { + let element = attrs + .iter() + .fold(XmlEvent::start_element(tag_name), |b, (&name, value)| { + b.attr(name, value) + }); + + self.next(element.into()) + } + + fn end_tag(&mut self) -> Result<()> { + self.next(XmlEvent::end_element().into()) + } + + fn current_tag(&self) -> String { + self.current_tag.clone() + } } -#[allow(unused_variables)] -impl<'w, W> ser::Serializer for &'w mut Serializer<W> -where - W: Write, -{ +impl<'ser, W: Write> serde::ser::Serializer for &'ser mut Serializer<W> { type Ok = (); type Error = Error; - type SerializeSeq = Impossible<Self::Ok, Self::Error>; - type SerializeTuple = Impossible<Self::Ok, Self::Error>; - type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>; - type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>; - type SerializeMap = Map<'w, W>; - type SerializeStruct = Struct<'w, W>; - type SerializeStructVariant = Impossible<Self::Ok, Self::Error>; + type SerializeSeq = SeqSeralizer<'ser, W>; + type SerializeTuple = TupleSerializer<'ser, W>; + type SerializeTupleStruct = TupleSerializer<'ser, W>; + type SerializeTupleVariant = TupleSerializer<'ser, W>; + type SerializeMap = MapSerializer<'ser, W>; + type SerializeStruct = StructSerializer<'ser, W>; + type SerializeStructVariant = StructSerializer<'ser, W>; fn serialize_bool(self, v: bool) -> Result<Self::Ok> { - if v { - write!(self.writer, "true")?; - } else { - write!(self.writer, "false")?; - } - - Ok(()) + self.serialize_str(&v.to_string()) } fn serialize_i8(self, v: i8) -> Result<Self::Ok> { - self.write_primitive(v) + self.serialize_i64(i64::from(v)) } fn serialize_i16(self, v: i16) -> Result<Self::Ok> { - self.write_primitive(v) + self.serialize_i64(i64::from(v)) } fn serialize_i32(self, v: i32) -> Result<Self::Ok> { - self.write_primitive(v) + self.serialize_i64(i64::from(v)) } fn serialize_i64(self, v: i64) -> Result<Self::Ok> { - self.write_primitive(v) + self.serialize_str(&v.to_string()) } fn serialize_u8(self, v: u8) -> Result<Self::Ok> { - self.write_primitive(v) + self.serialize_u64(u64::from(v)) } fn serialize_u16(self, v: u16) -> Result<Self::Ok> { - self.write_primitive(v) + self.serialize_u64(u64::from(v)) } fn serialize_u32(self, v: u32) -> Result<Self::Ok> { - self.write_primitive(v) + self.serialize_u64(u64::from(v)) } fn serialize_u64(self, v: u64) -> Result<Self::Ok> { - self.write_primitive(v) + let must_close_tag = self.build_start_tag()?; + self.characters(&v.to_string())?; + if must_close_tag { + self.end_tag()?; + } + Ok(()) } fn serialize_f32(self, v: f32) -> Result<Self::Ok> { - self.write_primitive(v) + self.serialize_f64(f64::from(v)) } fn serialize_f64(self, v: f64) -> Result<Self::Ok> { - self.write_primitive(v) + self.serialize_str(&v.to_string()) } fn serialize_char(self, v: char) -> Result<Self::Ok> { - self.write_primitive(v) + self.serialize_str(&v.to_string()) } - fn serialize_str(self, value: &str) -> Result<Self::Ok> { - self.write_primitive(value) + fn serialize_str(self, v: &str) -> Result<Self::Ok> { + let must_close_tag = self.build_start_tag()?; + self.characters(v)?; + if must_close_tag { + self.end_tag()?; + } + Ok(()) } - fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok> { - // TODO: I imagine you'd want to use base64 here. - // Not sure how to roundtrip effectively though... - Err(Error::UnsupportedOperation { - operation: "serialize_bytes".to_string(), - }) + fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> { + unimplemented!() } fn serialize_none(self) -> Result<Self::Ok> { + debug!("None"); + let must_close_tag = self.build_start_tag()?; + if must_close_tag { + self.end_tag()?; + } Ok(()) } - fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok> { + fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok> + where + T: Serialize, + { + debug!("Some"); value.serialize(self) } fn serialize_unit(self) -> Result<Self::Ok> { - self.serialize_none() + debug!("Unit"); + let must_close_tag = self.build_start_tag()?; + if must_close_tag { + self.end_tag()?; + } + Ok(()) } fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok> { - self.write_wrapped(name, ()) + debug!("Unit struct {}", name); + self.serialize_unit() } fn serialize_unit_variant( self, name: &'static str, - variant_index: u32, + _variant_index: u32, variant: &'static str, ) -> Result<Self::Ok> { - Err(Error::UnsupportedOperation { - operation: "serialize_unit_variant".to_string(), - }) + debug!("Unit variant {}::{}", name, variant); + self.start_tag(variant, HashMap::new())?; + self.serialize_unit()?; + self.end_tag()?; + Ok(()) } - fn serialize_newtype_struct<T: ?Sized + Serialize>( - self, - name: &'static str, - value: &T, - ) -> Result<Self::Ok> { - Err(Error::UnsupportedOperation { - operation: "serialize_newtype_struct".to_string(), - }) + fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<Self::Ok> + where + T: Serialize, + { + debug!("Newtype struct {}", name); + value.serialize(self) } - fn serialize_newtype_variant<T: ?Sized + Serialize>( + fn serialize_newtype_variant<T: ?Sized>( self, name: &'static str, - variant_index: u32, + _variant_index: u32, variant: &'static str, value: &T, - ) -> Result<Self::Ok> { - self.write_wrapped(variant, value) + ) -> Result<Self::Ok> + where + T: Serialize, + { + let must_close_tag = self.build_start_tag()?; + + debug!("Newtype variant {}::{}", name, variant); + self.open_tag(variant)?; + value.serialize(&mut *self)?; + + if must_close_tag { + self.end_tag()?; + } + Ok(()) } - fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> { - // TODO: Figure out how to constrain the things written to only be composites - Err(Error::UnsupportedOperation { - operation: "serialize_seq".to_string(), - }) + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { + debug!("Sequence"); + Ok(SeqSeralizer::new(self)) } - fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> { - Err(Error::UnsupportedOperation { - operation: "serialize_tuple".to_string(), - }) + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { + debug!("Tuple"); + let must_close_tag = self.build_start_tag()?; + Ok(TupleSerializer::new(self, must_close_tag)) } fn serialize_tuple_struct( self, name: &'static str, - len: usize, + _len: usize, ) -> Result<Self::SerializeTupleStruct> { - Err(Error::UnsupportedOperation { - operation: "serialize_tuple_struct".to_string(), - }) + debug!("Tuple struct {}", name); + let must_close_tag = self.build_start_tag()?; + Ok(TupleSerializer::new(self, must_close_tag)) } fn serialize_tuple_variant( self, name: &'static str, - variant_index: u32, + _variant_index: u32, variant: &'static str, - len: usize, + _len: usize, ) -> Result<Self::SerializeTupleVariant> { - Err(Error::UnsupportedOperation { - operation: "serialize_tuple_variant".to_string(), - }) + debug!("Tuple variant {}::{}", name, variant); + let must_close_tag = self.build_start_tag()?; + self.start_tag(variant, HashMap::new())?; + Ok(TupleSerializer::new(self, must_close_tag)) } - fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> { - Ok(Map::new(self)) + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { + let must_close_tag = self.build_start_tag()?; + Ok(MapSerializer::new(self, must_close_tag)) } - fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> { - write!(self.writer, "<{}>", name)?; - Ok(Struct::new(self, name)) + fn serialize_struct(self, name: &'static str, _len: usize) -> Result<Self::SerializeStruct> { + self.open_root_tag(name)?; + + debug!("Struct {}", name); + Ok(StructSerializer::new(self, false)) } fn serialize_struct_variant( self, name: &'static str, - variant_index: u32, + _variant_index: u32, variant: &'static str, - len: usize, + _len: usize, ) -> Result<Self::SerializeStructVariant> { - Err(Error::UnsupportedOperation { - operation: "Result".to_string(), - }) + self.open_root_tag(name)?; + + debug!("Struct variant {}", variant); + let must_close_tag = self.build_start_tag()?; + self.open_tag(variant)?; + Ok(StructSerializer::new(self, must_close_tag)) } } #[cfg(test)] mod tests { use super::*; - use serde::ser::{SerializeMap, SerializeStruct}; - use serde::Serializer as SerSerializer; - use serde_derive::Serialize; - - #[test] - fn test_serialize_bool() { - let inputs = vec![(true, "true"), (false, "false")]; - - for (src, should_be) in inputs { - let mut buffer = Vec::new(); - - { - let mut ser = Serializer::new(&mut buffer); - ser.serialize_bool(src).unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - assert_eq!(got, should_be); - } - } - - #[test] - fn test_start_serialize_struct() { - let mut buffer = Vec::new(); - - { - let mut ser = Serializer::new(&mut buffer); - let _ = ser.serialize_struct("foo", 0).unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - assert_eq!(got, "<foo>"); - } - - #[test] - fn test_serialize_struct_field() { - let mut buffer = Vec::new(); - - { - let mut ser = Serializer::new(&mut buffer); - let mut struct_ser = Struct::new(&mut ser, "baz"); - struct_ser.serialize_field("foo", "bar").unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - assert_eq!(got, "<foo>bar</foo>"); - } + use serde::Serialize; #[test] fn test_serialize_struct() { @@ -350,7 +413,7 @@ mod tests { name: "Bob".to_string(), age: 42, }; - let should_be = "<Person><name>Bob</name><age>42</age></Person>"; + let should_be = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Person><name>Bob</name><age>42</age></Person>"; let mut buffer = Vec::new(); { @@ -363,22 +426,6 @@ mod tests { } #[test] - fn test_serialize_map_entries() { - let should_be = "<name>Bob</name><age>5</age>"; - let mut buffer = Vec::new(); - - { - let mut ser = Serializer::new(&mut buffer); - let mut map = Map::new(&mut ser); - map.serialize_entry("name", "Bob").unwrap(); - map.serialize_entry("age", "5").unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - assert_eq!(got, should_be); - } - - #[test] fn test_serialize_enum() { #[derive(Serialize)] #[allow(dead_code)] @@ -389,7 +436,7 @@ mod tests { } let mut buffer = Vec::new(); - let should_be = "<Boolean>true</Boolean>"; + let should_be = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Boolean>true</Boolean>"; { let mut ser = Serializer::new(&mut buffer); @@ -400,21 +447,4 @@ mod tests { let got = String::from_utf8(buffer).unwrap(); assert_eq!(got, should_be); } - - #[test] - #[ignore] - fn serialize_a_list() { - let inputs = vec![1, 2, 3, 4]; - - let mut buffer = Vec::new(); - - { - let mut ser = Serializer::new(&mut buffer); - inputs.serialize(&mut ser).unwrap(); - } - - let got = String::from_utf8(buffer).unwrap(); - println!("{}", got); - panic!(); - } } diff --git a/src/ser/plain.rs b/src/ser/plain.rs new file mode 100644 index 0000000..49e2964 --- /dev/null +++ b/src/ser/plain.rs @@ -0,0 +1,196 @@ +use std::io::Write; + +use serde::ser::{Impossible, Serialize}; + +use crate::error::{Error, Result}; + +pub fn to_plain_string<T>(value: &T) -> Result<String> +where + T: ?Sized + Serialize, +{ + let mut writer = Vec::with_capacity(128); + value.serialize(&mut PlainStringSerializer::new(&mut writer))?; + + let string = String::from_utf8(writer)?; + Ok(string) +} + +struct PlainStringSerializer<W: Write> { + writer: W, +} + +impl<W: Write> PlainStringSerializer<W> { + fn new(writer: W) -> Self { + PlainStringSerializer { writer } + } + + fn characters(&mut self, s: &str) -> Result<()> { + write!(self.writer, "{}", s)?; + Ok(()) + } +} + +impl<'ser, W: 'ser + Write> serde::ser::Serializer for &'ser mut PlainStringSerializer<W> { + type Ok = (); + type Error = Error; + + type SerializeSeq = Impossible<Self::Ok, Self::Error>; + type SerializeTuple = Impossible<Self::Ok, Self::Error>; + type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>; + type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>; + type SerializeMap = Impossible<Self::Ok, Self::Error>; + type SerializeStruct = Impossible<Self::Ok, Self::Error>; + type SerializeStructVariant = Impossible<Self::Ok, Self::Error>; + + fn serialize_bool(self, v: bool) -> Result<Self::Ok> { + self.characters(&v.to_string()) + } + + fn serialize_i8(self, v: i8) -> Result<Self::Ok> { + self.serialize_i64(i64::from(v)) + } + + fn serialize_i16(self, v: i16) -> Result<Self::Ok> { + self.serialize_i64(i64::from(v)) + } + + fn serialize_i32(self, v: i32) -> Result<Self::Ok> { + self.serialize_i64(i64::from(v)) + } + + fn serialize_i64(self, v: i64) -> Result<Self::Ok> { + self.characters(&v.to_string()) + } + + fn serialize_u8(self, v: u8) -> Result<Self::Ok> { + self.serialize_u64(u64::from(v)) + } + + fn serialize_u16(self, v: u16) -> Result<Self::Ok> { + self.serialize_u64(u64::from(v)) + } + + fn serialize_u32(self, v: u32) -> Result<Self::Ok> { + self.serialize_u64(u64::from(v)) + } + + fn serialize_u64(self, v: u64) -> Result<Self::Ok> { + self.characters(&v.to_string()) + } + + fn serialize_f32(self, v: f32) -> Result<Self::Ok> { + self.serialize_f64(f64::from(v)) + } + + fn serialize_f64(self, v: f64) -> Result<Self::Ok> { + self.characters(&v.to_string()) + } + + fn serialize_char(self, v: char) -> Result<Self::Ok> { + self.characters(&v.to_string()) + } + + fn serialize_str(self, v: &str) -> Result<Self::Ok> { + self.characters(v) + } + + fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok> { + unimplemented!() + } + + fn serialize_none(self) -> Result<Self::Ok> { + unimplemented!() + } + + fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok> + where + T: Serialize, + { + unimplemented!() + } + + fn serialize_unit(self) -> Result<Self::Ok> { + unimplemented!() + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> { + unimplemented!() + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<Self::Ok> { + unimplemented!() + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + _name: &'static str, + _value: &T, + ) -> Result<Self::Ok> + where + T: Serialize, + { + unimplemented!() + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<Self::Ok> + where + T: Serialize, + { + unimplemented!() + } + + fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> { + unimplemented!() + } + + fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> { + unimplemented!() + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleStruct> { + unimplemented!() + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeTupleVariant> { + unimplemented!() + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> { + unimplemented!() + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> { + unimplemented!() + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant> { + unimplemented!() + } +} diff --git a/src/ser/seq.rs b/src/ser/seq.rs new file mode 100644 index 0000000..1681534 --- /dev/null +++ b/src/ser/seq.rs @@ -0,0 +1,37 @@ +use super::Serializer; +use crate::error::{Error, Result}; +use serde::ser::Serialize; +use std::io::Write; + +pub struct SeqSeralizer<'ser, W: 'ser + Write> { + ser: &'ser mut Serializer<W>, +} + +impl<'ser, W: 'ser + Write> SeqSeralizer<'ser, W> { + pub fn new(ser: &'ser mut Serializer<W>) -> Self { + SeqSeralizer { ser } + } +} + +impl<'ser, W: 'ser + Write> serde::ser::SerializeSeq for SeqSeralizer<'ser, W> { + type Ok = (); + type Error = Error; + + fn serialize_element<T>(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + let must_close_tag = self.ser.build_start_tag()?; + value.serialize(&mut *self.ser)?; + if must_close_tag { + self.ser.end_tag()?; + self.ser.reopen_tag()?; + } + Ok(()) + } + + fn end(self) -> Result<()> { + self.ser.abandon_tag()?; + Ok(()) + } +} diff --git a/src/ser/tuple.rs b/src/ser/tuple.rs new file mode 100644 index 0000000..3d893f8 --- /dev/null +++ b/src/ser/tuple.rs @@ -0,0 +1,91 @@ +use std::io::Write; + +use serde::ser::Serialize; + +use super::Serializer; +use crate::error::{Error, Result}; + +pub struct TupleSerializer<'ser, W: 'ser + Write> { + ser: &'ser mut Serializer<W>, + must_close_tag: bool, + first: bool, +} + +impl<'ser, W: 'ser + Write> TupleSerializer<'ser, W> { + pub fn new(ser: &'ser mut Serializer<W>, must_close_tag: bool) -> Self { + Self { + ser, + must_close_tag, + first: true, + } + } + + fn serialize_item<T>(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + if self.first { + self.first = false; + } else { + self.ser.characters(" ")?; + } + value.serialize(&mut *self.ser)?; + Ok(()) + } + + fn after_items(self) -> Result<()> { + if self.must_close_tag { + self.ser.end_tag()?; + } + Ok(()) + } +} + +impl<'ser, W: 'ser + Write> serde::ser::SerializeTupleVariant for TupleSerializer<'ser, W> { + type Ok = (); + type Error = Error; + + fn serialize_field<T>(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.serialize_item(value) + } + + fn end(self) -> Result<()> { + self.ser.end_tag()?; + self.after_items() + } +} + +impl<'ser, W: 'ser + Write> serde::ser::SerializeTupleStruct for TupleSerializer<'ser, W> { + type Ok = (); + type Error = Error; + + fn serialize_field<T>(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.serialize_item(value) + } + + fn end(self) -> Result<()> { + self.after_items() + } +} + +impl<'ser, W: 'ser + Write> serde::ser::SerializeTuple for TupleSerializer<'ser, W> { + type Ok = (); + type Error = Error; + + fn serialize_element<T>(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.serialize_item(value) + } + + fn end(self) -> Result<()> { + self.after_items() + } +} diff --git a/src/ser/var.rs b/src/ser/var.rs deleted file mode 100644 index e4ee0f0..0000000 --- a/src/ser/var.rs +++ /dev/null @@ -1,103 +0,0 @@ -use std::io::Write; - -use serde::ser::{self, Serialize}; - -use crate::error::{Error, Result}; -use crate::ser::Serializer; - -/// An implementation of `SerializeMap` for serializing to XML. -pub struct Map<'w, W> -where - W: Write, -{ - parent: &'w mut Serializer<W>, -} - -impl<'w, W> Map<'w, W> -where - W: 'w + Write, -{ - pub fn new(parent: &'w mut Serializer<W>) -> Map<'w, W> { - Map { parent } - } -} - -impl<'w, W> ser::SerializeMap for Map<'w, W> -where - W: 'w + Write, -{ - type Ok = (); - type Error = Error; - - fn serialize_key<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<()> { - panic!("impossible to serialize the key on its own, please use serialize_entry()") - } - - fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> { - value.serialize(&mut *self.parent) - } - - fn end(self) -> Result<Self::Ok> { - Ok(()) - } - - fn serialize_entry<K: ?Sized + Serialize, V: ?Sized + Serialize>( - &mut self, - key: &K, - value: &V, - ) -> Result<()> { - // TODO: Is it possible to ensure our key is never a composite type? - // Anything which isn't a "primitive" would lead to malformed XML here... - write!(self.parent.writer, "<")?; - key.serialize(&mut *self.parent)?; - write!(self.parent.writer, ">")?; - - value.serialize(&mut *self.parent)?; - - write!(self.parent.writer, "</")?; - key.serialize(&mut *self.parent)?; - write!(self.parent.writer, ">")?; - Ok(()) - } -} - -/// An implementation of `SerializeStruct` for serializing to XML. -pub struct Struct<'w, W> -where - W: Write, -{ - parent: &'w mut Serializer<W>, - name: &'w str, -} - -impl<'w, W> Struct<'w, W> -where - W: 'w + Write, -{ - pub fn new(parent: &'w mut Serializer<W>, name: &'w str) -> Struct<'w, W> { - Struct { parent, name } - } -} - -impl<'w, W> ser::SerializeStruct for Struct<'w, W> -where - W: 'w + Write, -{ - type Ok = (); - type Error = Error; - - fn serialize_field<T: ?Sized + Serialize>( - &mut self, - key: &'static str, - value: &T, - ) -> Result<()> { - write!(self.parent.writer, "<{}>", key)?; - value.serialize(&mut *self.parent)?; - write!(self.parent.writer, "</{}>", key)?; - Ok(()) - } - - fn end(self) -> Result<Self::Ok> { - write!(self.parent.writer, "</{}>", self.name).map_err(|e| e.into()) - } -} |