use std::io::{self, Write};
use std::{result, fmt};
use serde::ser::{self, Serialize, Impossible};
use write::Writer;
use parse::Item;
#[derive(Copy, Clone, Debug)]
pub enum UnsupportedType {
Bool,
Bytes,
None,
Unit,
Seq,
Map,
}
#[derive(Debug, Clone)]
pub enum Error {
Custom(String),
UnsupportedType(UnsupportedType),
NonStringKey,
TopLevelMap,
OrphanValue,
MapKeyMissing,
}
impl From<io::Error> for Error {
fn from(e: io::Error) -> Self {
Error::Custom(e.to_string())
}
}
impl From<UnsupportedType> for Error {
fn from(t: UnsupportedType) -> Self {
Error::UnsupportedType(t)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl ::std::error::Error for Error {
fn description(&self) -> &str {
"INI serialization error"
}
}
impl ser::Error for Error {
fn custom<T: fmt::Display>(msg: T) -> Self {
Error::Custom(msg.to_string())
}
}
pub type Result<T> = result::Result<T, Error>;
pub struct Serializer<W> {
writer: Writer<W>,
}
impl<W> Serializer<W> {
pub fn new(writer: Writer<W>) -> Self {
Serializer {
writer: writer,
}
}
}
struct ValueSerializer<'a, 'k, W: 'a> {
writer: &'a mut Writer<W>,
key: &'k str,
top_level: bool,
allow_values: &'a mut bool,
}
pub struct MapSerializer<'a, W: 'a> {
writer: &'a mut Writer<W>,
key: Option<String>,
top_level: bool,
allow_values: bool,
}
impl<'a, 'k, W: Write> ValueSerializer<'a, 'k, W> {
fn serialize_string(&mut self, s: String) -> Result<()> {
if !self.top_level || *self.allow_values {
self.writer.write(&Item::Value {
key: self.key.into(),
value: s,
}).map_err(Into::into)
} else {
Err(Error::OrphanValue)
}
}
fn serialize_section(&mut self) -> Result<()> {
self.writer.write(&Item::Section {
name: self.key.into(),
}).map_err(Into::into)
}
}
impl<'a, 'k, W: Write + 'a> ser::Serializer for ValueSerializer<'a, 'k, 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 = MapSerializer<'a, W>;
type SerializeStruct = MapSerializer<'a, W>;
type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
fn serialize_bool(self, _v: bool) -> Result<()> {
Err(UnsupportedType::Bool.into())
}
fn serialize_i8(mut self, v: i8) -> Result<()> {
self.serialize_string(v.to_string())
}
fn serialize_i16(mut self, v: i16) -> Result<()> {
self.serialize_string(v.to_string())
}
fn serialize_i32(mut self, v: i32) -> Result<()> {
self.serialize_string(v.to_string())
}
fn serialize_i64(mut self, v: i64) -> Result<()> {
self.serialize_string(v.to_string())
}
fn serialize_u8(mut self, v: u8) -> Result<()> {
self.serialize_string(v.to_string())
}
fn serialize_u16(mut self, v: u16) -> Result<()> {
self.serialize_string(v.to_string())
}
fn serialize_u32(mut self, v: u32) -> Result<()> {
self.serialize_string(v.to_string())
}
fn serialize_u64(mut self, v: u64) -> Result<()> {
self.serialize_string(v.to_string())
}
fn serialize_f32(mut self, v: f32) -> Result<()> {
self.serialize_string(v.to_string())
}
fn serialize_f64(mut self, v: f64) -> Result<()> {
self.serialize_string(v.to_string())
}
fn serialize_char(mut self, v: char) -> Result<()> {
self.serialize_string(v.to_string())
}
fn serialize_str(mut self, v: &str) -> Result<()> {
self.serialize_string(v.into())
}
fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
Err(UnsupportedType::Bytes.into())
}
fn serialize_none(self) -> Result<()> {
Err(UnsupportedType::None.into())
}
fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<()> {
value.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
Err(UnsupportedType::Unit.into())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
Err(UnsupportedType::Unit.into())
}
fn serialize_unit_variant(self, _name: &'static str, _variant_index: u32, variant: &'static str) -> Result<()> {
self.serialize_str(variant)
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(self, _name: &'static str, value: &T) -> Result<()> {
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T) -> Result<()> {
Err(UnsupportedType::Unit.into())
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
Err(UnsupportedType::Seq.into())
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeTupleStruct> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize) -> Result<Self::SerializeTupleVariant> {
Err(UnsupportedType::Seq.into())
}
fn serialize_map(mut self, _len: Option<usize>) -> Result<Self::SerializeMap> {
if self.top_level {
*self.allow_values = false;
self.serialize_section().map(move |_| MapSerializer {
writer: self.writer,
key: None,
top_level: false,
allow_values: false,
})
} else {
Err(UnsupportedType::Map.into())
}
}
fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
self.serialize_map(Some(len))
}
fn serialize_struct_variant(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize) -> Result<Self::SerializeStructVariant> {
Err(UnsupportedType::Map.into())
}
}
#[derive(Default)]
struct KeySerializer {
key: String,
}
impl<'a> ser::Serializer for &'a mut KeySerializer {
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<()> {
Err(Error::NonStringKey)
}
fn serialize_i8(self, _v: i8) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_i16(self, _v: i16) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_i32(self, _v: i32) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_i64(self, _v: i64) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_u8(self, _v: u8) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_u16(self, _v: u16) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_u32(self, _v: u32) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_u64(self, _v: u64) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_f32(self, _v: f32) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_f64(self, _v: f64) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_char(self, v: char) -> Result<()> {
self.serialize_str(&v.to_string())
}
fn serialize_str(self, v: &str) -> Result<()> {
Ok(self.key = v.into())
}
fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_none(self) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<()> {
value.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_unit_variant(self, _name: &'static str, _variant_index: u32, variant: &'static str) -> Result<()> {
self.serialize_str(variant)
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(self, _name: &'static str, value: &T) -> Result<()> {
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T) -> Result<()> {
Err(Error::NonStringKey)
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
Err(Error::NonStringKey)
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeTupleStruct> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize) -> Result<Self::SerializeTupleVariant> {
Err(Error::NonStringKey)
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
Err(Error::NonStringKey)
}
fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
self.serialize_map(Some(len))
}
fn serialize_struct_variant(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize) -> Result<Self::SerializeStructVariant> {
Err(Error::NonStringKey)
}
}
impl<'a, W: Write> ser::Serializer for &'a 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 = MapSerializer<'a, W>;
type SerializeStruct = MapSerializer<'a, W>;
type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
fn serialize_bool(self, _v: bool) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_i8(self, _v: i8) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_i16(self, _v: i16) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_i32(self, _v: i32) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_i64(self, _v: i64) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_u8(self, _v: u8) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_u16(self, _v: u16) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_u32(self, _v: u32) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_u64(self, _v: u64) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_f32(self, _v: f32) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_f64(self, _v: f64) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_char(self, _v: char) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_str(self, _v: &str) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_bytes(self, _v: &[u8]) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_none(self) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<()> {
value.serialize(self)
}
fn serialize_unit(self) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_unit_variant(self, _name: &'static str, _variant_index: u32, variant: &'static str) -> Result<()> {
self.serialize_str(variant)
}
fn serialize_newtype_struct<T: ?Sized + Serialize>(self, _name: &'static str, value: &T) -> Result<()> {
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized + Serialize>(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _value: &T) -> Result<()> {
Err(Error::TopLevelMap)
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
Err(Error::TopLevelMap)
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeTupleStruct> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize) -> Result<Self::SerializeTupleVariant> {
Err(Error::TopLevelMap)
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
Ok(MapSerializer {
writer: &mut self.writer,
key: None,
top_level: true,
allow_values: true,
})
}
fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
self.serialize_map(Some(len))
}
fn serialize_struct_variant(self, _name: &'static str, _variant_index: u32, _variant: &'static str, _len: usize) -> Result<Self::SerializeStructVariant> {
Err(Error::TopLevelMap)
}
}
impl<'a, W: Write> ser::SerializeMap for MapSerializer<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<()> {
let mut k = KeySerializer::default();
key.serialize(&mut k)?;
self.key = Some(k.key);
Ok(())
}
fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
let writer = &mut self.writer;
let allow_values = &mut self.allow_values;
let top_level = self.top_level;
self.key.as_ref().ok_or_else(|| Error::MapKeyMissing).and_then(move |key| value.serialize(ValueSerializer {
writer: writer,
key: key,
top_level: top_level,
allow_values: allow_values,
}))
}
fn end(self) -> Result<()> {
Ok(())
}
}
impl<'a, W: Write> ser::SerializeStruct for MapSerializer<'a, W> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, key: &'static str, value: &T) -> Result<()> {
value.serialize(ValueSerializer {
writer: &mut self.writer,
key: key,
top_level: self.top_level,
allow_values: &mut self.allow_values,
})
}
fn end(self) -> Result<()> {
Ok(())
}
}
pub fn to_writer<W: Write, T: Serialize + ?Sized>(writer: W, value: &T) -> Result<()> {
let mut ser = Serializer::new(Writer::new(writer, Default::default()));
value.serialize(&mut ser)
}
pub fn to_vec<T: Serialize + ?Sized>(value: &T) -> Result<Vec<u8>> {
let mut writer = Vec::with_capacity(128);
to_writer(&mut writer, value).map(|_| writer)
}
pub fn to_string<T: Serialize + ?Sized>(value: &T) -> Result<String> {
let vec = to_vec(value)?;
Ok(unsafe { String::from_utf8_unchecked(vec) })
}