summaryrefslogtreecommitdiffstats
path: root/third_party/rust/xml-rs/src/writer/events.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/xml-rs/src/writer/events.rs')
-rw-r--r--third_party/rust/xml-rs/src/writer/events.rs241
1 files changed, 241 insertions, 0 deletions
diff --git a/third_party/rust/xml-rs/src/writer/events.rs b/third_party/rust/xml-rs/src/writer/events.rs
new file mode 100644
index 0000000000..1f7040f66a
--- /dev/null
+++ b/third_party/rust/xml-rs/src/writer/events.rs
@@ -0,0 +1,241 @@
+//! Contains `XmlEvent` datatype, instances of which are consumed by the writer.
+
+use std::borrow::Cow;
+
+use name::Name;
+use attribute::Attribute;
+use common::XmlVersion;
+use namespace::{Namespace, NS_NO_PREFIX};
+
+/// A part of an XML output stream.
+///
+/// Objects of this enum are consumed by `EventWriter`. They correspond to different parts of
+/// an XML document.
+#[derive(Debug)]
+pub enum XmlEvent<'a> {
+ /// Corresponds to XML document declaration.
+ ///
+ /// This event should always be written before any other event. If it is not written
+ /// at all, a default XML declaration will be outputted if the corresponding option
+ /// is set in the configuration. Otherwise an error will be returned.
+ StartDocument {
+ /// XML version.
+ ///
+ /// Defaults to `XmlVersion::Version10`.
+ version: XmlVersion,
+
+ /// XML document encoding.
+ ///
+ /// Defaults to `Some("UTF-8")`.
+ encoding: Option<&'a str>,
+
+ /// XML standalone declaration.
+ ///
+ /// Defaults to `None`.
+ standalone: Option<bool>
+ },
+
+ /// Denotes an XML processing instruction.
+ ProcessingInstruction {
+ /// Processing instruction target.
+ name: &'a str,
+
+ /// Processing instruction content.
+ data: Option<&'a str>
+ },
+
+ /// Denotes a beginning of an XML element.
+ StartElement {
+ /// Qualified name of the element.
+ name: Name<'a>,
+
+ /// A list of attributes associated with the element.
+ ///
+ /// Currently attributes are not checked for duplicates (TODO). Attribute values
+ /// will be escaped, and all characters invalid for attribute values like `"` or `<`
+ /// will be changed into character entities.
+ attributes: Cow<'a, [Attribute<'a>]>,
+
+ /// Contents of the namespace mapping at this point of the document.
+ ///
+ /// This mapping will be inspected for "new" entries, and if at this point of the document
+ /// a particular pair of prefix and namespace URI is already defined, no namespace
+ /// attributes will be emitted.
+ namespace: Cow<'a, Namespace>,
+ },
+
+ /// Denotes an end of an XML element.
+ EndElement {
+ /// Optional qualified name of the element.
+ ///
+ /// If `None`, then it is assumed that the element name should be the last valid one.
+ /// If `Some` and element names tracking is enabled, then the writer will check it for
+ /// correctness.
+ name: Option<Name<'a>>
+ },
+
+ /// Denotes CDATA content.
+ ///
+ /// This event contains unparsed data, and no escaping will be performed when writing it
+ /// to the output stream.
+ CData(&'a str),
+
+ /// Denotes a comment.
+ ///
+ /// The string will be checked for invalid sequences and error will be returned by the
+ /// write operation
+ Comment(&'a str),
+
+ /// Denotes character data outside of tags.
+ ///
+ /// Contents of this event will be escaped if `perform_escaping` option is enabled,
+ /// that is, every character invalid for PCDATA will appear as a character entity.
+ Characters(&'a str)
+}
+
+impl<'a> XmlEvent<'a> {
+ /// Returns an writer event for a processing instruction.
+ #[inline]
+ pub fn processing_instruction(name: &'a str, data: Option<&'a str>) -> XmlEvent<'a> {
+ XmlEvent::ProcessingInstruction { name: name, data: data }
+ }
+
+ /// Returns a builder for a starting element.
+ ///
+ /// This builder can then be used to tweak attributes and namespace starting at
+ /// this element.
+ #[inline]
+ pub fn start_element<S>(name: S) -> StartElementBuilder<'a> where S: Into<Name<'a>> {
+ StartElementBuilder {
+ name: name.into(),
+ attributes: Vec::new(),
+ namespace: Namespace::empty().into()
+ }
+ }
+
+ /// Returns a builder for an closing element.
+ ///
+ /// This method, unline `start_element()`, does not accept a name because by default
+ /// the writer is able to determine it automatically. However, when this functionality
+ /// is disabled, it is possible to specify the name with `name()` method on the builder.
+ #[inline]
+ pub fn end_element() -> EndElementBuilder<'a> {
+ EndElementBuilder { name: None }
+ }
+
+ /// Returns a CDATA event.
+ ///
+ /// Naturally, the provided string won't be escaped, except for closing CDATA token `]]>`
+ /// (depending on the configuration).
+ #[inline]
+ pub fn cdata(data: &'a str) -> XmlEvent<'a> { XmlEvent::CData(data) }
+
+ /// Returns a regular characters (PCDATA) event.
+ ///
+ /// All offending symbols, in particular, `&` and `<`, will be escaped by the writer.
+ #[inline]
+ pub fn characters(data: &'a str) -> XmlEvent<'a> { XmlEvent::Characters(data) }
+
+ /// Returns a comment event.
+ #[inline]
+ pub fn comment(data: &'a str) -> XmlEvent<'a> { XmlEvent::Comment(data) }
+}
+
+impl<'a> From<&'a str> for XmlEvent<'a> {
+ #[inline]
+ fn from(s: &'a str) -> XmlEvent<'a> { XmlEvent::Characters(s) }
+}
+
+pub struct EndElementBuilder<'a> {
+ name: Option<Name<'a>>
+}
+
+/// A builder for a closing element event.
+impl<'a> EndElementBuilder<'a> {
+ /// Sets the name of this closing element.
+ ///
+ /// Usually the writer is able to determine closing element names automatically. If
+ /// this functionality is enabled (by default it is), then this name is checked for correctness.
+ /// It is possible, however, to disable such behavior; then the user must ensure that
+ /// closing element name is correct manually.
+ #[inline]
+ pub fn name<N>(mut self, name: N) -> EndElementBuilder<'a> where N: Into<Name<'a>> {
+ self.name = Some(name.into());
+ self
+ }
+}
+
+impl<'a> From<EndElementBuilder<'a>> for XmlEvent<'a> {
+ fn from(b: EndElementBuilder<'a>) -> XmlEvent<'a> {
+ XmlEvent::EndElement { name: b.name }
+ }
+}
+
+/// A builder for a starting element event.
+pub struct StartElementBuilder<'a> {
+ name: Name<'a>,
+ attributes: Vec<Attribute<'a>>,
+ namespace: Namespace
+}
+
+impl<'a> StartElementBuilder<'a> {
+ /// Sets an attribute value of this element to the given string.
+ ///
+ /// This method can be used to add attributes to the starting element. Name is a qualified
+ /// name; its namespace is ignored, but its prefix is checked for correctness, that is,
+ /// it is checked that the prefix is bound to some namespace in the current context.
+ ///
+ /// Currently attributes are not checked for duplicates. Note that duplicate attributes
+ /// are a violation of XML document well-formedness.
+ ///
+ /// The writer checks that you don't specify reserved prefix names, for example `xmlns`.
+ #[inline]
+ pub fn attr<N>(mut self, name: N, value: &'a str) -> StartElementBuilder<'a>
+ where N: Into<Name<'a>>
+ {
+ self.attributes.push(Attribute::new(name.into(), value));
+ self
+ }
+
+ /// Adds a namespace to the current namespace context.
+ ///
+ /// If no namespace URI was bound to the provided prefix at this point of the document,
+ /// then the mapping from the prefix to the provided namespace URI will be written as
+ /// a part of this element attribute set.
+ ///
+ /// If the same namespace URI was bound to the provided prefix at this point of the document,
+ /// then no namespace attributes will be emitted.
+ ///
+ /// If some other namespace URI was bound to the provided prefix at this point of the document,
+ /// then another binding will be added as a part of this element attribute set, shadowing
+ /// the outer binding.
+ #[inline]
+ pub fn ns<S1, S2>(mut self, prefix: S1, uri: S2) -> StartElementBuilder<'a>
+ where S1: Into<String>, S2: Into<String>
+ {
+ self.namespace.put(prefix, uri);
+ self
+ }
+
+ /// Adds a default namespace mapping to the current namespace context.
+ ///
+ /// Same rules as for `ns()` are also valid for the default namespace mapping.
+ #[inline]
+ pub fn default_ns<S>(mut self, uri: S) -> StartElementBuilder<'a>
+ where S: Into<String>
+ {
+ self.namespace.put(NS_NO_PREFIX, uri);
+ self
+ }
+}
+
+impl<'a> From<StartElementBuilder<'a>> for XmlEvent<'a> {
+ #[inline]
+ fn from(b: StartElementBuilder<'a>) -> XmlEvent<'a> {
+ XmlEvent::StartElement {
+ name: b.name,
+ attributes: Cow::Owned(b.attributes),
+ namespace: Cow::Owned(b.namespace)
+ }
+ }
+}