use crate::ser::{Error, Escaped, Result};
use std::io::Write;
pub(super) trait WriteExt {
fn write_tag_name_unescaped(&mut self, tag_name: &[u8]) -> Result<()>;
fn write_tag_name_escaped(&mut self, tag_name: &[u8]) -> Result<()>;
fn write_parameter_unescaped(&mut self, parameter: &[u8]) -> Result<()>;
fn write_parameter_escaped(&mut self, parameter: &[u8]) -> Result<()>;
fn write_key_unescaped(&mut self, value: &[u8]) -> Result<()>;
fn write_key_escaped(&mut self, value: &[u8]) -> Result<()>;
fn close_tag(&mut self) -> Result<()>;
}
impl<W> WriteExt for W
where
W: Write,
{
fn write_tag_name_unescaped(&mut self, tag_name: &[u8]) -> Result<()> {
self.write_all(b"#").or(Err(Error::Io))?;
self.write_all(tag_name).or(Err(Error::Io))
}
fn write_tag_name_escaped(&mut self, tag_name: &[u8]) -> Result<()> {
self.write_tag_name_unescaped(&Escaped::new(tag_name).collect::<Vec<_>>())
}
fn write_parameter_unescaped(&mut self, parameter: &[u8]) -> Result<()> {
self.write_all(b":").or(Err(Error::Io))?;
self.write_all(parameter).or(Err(Error::Io))
}
fn write_parameter_escaped(&mut self, parameter: &[u8]) -> Result<()> {
self.write_parameter_unescaped(&Escaped::new(parameter).collect::<Vec<_>>())
}
fn write_key_unescaped(&mut self, value: &[u8]) -> Result<()> {
self.write_all(b" ").or(Err(Error::Io))?;
self.write_all(value).or(Err(Error::Io))
}
fn write_key_escaped(&mut self, value: &[u8]) -> Result<()> {
self.write_key_unescaped(&Escaped::new(value).collect::<Vec<_>>())
}
fn close_tag(&mut self) -> Result<()> {
self.write_all(b";\n").or(Err(Error::Io))
}
}
#[cfg(test)]
mod tests {
use super::WriteExt;
use claims::{assert_err, assert_ok};
use std::{io, io::Write};
#[test]
fn write_tag_name_unescaped_regular() {
let mut output = Vec::new();
assert_ok!(output.write_tag_name_unescaped(b"foo"));
assert_eq!(output, b"#foo");
}
#[test]
fn write_tag_name_unescaped_escapes() {
let mut output = Vec::new();
assert_ok!(output.write_tag_name_unescaped(b"fo#o"));
assert_eq!(output, b"#fo#o");
}
#[test]
fn write_tag_name_escaped_regular() {
let mut output = Vec::new();
assert_ok!(output.write_tag_name_escaped(b"foo"));
assert_eq!(output, b"#foo");
}
#[test]
fn write_tag_name_escaped_escapes() {
let mut output = Vec::new();
assert_ok!(output.write_tag_name_escaped(b"fo#o"));
assert_eq!(output, b"#fo\\#o");
}
#[test]
fn write_parameter_unescaped_regular() {
let mut output = Vec::new();
assert_ok!(output.write_parameter_unescaped(b"foo"));
assert_eq!(output, b":foo");
}
#[test]
fn write_parameter_unescaped_escapes() {
let mut output = Vec::new();
assert_ok!(output.write_parameter_unescaped(b"fo#o"));
assert_eq!(output, b":fo#o");
}
#[test]
fn write_parameter_escaped_regular() {
let mut output = Vec::new();
assert_ok!(output.write_parameter_escaped(b"foo"));
assert_eq!(output, b":foo");
}
#[test]
fn write_parameter_escaped_escapes() {
let mut output = Vec::new();
assert_ok!(output.write_parameter_escaped(b"fo#o"));
assert_eq!(output, b":fo\\#o");
}
#[test]
fn write_key_unescaped_escapes() {
let mut output = Vec::new();
assert_ok!(output.write_key_unescaped(b"fo#o"));
assert_eq!(output, b" fo#o");
}
#[test]
fn write_key_escaped_regular() {
let mut output = Vec::new();
assert_ok!(output.write_key_escaped(b"foo"));
assert_eq!(output, b" foo");
}
#[test]
fn write_key_escaped_escapes() {
let mut output = Vec::new();
assert_ok!(output.write_key_escaped(b"fo#o"));
assert_eq!(output, b" fo\\#o");
}
#[test]
fn close_tag() {
let mut output = Vec::new();
assert_ok!(output.close_tag());
assert_eq!(output, b";\n");
}
struct FailingWriter;
impl Write for FailingWriter {
fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
Err(io::Error::new(io::ErrorKind::Other, "failed"))
}
fn flush(&mut self) -> io::Result<()> {
Err(io::Error::new(io::ErrorKind::Other, "failed"))
}
}
#[test]
fn write_tag_name_unescaped_failure() {
let mut output = FailingWriter;
assert_err!(output.write_tag_name_unescaped(b"foo"));
}
#[test]
fn write_tag_name_escaped_failure() {
let mut output = FailingWriter;
assert_err!(output.write_tag_name_escaped(b"foo"));
}
#[test]
fn write_parameter_unescaped_failure() {
let mut output = FailingWriter;
assert_err!(output.write_parameter_unescaped(b"foo"));
}
#[test]
fn write_parameter_escaped_failure() {
let mut output = FailingWriter;
assert_err!(output.write_parameter_unescaped(b"foo"));
}
#[test]
fn write_key_unescaped_failure() {
let mut output = FailingWriter;
assert_err!(output.write_key_unescaped(b"foo"));
}
#[test]
fn write_key_escaped_failure() {
let mut output = FailingWriter;
assert_err!(output.write_key_escaped(b"foo"));
}
#[test]
fn close_tag_failure() {
let mut output = FailingWriter;
assert_err!(output.close_tag());
}
}