use core::fmt::Write as _; use toml_writer::TomlWrite as _; use super::array_of_tables::ArrayOfTablesSerializer; use super::style::Style; use super::value::KeySerializer; use super::value::ValueSerializer; use super::Buffer; use super::Error; use super::SerializationStrategy; use super::Serializer; use super::Table; use crate::alloc_prelude::*; #[doc(hidden)] pub struct SerializeDocumentTable<'d> { buf: &'d mut Buffer, table: Table, key: Option, style: Style, } impl<'d> SerializeDocumentTable<'d> { pub(crate) fn map(buf: &'d mut Buffer, table: Table, style: Style) -> Result { Ok(Self { buf, table, key: None, style, }) } fn end(self) -> Result<&'d mut Buffer, Error> { self.buf.push(self.table); Ok(self.buf) } } impl<'d> serde_core::ser::SerializeMap for SerializeDocumentTable<'d> { type Ok = &'d mut Buffer; type Error = Error; fn serialize_key(&mut self, input: &T) -> Result<(), Self::Error> where T: serde_core::ser::Serialize + ?Sized, { let mut encoded_key = String::new(); input.serialize(KeySerializer { dst: &mut encoded_key, })?; self.key = Some(encoded_key); Ok(()) } fn serialize_value(&mut self, value: &T) -> Result<(), Self::Error> where T: serde_core::ser::Serialize + ?Sized, { let encoded_key = self .key .take() .expect("always called after `serialize_key`"); match SerializationStrategy::from(value) { SerializationStrategy::Value => { let dst = self.table.body_mut(); write!(dst, "{encoded_key}")?; dst.space()?; dst.keyval_sep()?; dst.space()?; let value_serializer = ValueSerializer::with_style(dst, self.style); let dst = value.serialize(value_serializer)?; dst.newline()?; } SerializationStrategy::ArrayOfTables => { self.table.has_children(true); let value_serializer = ArrayOfTablesSerializer::new( self.buf, self.table.clone(), encoded_key, self.style, ); value.serialize(value_serializer)?; } SerializationStrategy::Table | SerializationStrategy::Unknown => { let child = self.buf.child_table(&mut self.table, encoded_key); let value_serializer = Serializer::with_table(self.buf, child, self.style); value.serialize(value_serializer)?; } SerializationStrategy::Skip => { // silently drop these key-value pairs } } Ok(()) } fn end(self) -> Result { self.end() } } impl<'d> serde_core::ser::SerializeStruct for SerializeDocumentTable<'d> { type Ok = &'d mut Buffer; type Error = Error; fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: serde_core::ser::Serialize + ?Sized, { match SerializationStrategy::from(value) { SerializationStrategy::Value => { let dst = self.table.body_mut(); dst.key(key)?; dst.space()?; dst.keyval_sep()?; dst.space()?; let value_serializer = ValueSerializer::with_style(dst, self.style); let dst = value.serialize(value_serializer)?; dst.newline()?; } SerializationStrategy::ArrayOfTables => { self.table.has_children(true); let value_serializer = ArrayOfTablesSerializer::new( self.buf, self.table.clone(), key.to_owned(), self.style, ); value.serialize(value_serializer)?; } SerializationStrategy::Table | SerializationStrategy::Unknown => { let child = self.buf.child_table(&mut self.table, key.to_owned()); let value_serializer = Serializer::with_table(self.buf, child, self.style); value.serialize(value_serializer)?; } SerializationStrategy::Skip => { // silently drop these key-value pairs } } Ok(()) } fn end(self) -> Result { self.end() } } impl<'d> serde_core::ser::SerializeStructVariant for SerializeDocumentTable<'d> { type Ok = &'d mut Buffer; type Error = Error; #[inline] fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: serde_core::ser::Serialize + ?Sized, { serde_core::ser::SerializeStruct::serialize_field(self, key, value) } #[inline] fn end(self) -> Result { self.end() } }