pub mod svg;
use svg::*;
#[macro_export]
macro_rules! wr {
($($arg:tt)*) => {
move |w|write!(w,$($arg)*)
}
}
pub fn write_fmt_ret<'a, T: fmt::Write>(
w: &'a mut T,
args: fmt::Arguments,
) -> Result<&'a mut T, fmt::Error> {
w.write_fmt(args)?;
Ok(w)
}
#[macro_export]
macro_rules! write_ret {
($dst:expr, $($arg:tt)*) => ($crate::write_fmt_ret($dst,format_args!($($arg)*)))
}
pub mod prelude {
pub use super::wr;
pub use super::write_ret;
pub use super::WriteAttr;
pub use core::fmt::Write;
}
use core::fmt;
use fmt::Write;
pub struct WriterAdaptor<T> {
pub inner: T,
pub error: Result<(), std::io::Error>,
}
pub fn upgrade<T: std::io::Write>(inner: T) -> WriterAdaptor<T> {
WriterAdaptor {
inner,
error: Ok(()),
}
}
impl<T: std::io::Write> fmt::Write for WriterAdaptor<T> {
fn write_str(&mut self, s: &str) -> fmt::Result {
match self.inner.write_all(s.as_bytes()) {
Ok(()) => Ok(()),
Err(e) => {
self.error = Err(e);
Err(fmt::Error)
}
}
}
}
pub mod tag_types {
pub static NORMAL: [&str; 2] = ["<", "/>"];
pub static COMMENT: [&str; 2] = ["<!--", "-->"];
pub static PROLOG: [&str; 2] = ["<?", "?>"];
pub static DECL: [&str; 2] = ["<!", ">"];
}
pub struct ElementHeaderWriter<'a, T>(&'a mut Element<T>);
impl<'a, T: Write> ElementHeaderWriter<'a, T> {
pub fn write<F, J>(self, func: F) -> Result<(&'a mut Element<T>, J), fmt::Error>
where
for<'x, 'y> F: FnOnce(
&'x mut AttributeWriter<'y, T>,
) -> Result<(&'x mut AttributeWriter<'y, T>, J), fmt::Error>,
{
let (_res, j) = func(&mut AttributeWriter { inner: self.0 })?;
write!(self.0, ">")?;
Ok((self.0, j))
}
}
pub trait WriteAttr: Write + Sized {
fn points_data<F>(&mut self, func: F) -> Result<&mut Self, fmt::Error>
where
for<'x, 'y> F: FnOnce(
&'x mut PointsBuilder<'y, Self>,
) -> Result<&'x mut PointsBuilder<'y, Self>, fmt::Error>,
{
{
let mut p = PointsBuilder::new(self)?;
func(&mut p)?;
p.finish()?;
}
Ok(self)
}
fn path_data<F>(&mut self, func: F) -> Result<&mut Self, fmt::Error>
where
for<'x, 'y> F: FnOnce(
&'x mut PathBuilder<'y, Self>,
) -> Result<&'x mut PathBuilder<'y, Self>, fmt::Error>,
{
{
let mut p = PathBuilder::new(self)?;
func(&mut p)?;
p.finish()?;
}
Ok(self)
}
fn with_attr(
&mut self,
s: &str,
func: impl FnOnce(&mut Self) -> core::fmt::Result,
) -> Result<&mut Self, core::fmt::Error> {
write!(self, " {}=", s)?;
write!(self, "\"")?;
func(self)?;
write!(self, "\"")?;
Ok(self)
}
fn attr(
&mut self,
s: &str,
val: impl core::fmt::Display,
) -> Result<&mut Self, core::fmt::Error> {
write!(self, " {}=\"{}\"", s, val)?;
Ok(self)
}
}
pub struct AttributeWriter<'a, T> {
inner: &'a mut Element<T>,
}
impl<'a, T: fmt::Write> AttributeWriter<'a, T> {
pub fn empty_ok(&mut self) -> Result<(&mut AttributeWriter<'a, T>, ()), fmt::Error> {
Ok((self, ()))
}
}
impl<'a, T: fmt::Write> fmt::Write for AttributeWriter<'a, T> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.inner.write_str(s)
}
}
impl<'a, T: fmt::Write> WriteAttr for AttributeWriter<'a, T> {}
pub struct ElementStack<'a, T> {
writer: Element<T>,
tags: Vec<&'a str>,
}
impl<'a, T: fmt::Write> ElementStack<'a, T> {
pub fn check_unwound(&mut self) {
if !self.tags.is_empty() {
panic!("not all ending tags have been popped.")
}
}
pub fn new(writer: T) -> ElementStack<'a, T> {
ElementStack {
writer: Element::new(writer),
tags: Vec::new(),
}
}
pub fn from_element(writer: Element<T>) -> ElementStack<'a, T> {
ElementStack {
writer,
tags: Vec::new(),
}
}
pub fn elem_stack<F, J>(&mut self, tag: &'a str, func: F) -> Result<J, fmt::Error>
where
for<'x, 'y> F: FnOnce(
&'x mut AttributeWriter<'y, T>,
) -> Result<(&'x mut AttributeWriter<'y, T>, J), fmt::Error>,
{
write!(self.writer, "<{}", tag)?;
let mut attr = AttributeWriter {
inner: &mut self.writer,
};
let (_cert, j) = func(&mut attr)?;
write!(self.writer, ">")?;
self.tags.push(tag);
Ok(j)
}
pub fn as_element(&mut self) -> &mut Element<T> {
&mut self.writer
}
pub fn pop(&mut self) -> Result<&mut ElementStack<'a, T>, fmt::Error> {
let tag = self.tags.pop().expect("pop called too many times");
write!(self.writer, "</{}>", tag)?;
Ok(self)
}
}
impl<'a, T> core::ops::Deref for ElementStack<'a, T> {
type Target = Element<T>;
fn deref(&self) -> &Self::Target {
&self.writer
}
}
impl<'a, T> core::ops::DerefMut for ElementStack<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.writer
}
}
pub struct Element<T> {
writer: T,
}
impl<T: fmt::Write> fmt::Write for Element<T> {
fn write_str(&mut self, s: &str) -> fmt::Result {
self.writer.write_str(s)
}
}
impl<T: fmt::Write> Element<T> {
pub fn new(writer: T) -> Self {
Element { writer }
}
pub fn into_writer(self) -> T {
self.writer
}
pub fn get_writer(&mut self) -> &mut T {
&mut self.writer
}
pub fn empty_ok(&mut self) -> Result<(&mut Element<T>, ()), fmt::Error> {
Ok((self, ()))
}
pub fn single_ext<F, J>(&mut self, tag: &str, tags: [&str; 2], func: F) -> Result<J, fmt::Error>
where
for<'x, 'y> F: FnOnce(
&'x mut AttributeWriter<'y, T>,
) -> Result<(&'x mut AttributeWriter<'y, T>, J), fmt::Error>,
{
let [start, end] = tags;
write!(self.writer, "{}{}", start, tag)?;
let (_, j) = func(&mut AttributeWriter { inner: self })?;
write!(self.writer, "{}", end)?;
Ok(j)
}
pub fn single<F, J>(&mut self, tag: &str, func: F) -> Result<J, fmt::Error>
where
for<'x, 'y> F: FnOnce(
&'x mut AttributeWriter<'y, T>,
) -> Result<(&'x mut AttributeWriter<'y, T>, J), fmt::Error>,
{
let j = self.single_ext(tag, ["<", "/>"], func)?;
Ok(j)
}
pub fn elem_no_attr<F, J>(&mut self, tag: &str, func: F) -> Result<(&mut Self, J), fmt::Error>
where
for<'x> F: FnOnce(&'x mut Element<T>) -> Result<(&'x mut Element<T>, J), fmt::Error>,
{
write!(self.writer, "<{}>", tag)?;
let (_, j) = func(self)?;
write!(self.writer, "</{}>", tag)?;
Ok((self, j))
}
pub fn elem<J, F>(&mut self, tag: &str, func: F) -> Result<J, fmt::Error>
where
F: FnOnce(ElementHeaderWriter<T>) -> Result<(&mut Element<T>, J), fmt::Error>,
{
write!(self.writer, "<{}", tag)?;
let attr = ElementHeaderWriter(self);
let (_cert, j) = func(attr)?;
write!(self.writer, "</{}>", tag)?;
Ok(j)
}
}