rtimelog 1.1.1

System for tracking time in a text-log-based format.
Documentation
//! Macro simplification for emitting XML.

#[allow(unused_imports)]
use xml::writer::XmlEvent;

/// Write [`XmlEvent`]s to the supplied writer.
///
/// The first argument to the macro is always the writer object.
/// When writing elements, the second argument is the tag name, followed by an
/// optional list of `attr: "value"` pairs, separated by commas.
///
/// If the content of the element is just text, the above will be followed by a `;`
/// and an expression giving the text.
///
/// If the content is more XML, the start definition will be followed by `=>` and
/// a block. The block contains further XML writing code must return a [`Result`];
///
/// If you want to just send text to the XML, the only thing following the writer
/// should be a `;` and and expression giving the text.
///
/// ## Examples
///
/// ```rust, no_run
/// # use std::fs::File;
/// use xml::writer::{EmitterConfig, XmlEvent};
/// use timelog::emit_xml;
/// use timelog::Result;
///
/// # fn main() -> Result<()> {
/// let mut file = File::create("output.html").expect("Can't open file");
/// let mut w = EmitterConfig::new()
///     .perform_indent(true)
///     .write_document_declaration(false)
///     .create_writer(&mut file);
///
///     emit_xml!(w, html => {
///         emit_xml!(w, head => {
///             emit_xml!(w, title; "This is the page")
///         })?;
///         emit_xml!(w, body => {
///             emit_xml!(w, div, class: "group" => {
///                 emit_xml!(w, h1; &format!("Page for {}", "me"))?;
///                 emit_xml!(w, p, class: "stuff"; "Useless text")?;
///                 emit_xml!(w, br)
///             })?;
///             emit_xml!(w, p => {
///                 emit_xml!(w; "This is some random text.")?;
///                 emit_xml!(w, em; "That is part of more formatted text.")
///             })
///         })
///     })?;
///
/// # Ok(())
/// # }
/// ```
#[macro_export]
macro_rules! emit_xml {
    ($target:expr; $text:expr) => {
        {
            $target.write(XmlEvent::from(XmlEvent::characters($text)))?;
            $crate::Result::Ok(())
        }
    };
    ($target:expr, $tag:ident; $text:expr) => {
        {
            $target.write(XmlEvent::from(XmlEvent::start_element(stringify!($tag))))?;
            $target.write(XmlEvent::from(XmlEvent::characters($text)))?;
            $target.write(XmlEvent::from(XmlEvent::end_element().name(stringify!($tag))))?;
            $crate::Result::Ok(())
        }
    };
    ($target:expr, $tag:ident, $($attr:ident: $val:expr),+; $text:expr) => {
        {
            $target.write(XmlEvent::from(XmlEvent::start_element(stringify!($tag))
                $(
                    .attr(stringify!($attr), $val)
                )+
            ))?;
            $target.write(XmlEvent::from(XmlEvent::characters($text)))?;
            $target.write(XmlEvent::from(XmlEvent::end_element().name(stringify!($tag))))?;
            $crate::Result::Ok(())
        }
    };
    ($target:expr, $tag:ident => $block:block) => {
        {
            $target.write(XmlEvent::from(XmlEvent::start_element(stringify!($tag))))?;
            $block?;
            $target.write(XmlEvent::from(XmlEvent::end_element().name(stringify!($tag))))?;
            $crate::Result::Ok(())
        }
    };
    ($target:expr, $tag:ident, $($attr:ident: $val:expr),+ => $block:block) => {
        {
            $target.write(XmlEvent::from(XmlEvent::start_element(stringify!($tag))
                $(
                    .attr(stringify!($attr), $val)
                )+
            ))?;
            let result: $crate::Result<()> = $block;
            result?;
            $target.write(XmlEvent::from(XmlEvent::end_element().name(stringify!($tag))))?;
            $crate::Result::Ok(())
        }
    };
    ($target:expr, $tag:ident) => {
        {
            $target.write(XmlEvent::from(XmlEvent::start_element(stringify!($tag))))?;
            $target.write(XmlEvent::from(XmlEvent::end_element().name(stringify!($tag))))?;
            $crate::Result::Ok(())
        }
    };
    ($target:expr, $tag:ident, $($attr:ident: $val:expr),+) => {
        {
            $target.write(XmlEvent::from(XmlEvent::start_element(stringify!($tag))
                $(
                    .attr(stringify!($attr), $val)
                )+
            ))?;
            $target.write(XmlEvent::from(XmlEvent::end_element().name(stringify!($tag))))?;
            $crate::Result::Ok(())
        }
    };
}