use std::io::Write;
use crate::xdoc::error::Result;
#[derive(Debug, Clone, Eq, PartialOrd, PartialEq, Hash)]
pub enum Newline {
None,
Newline,
Windows,
}
impl Default for Newline {
fn default() -> Self {
Newline::Newline
}
}
#[derive(Debug, Clone, Eq, PartialOrd, PartialEq, Hash)]
pub enum Indent {
None,
Spaces(usize),
Tab,
}
impl Default for Indent {
fn default() -> Self {
Indent::Spaces(2)
}
}
#[derive(Debug, Clone, Eq, PartialOrd, PartialEq, Hash, Default)]
pub struct WriteOpts {
pub indent: Indent,
pub newline: Newline,
}
impl WriteOpts {
fn newline_str(&self) -> &'static str {
match self.newline {
Newline::None => "",
Newline::Newline => "\n",
Newline::Windows => "\n\r",
}
}
fn write_repeatedly<W>(writer: &mut W, num: usize, s: &str) -> Result<()>
where
W: Write,
{
let s = std::iter::repeat(s).take(num).collect::<String>();
xwrite!(writer, "{}", s)?;
Ok(())
}
pub(crate) fn indent<W>(&self, writer: &mut W, depth: usize) -> Result<()>
where
W: Write,
{
match self.indent {
Indent::None => {
return Ok(());
}
Indent::Spaces(n) => {
Self::write_repeatedly(writer, depth * n, " ")?;
}
Indent::Tab => {
Self::write_repeatedly(writer, depth, "\t")?;
}
}
Ok(())
}
pub(crate) fn newline<W>(&self, writer: &mut W) -> Result<()>
where
W: Write,
{
xwrite!(writer, "{}", self.newline_str())?;
Ok(())
}
}
pub(crate) fn write_attribute_value<W, S>(s: S, writer: &mut W, _opts: &WriteOpts) -> Result<()>
where
W: Write,
S: AsRef<str>,
{
for c in s.as_ref().chars() {
match c {
'<' => better_wrap!(write!(writer, "<"))?,
'>' => better_wrap!(write!(writer, ">"))?,
'&' => better_wrap!(write!(writer, "&"))?,
'"' => better_wrap!(write!(writer, """))?,
_ => better_wrap!(write!(writer, "{}", c))?,
}
}
Ok(())
}
pub(crate) fn write_element_text<W, S>(
s: S,
writer: &mut W,
_opts: &WriteOpts,
_depth: usize,
) -> Result<()>
where
W: Write,
S: AsRef<str>,
{
for c in s.as_ref().chars() {
match c {
'<' => better_wrap!(write!(writer, "<"))?,
'>' => better_wrap!(write!(writer, ">"))?,
'&' => better_wrap!(write!(writer, "&"))?,
'\u{a0}' => better_wrap!(write!(writer, " "))?,
_ => better_wrap!(write!(writer, "{}", c))?,
}
}
Ok(())
}