#[cfg(feature = "alloc")] use alloc::borrow::Cow; #[cfg(feature = "alloc")] use alloc::string::String; #[cfg(feature = "alloc")] use alloc::vec::Vec; use crate::TomlWrite; use crate::WriteTomlKey; #[cfg(feature = "alloc")] pub trait ToTomlValue { fn to_toml_value(&self) -> String; } #[cfg(feature = "alloc")] impl ToTomlValue for T where T: WriteTomlValue + ?Sized, { fn to_toml_value(&self) -> String { let mut result = String::new(); let _ = self.write_toml_value(&mut result); result } } pub trait WriteTomlValue { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result; } impl WriteTomlValue for bool { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write!(writer, "{self}") } } impl WriteTomlValue for u8 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write!(writer, "{self}") } } impl WriteTomlValue for i8 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write!(writer, "{self}") } } impl WriteTomlValue for u16 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write!(writer, "{self}") } } impl WriteTomlValue for i16 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write!(writer, "{self}") } } impl WriteTomlValue for u32 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write!(writer, "{self}") } } impl WriteTomlValue for i32 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write!(writer, "{self}") } } impl WriteTomlValue for u64 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write!(writer, "{self}") } } impl WriteTomlValue for i64 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write!(writer, "{self}") } } impl WriteTomlValue for u128 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write!(writer, "{self}") } } impl WriteTomlValue for i128 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write!(writer, "{self}") } } impl WriteTomlValue for f32 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { match (self.is_sign_negative(), self.is_nan(), *self == 0.0) { (true, true, _) => write!(writer, "-nan"), (false, true, _) => write!(writer, "nan"), (true, false, true) => write!(writer, "-0.0"), (false, false, true) => write!(writer, "0.0"), (_, false, false) => { if self % 1.0 == 0.0 { write!(writer, "{self}.0") } else { write!(writer, "{self}") } } } } } impl WriteTomlValue for f64 { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { match (self.is_sign_negative(), self.is_nan(), *self == 0.0) { (true, true, _) => write!(writer, "-nan"), (false, true, _) => write!(writer, "nan"), (true, false, true) => write!(writer, "-0.0"), (false, false, true) => write!(writer, "0.0"), (_, false, false) => { if self % 1.0 == 0.0 { write!(writer, "{self}.0") } else { write!(writer, "{self}") } } } } } impl WriteTomlValue for char { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { let mut buf = [0; 4]; let v = self.encode_utf8(&mut buf); v.write_toml_value(writer) } } impl WriteTomlValue for str { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { crate::TomlStringBuilder::new(self) .as_default() .write_toml_value(writer) } } #[cfg(feature = "alloc")] impl WriteTomlValue for String { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { self.as_str().write_toml_value(writer) } } #[cfg(feature = "alloc")] impl WriteTomlValue for Cow<'_, str> { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { self.as_ref().write_toml_value(writer) } } impl WriteTomlValue for [V] { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { writer.open_array()?; let mut iter = self.iter(); if let Some(v) = iter.next() { writer.value(v)?; } for v in iter { writer.val_sep()?; writer.space()?; writer.value(v)?; } writer.close_array()?; Ok(()) } } impl WriteTomlValue for [V; N] { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { self.as_slice().write_toml_value(writer) } } #[cfg(feature = "alloc")] impl WriteTomlValue for Vec { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { self.as_slice().write_toml_value(writer) } } #[cfg(feature = "alloc")] impl WriteTomlValue for alloc::collections::BTreeMap { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write_toml_inline_table(self.iter(), writer) } } #[cfg(feature = "std")] impl WriteTomlValue for std::collections::HashMap { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { write_toml_inline_table(self.iter(), writer) } } fn write_toml_inline_table< 'i, I: Iterator, K: WriteTomlKey + 'i, V: WriteTomlValue + 'i, W: TomlWrite + ?Sized, >( mut iter: I, writer: &mut W, ) -> core::fmt::Result { writer.open_inline_table()?; let mut trailing_space = false; if let Some((key, value)) = iter.next() { writer.space()?; writer.key(key)?; writer.space()?; writer.keyval_sep()?; writer.space()?; writer.value(value)?; trailing_space = true; } for (key, value) in iter { writer.val_sep()?; writer.space()?; writer.key(key)?; writer.space()?; writer.keyval_sep()?; writer.space()?; writer.value(value)?; } if trailing_space { writer.space()?; } writer.close_inline_table()?; Ok(()) } impl WriteTomlValue for &V { fn write_toml_value(&self, writer: &mut W) -> core::fmt::Result { (*self).write_toml_value(writer) } }