use alloc::{borrow::Cow, string::ToString};
use core::{fmt::Write, ops::Deref};
use crate::{Serialize, SerializeOptions, XmlWriter};
#[derive(Default, Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Text<'s>(Cow<'s, str>);
impl<'s> Text<'s> {
pub fn to_owned(&self) -> Text<'static> {
self.clone().into_owned()
}
pub fn as_str(&self) -> &str {
&*self.0
}
pub fn set(&mut self, text: impl Into<Cow<'s, str>>) {
self.0 = text.into();
}
pub fn into_owned(self) -> Text<'static> {
Text(match self.0 {
Cow::Borrowed(b) => Cow::Owned(b.to_string()),
Cow::Owned(b) => Cow::Owned(b)
})
}
}
impl Deref for Text<'_> {
type Target = str;
fn deref(&self) -> &Self::Target {
&*self.0
}
}
impl<'s, T: Into<Cow<'s, str>>> From<T> for Text<'s> {
fn from(value: T) -> Self {
Self(value.into())
}
}
impl Serialize for Text<'_> {
fn serialize_xml<W: Write>(&self, writer: &mut XmlWriter<W>, _: &SerializeOptions) -> crate::Result<()> {
writer.text(&self.0)
}
}
pub fn text<'s>(s: impl Into<Cow<'s, str>>) -> Text<'s> {
Text(s.into())
}
#[cfg(test)]
mod tests {
use super::text;
use crate::{Serialize, SerializeOptions};
#[test]
fn text_escapes() -> crate::Result<()> {
assert_eq!(text("One & two").serialize_to_string(&SerializeOptions::default())?, "One & two");
Ok(())
}
}