use std::{ fmt::{self, Display, Formatter, Write}, io, }; use tokio::io::{AsyncWrite, AsyncWriteExt}; use super::{ AttDef, AttDefName, AttType, AttValue, AttValueData, AttlistDecl, Attribute, CDEnd, CDSect, CDStart, CData, Char, CharData, CharRef, Children, ChildrenKind, Choice, Comment, ConditionalSect, Content, ContentItem, Contentspec, Cp, CpKind, DeclSep, DefaultAttName, DefaultDecl, DoctypeDecl, Document, ETag, Element, Elementdecl, EmptyElemTag, EncName, EncodingDecl, EntityDecl, EntityDef, EntityRef, EntityValue, EntityValueData, EnumeratedType, Enumeration, Eq, ExtParsedEnt, ExtSubset, ExtSubsetDecl, ExtSubsetDeclaration, ExternalID, GEDecl, Ignore, IgnoreSect, IgnoreSectContents, IncludeSect, IntSubset, LocalPart, MarkupDecl, Misc, Mixed, NCName, NDataDecl, NSAttName, Name, NameChar, NameStartChar, Names, Nmtoken, Nmtokens, NotationDecl, NotationDeclID, NotationType, Occurence, PEDecl, PEDef, PEReference, PITarget, Prefix, PrefixedAttName, PrefixedName, Prolog, PubidChar, PubidLiteral, PublicID, QName, Reference, SDDecl, STag, Seq, StringType, SystemLiteral, TextDecl, TokenizedType, UnprefixedName, VersionInfo, VersionNum, XMLDecl, PI, S, }; /// Compact Composer trait, can create different trait later for pretty composition pub trait Composer<'s> { fn write(&self, writer: &mut W) -> impl std::future::Future> where W: Unpin + AsyncWrite; } // namespaces in xml /// [1] NSAttName ::= PrefixedAttName | DefaultAttName impl<'s> Composer<'s> for NSAttName<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: AsyncWrite + Unpin, { match self { NSAttName::PrefixedAttName(prefixed_att_name) => { prefixed_att_name.write(writer).await? } NSAttName::DefaultAttName => DefaultAttName.write(writer).await?, } Ok(()) } } /// [2] PrefixedAttName ::= 'xmlns:' NCName impl<'s> Composer<'s> for PrefixedAttName<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: AsyncWrite + Unpin, { writer.write_all("xmlns:".as_bytes()).await?; self.0.write(writer).await?; Ok(()) } } /// [3] DefaultAttName ::= 'xmlns'; impl Composer<'_> for DefaultAttName { async fn write(&self, writer: &mut W) -> io::Result<()> where W: AsyncWrite + Unpin, { writer.write_all("xmlns".as_bytes()).await?; Ok(()) } } /// [4] NCName ::= Name - (Char* ':' Char*) impl<'s> Composer<'s> for NCName<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: AsyncWrite + Unpin, { writer.write_all(self.0.as_bytes()).await?; Ok(()) } } /// [7] QName ::= PrefixedName | UnprefixedName impl<'s> Composer<'s> for QName<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: AsyncWrite + Unpin, { match self { QName::PrefixedName(prefixed_name) => prefixed_name.write(writer).await?, QName::UnprefixedName(unprefixed_name) => unprefixed_name.write(writer).await?, } Ok(()) } } /// [8] PrefixedName ::= Prefix ':' LocalPart impl<'s> Composer<'s> for PrefixedName<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: AsyncWrite + Unpin, { self.prefix.write(writer).await?; writer.write_all(":".as_bytes()).await?; self.local_part.write(writer).await?; Ok(()) } } /// [9] UnprefixedName ::= LocalPart impl<'s> Composer<'s> for UnprefixedName<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { self.0.write(writer).await?; Ok(()) } } /// [10] Prefix ::= NCName impl<'s> Composer<'s> for Prefix<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { self.0.write(writer).await?; Ok(()) } } /// [11] LocalPart ::= NCName impl<'s> Composer<'s> for LocalPart<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { self.0.write(writer).await?; Ok(()) } } // xml spec /// [1] document ::= prolog element Misc* impl<'s> Composer<'s> for Document<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { self.prolog.write(writer).await?; self.element.write(writer).await?; for misc in &self.miscs { misc.write(writer).await? } Ok(()) } } /// [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */ impl Composer<'_> for Char { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all(self.0.to_string().as_bytes()).await?; Ok(()) } } /// [3] S ::= (#x20 | #x9 | #xD | #xA)+ impl<'s> Composer<'s> for S { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("\u{20}".as_bytes()).await?; Ok(()) } } /// [4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] impl Composer<'_> for NameStartChar { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all(self.0.to_string().as_bytes()).await?; Ok(()) } } /// [4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] impl Composer<'_> for NameChar { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all(self.0.to_string().as_bytes()).await?; Ok(()) } } /// [5] Name ::= NameStartChar (NameChar)* impl<'s> Composer<'s> for Name<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all(self.0.as_bytes()).await?; Ok(()) } } /// [6] Names ::= Name (#x20 Name)* impl<'s> Composer<'s> for Names<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { let mut first = true; for name in &self.0 { if !first { writer.write_all("\u{20}".as_bytes()).await?; } name.write(writer).await?; if first { first = false } } Ok(()) } } /// [7] Nmtoken ::= (NameChar)+ impl<'s> Composer<'s> for Nmtoken<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all(self.0.as_bytes()).await?; Ok(()) } } /// [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)* impl<'s> Composer<'s> for Nmtokens<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { let mut first = true; for nmtoken in &self.0 { if !first { writer.write_all("\u{20}".as_bytes()).await?; } nmtoken.write(writer).await?; if first { first = false } } Ok(()) } } /// [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' /// | "'" ([^%&'] | PEReference | Reference)* "'" impl<'s> Composer<'s> for EntityValue<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { EntityValue::DoubleQuoted(entity_value_data) => { writer.write_all("\"".as_bytes()).await?; for entity_value_data in entity_value_data { match entity_value_data { EntityValueData::String(s) => writer.write_all(s.as_bytes()).await?, EntityValueData::PEReference(pe_reference) => { pe_reference.write(writer).await? } EntityValueData::Reference(reference) => reference.write(writer).await?, } } writer.write_all("\"".as_bytes()).await?; } EntityValue::SingleQuoted(entity_value_data) => { writer.write_all("'".as_bytes()).await?; for entity_value_data in entity_value_data { match entity_value_data { EntityValueData::String(s) => writer.write_all(s.as_bytes()).await?, EntityValueData::PEReference(pe_reference) => { pe_reference.write(writer).await? } EntityValueData::Reference(reference) => reference.write(writer).await?, } } writer.write_all("'".as_bytes()).await?; } } Ok(()) } } /// [10] AttValue ::= '"' ([^<&"] | Reference)* '"' /// | "'" ([^<&'] | Reference)* "'" impl<'s> Composer<'s> for AttValue<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { AttValue::DoubleQuoted(att_value_data) => { writer.write_all("\"".as_bytes()).await?; for att_value_data in att_value_data { match att_value_data { AttValueData::String(s) => writer.write_all(s.as_bytes()).await?, AttValueData::Reference(reference) => reference.write(writer).await?, } } writer.write_all("\"".as_bytes()).await?; } AttValue::SingleQuoted(att_value_data) => { writer.write_all("'".as_bytes()).await?; for att_value_data in att_value_data { match att_value_data { AttValueData::String(s) => writer.write_all(s.as_bytes()).await?, AttValueData::Reference(reference) => reference.write(writer).await?, } } writer.write_all("'".as_bytes()).await?; } } Ok(()) } } /// [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'") impl<'s> Composer<'s> for SystemLiteral<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { SystemLiteral::DoubleQuoted(s) => { writer.write_all("\"".as_bytes()).await?; writer.write_all(s.as_bytes()).await?; writer.write_all("\"".as_bytes()).await?; } SystemLiteral::SingleQuoted(s) => { writer.write_all("'".as_bytes()).await?; writer.write_all(s.as_bytes()).await?; writer.write_all("'".as_bytes()).await?; } } Ok(()) } } /// [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'" impl<'s> Composer<'s> for PubidLiteral<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { PubidLiteral::DoubleQuoted(s) => { writer.write_all("\"".as_bytes()).await?; writer.write_all(s.as_bytes()).await?; writer.write_all("\"".as_bytes()).await?; } PubidLiteral::SingleQuoted(s) => { writer.write_all("'".as_bytes()).await?; writer.write_all(s.as_bytes()).await?; writer.write_all("'".as_bytes()).await?; } } Ok(()) } } /// [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%] impl Composer<'_> for PubidChar { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all(self.0.to_string().as_bytes()).await?; Ok(()) } } /// [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*) impl<'s> Composer<'s> for CharData<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all(self.0.as_bytes()).await?; Ok(()) } } /// [15] Comment ::= '' impl<'s> Composer<'s> for Comment<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [16] PI ::= '' Char*)))? '?>' impl<'s> Composer<'s> for PI<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l')) impl<'s> Composer<'s> for PITarget<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { self.0.write(writer).await?; Ok(()) } } /// [18] CDSect ::= CDStart CData CDEnd impl<'s> Composer<'s> for CDSect<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { CDStart.write(writer).await?; self.0.write(writer).await?; CDEnd.write(writer).await?; Ok(()) } } /// [19] CDStart ::= ' for CDStart { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("' Char*)) impl<'s> Composer<'s> for CData<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all(self.0.as_bytes()).await?; Ok(()) } } /// [21] CDEnd ::= ']]>' impl Composer<'_> for CDEnd { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("]]>".as_bytes()).await?; Ok(()) } } /// [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)? impl<'s> Composer<'s> for Prolog<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { if let Some(xml_decl) = &self.xml_decl { xml_decl.write(writer).await?; } for misc in &self.miscs { misc.write(writer).await?; } if let Some((doctype_decl, miscs)) = &self.doctype_decl { doctype_decl.write(writer).await?; for misc in miscs { misc.write(writer).await?; } } Ok(()) } } /// [23] XMLDecl ::= '' impl<'s> Composer<'s> for XMLDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"') impl Composer<'_> for VersionInfo { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { S.write(writer).await?; writer.write_all("version".as_bytes()).await?; Eq.write(writer).await?; match self { VersionInfo::SingleQuoted(version_num) => { writer.write_all("'".as_bytes()).await?; version_num.write(writer).await?; writer.write_all("'".as_bytes()).await?; } VersionInfo::DoubleQuoted(version_num) => { writer.write_all("\"".as_bytes()).await?; version_num.write(writer).await?; writer.write_all("\"".as_bytes()).await?; } } Ok(()) } } /// [25] Eq ::= S? '=' S? impl Composer<'_> for Eq { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("=".as_bytes()).await?; Ok(()) } } /// [26] VersionNum ::= '1.' [0-9]+ impl Composer<'_> for VersionNum { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { VersionNum::One => writer.write_all("1.0".as_bytes()).await?, VersionNum::OneDotOne => writer.write_all("1.1".as_bytes()).await?, } Ok(()) } } /// [27] Misc ::= Comment | PI | S impl<'s> Composer<'s> for Misc<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { Misc::Comment(comment) => comment.write(writer).await?, Misc::PI(pi) => pi.write(writer).await?, Misc::S => {} } Ok(()) } } /// [16] doctypedecl ::= '' /// [28] doctypedecl ::= '' impl<'s> Composer<'s> for DoctypeDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [28a] DeclSep ::= PEReference | S impl<'s> Composer<'s> for DeclSep<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { DeclSep::PEReference(pe_reference) => pe_reference.write(writer).await?, DeclSep::S => S.write(writer).await?, } Ok(()) } } /// [28b] intSubset ::= (markupdecl | DeclSep)* impl<'s> Composer<'s> for IntSubset<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { for declaration in &self.0 { match declaration { super::IntSubsetDeclaration::MarkupDecl(markup_decl) => { markup_decl.write(writer).await? } super::IntSubsetDeclaration::DeclSep(decl_sep) => decl_sep.write(writer).await?, } } Ok(()) } } /// [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment impl<'s> Composer<'s> for MarkupDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { MarkupDecl::Elementdecl(elementdecl) => elementdecl.write(writer).await?, MarkupDecl::AttlistDecl(attlist_decl) => attlist_decl.write(writer).await?, MarkupDecl::EntityDecl(entity_decl) => entity_decl.write(writer).await?, MarkupDecl::NotationDecl(notation_decl) => notation_decl.write(writer).await?, MarkupDecl::PI(pi) => pi.write(writer).await?, MarkupDecl::Comment(comment) => comment.write(writer).await?, } Ok(()) } } /// [30] extSubset ::= TextDecl? extSubsetDecl impl<'s> Composer<'s> for ExtSubset<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { if let Some(text_decl) = &self.text_decl { text_decl.write(writer).await? } self.ext_subset_decl.write(writer).await?; Ok(()) } } /// [31] extSubsetDecl ::= ( markupdecl | conditionalSect | DeclSep)* impl<'s> Composer<'s> for ExtSubsetDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { for declaration in &self.0 { match declaration { ExtSubsetDeclaration::MarkupDecl(markup_decl) => markup_decl.write(writer).await?, ExtSubsetDeclaration::ConditionalSect(conditional_sect) => { Box::pin(conditional_sect.write(writer)).await? } ExtSubsetDeclaration::DeclSep(decl_sep) => decl_sep.write(writer).await?, } } Ok(()) } } /// [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"')) impl Composer<'_> for SDDecl { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { S.write(writer).await?; writer.write_all("standalone".as_bytes()).await?; Eq.write(writer).await?; match self { SDDecl::SingleQuoted(sd_decl) => { writer.write_all("'".as_bytes()).await?; match sd_decl { true => writer.write_all("yes".as_bytes()).await?, false => writer.write_all("no".as_bytes()).await?, } writer.write_all("'".as_bytes()).await?; } SDDecl::DoubleQuoted(sd_decl) => { writer.write_all("\"".as_bytes()).await?; match sd_decl { true => writer.write_all("yes".as_bytes()).await?, false => writer.write_all("no".as_bytes()).await?, } writer.write_all("\"".as_bytes()).await?; } } Ok(()) } } // (Productions 33 through 38 have been removed.) /// [39] element ::= EmptyElemTag | STag content ETag impl<'s> Composer<'s> for Element<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { Element::Empty(empty_elem_tag) => empty_elem_tag.write(writer).await?, Element::NotEmpty(s_tag, content, e_tag) => { s_tag.write(writer).await?; content.write(writer).await?; e_tag.write(writer).await?; } } Ok(()) } } /// [12] STag ::= '<' QName (S Attribute)* S? '>' /// [40] STag ::= '<' Name (S Attribute)* S? '>' impl<'s> Composer<'s> for STag<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("<".as_bytes()).await?; self.name.write(writer).await?; for attribute in &self.attributes { S.write(writer).await?; attribute.write(writer).await?; } writer.write_all(">".as_bytes()).await?; Ok(()) } } /// [15] Attribute ::= NSAttName Eq AttValue | QName Eq AttValue impl<'s> Composer<'s> for Attribute<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { Attribute::NamespaceDeclaration { ns_name, value } => { ns_name.write(writer).await?; Eq.write(writer).await?; value.write(writer).await?; } Attribute::Attribute { name, value } => { name.write(writer).await?; Eq.write(writer).await?; value.write(writer).await?; } } Ok(()) } } /// [13] ETag ::= '' impl<'s> Composer<'s> for ETag<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [43] content ::= CharData? ((element | Reference | CDSect | PI | Comment) CharData?)* impl<'s> Composer<'s> for Content<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { if let Some(char_data) = &self.char_data { char_data.write(writer).await?; } for (content, char_data) in &self.content { match content { ContentItem::Element(element) => Box::pin(element.write(writer)).await?, ContentItem::Reference(reference) => reference.write(writer).await?, ContentItem::CDSect(cd_sect) => cd_sect.write(writer).await?, ContentItem::PI(pi) => pi.write(writer).await?, ContentItem::Comment(comment) => comment.write(writer).await?, // TODO: verify no split chardata // _ => todo!("verify no split chardata"), } if let Some(char_data) = char_data { char_data.write(writer).await?; } } Ok(()) } } /// [14] EmptyElemTag ::= '<' QName (S Attribute)* S? '/>' impl<'s> Composer<'s> for EmptyElemTag<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("<".as_bytes()).await?; self.name.write(writer).await?; for attribute in &self.attributes { S.write(writer).await?; attribute.write(writer).await?; } writer.write_all("/>".as_bytes()).await?; Ok(()) } } /// [17] elementdecl ::= '' impl<'s> Composer<'s> for Elementdecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children impl<'s> Composer<'s> for Contentspec<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { Contentspec::Empty => writer.write_all("EMPTY".as_bytes()).await?, Contentspec::Any => writer.write_all("ANY".as_bytes()).await?, Contentspec::Mixed(mixed) => mixed.write(writer).await?, Contentspec::Children(children) => children.write(writer).await?, } Ok(()) } } /// Occurence ::= ('?' | '*' | '+')? impl Composer<'_> for Occurence { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { Occurence::Once => {} Occurence::Optional => writer.write_all("?".as_bytes()).await?, Occurence::Many0 => writer.write_all("*".as_bytes()).await?, Occurence::Many1 => writer.write_all("+".as_bytes()).await?, } Ok(()) } } /// [47] children ::= (choice | seq) ('?' | '*' | '+')? impl<'s> Composer<'s> for Children<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match &self.kind { ChildrenKind::Choice(choice) => choice.write(writer).await?, ChildrenKind::Seq(seq) => seq.write(writer).await?, } self.occurence.write(writer).await?; Ok(()) } } /// [18] cp ::= (QName | choice | seq) ('?' | '*' | '+')? impl<'s> Composer<'s> for Cp<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match &self.kind { CpKind::Name(q_name) => q_name.write(writer).await?, CpKind::Choice(choice) => Box::pin(choice.write(writer)).await?, CpKind::Seq(seq) => Box::pin(seq.write(writer)).await?, } self.occurence.write(writer).await?; Ok(()) } } /// [49] choice ::= '(' S? cp ( S? '|' S? cp )+ S? ')' impl<'s> Composer<'s> for Choice<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("(".as_bytes()).await?; let mut first = true; for cp in &self.0 { if !first { writer.write_all("|".as_bytes()).await?; } cp.write(writer).await?; if first { first = false } } writer.write_all(")".as_bytes()).await?; Ok(()) } } /// [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')' impl<'s> Composer<'s> for Seq<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("(".as_bytes()).await?; let mut first = true; for cp in &self.0 { if !first { writer.write_all(",".as_bytes()).await?; } cp.write(writer).await?; if first { first = false } } writer.write_all(")".as_bytes()).await?; Ok(()) } } /// [19] Mixed ::= '(' S? '#PCDATA' (S? '|' S? QName)* S? ')*' | '(' S? '#PCDATA' S? ')' impl<'s> Composer<'s> for Mixed<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("(#PCDATA".as_bytes()).await?; if !self.0.is_empty() { for q_name in &self.0 { writer.write_all("|".as_bytes()).await?; q_name.write(writer).await?; } writer.write_all(")*".as_bytes()).await?; } else { writer.write_all(")".as_bytes()).await?; } Ok(()) } } /// [20] AttlistDecl ::= '' impl<'s> Composer<'s> for AttlistDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [21] AttDef ::= S (QName | NSAttName) S AttType S DefaultDecl impl<'s> Composer<'s> for AttDef<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { S.write(writer).await?; match &self.name { AttDefName::QName(q_name) => q_name.write(writer).await?, AttDefName::NSAttName(ns_att_name) => ns_att_name.write(writer).await?, } S.write(writer).await?; self.att_type.write(writer).await?; S.write(writer).await?; self.default_decl.write(writer).await?; Ok(()) } } /// [54] AttType ::= StringType | TokenizedType | EnumeratedType impl<'s> Composer<'s> for AttType<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { AttType::StringType => StringType.write(writer).await?, AttType::TokenizedType(tokenized_type) => tokenized_type.write(writer).await?, AttType::EnumeratedType(enumerated_type) => enumerated_type.write(writer).await?, } Ok(()) } } /// [55] StringType ::= 'CDATA' impl Composer<'_> for StringType { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("CDATA".as_bytes()).await?; Ok(()) } } /// [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS' impl Composer<'_> for TokenizedType { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { TokenizedType::ID => writer.write_all("ID".as_bytes()).await?, TokenizedType::IDRef => writer.write_all("IDREF".as_bytes()).await?, TokenizedType::IDRefs => writer.write_all("IDREFS".as_bytes()).await?, TokenizedType::Entity => writer.write_all("ENTITY".as_bytes()).await?, TokenizedType::Entities => writer.write_all("ENTITIES".as_bytes()).await?, TokenizedType::NMToken => writer.write_all("NMTOKEN".as_bytes()).await?, TokenizedType::NMTokens => writer.write_all("NMTOKENS".as_bytes()).await?, } Ok(()) } } /// [57] EnumeratedType ::= NotationType | Enumeration impl<'s> Composer<'s> for EnumeratedType<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { EnumeratedType::NotationType(notation_type) => notation_type.write(writer).await?, EnumeratedType::Enumeration(enumeration) => enumeration.write(writer).await?, } Ok(()) } } /// [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')' impl<'s> Composer<'s> for NotationType<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("NOTATION".as_bytes()).await?; S.write(writer).await?; writer.write_all("(".as_bytes()).await?; let mut first = true; for name in &self.0 { if !first { writer.write_all("|".as_bytes()).await?; } name.write(writer).await?; if first { first = false } } writer.write_all(")".as_bytes()).await?; Ok(()) } } /// [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')' impl<'s> Composer<'s> for Enumeration<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("(".as_bytes()).await?; let mut first = true; for nm_token in &self.0 { if !first { writer.write_all("|".as_bytes()).await?; } nm_token.write(writer).await?; if first { first = false } } writer.write_all(")".as_bytes()).await?; Ok(()) } } /// [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue) impl<'s> Composer<'s> for DefaultDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { DefaultDecl::Required => writer.write_all("#REQUIRED".as_bytes()).await?, DefaultDecl::Implied => writer.write_all("#IMPLIED".as_bytes()).await?, DefaultDecl::Fixed(fixed, att_value) => { if *fixed { writer.write_all("#FIXED".as_bytes()).await?; S.write(writer).await?; } att_value.write(writer).await? } } Ok(()) } } /// [61] conditionalSect ::= includeSect | ignoreSect impl<'s> Composer<'s> for ConditionalSect<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { ConditionalSect::IncludeSect(include_sect) => include_sect.write(writer).await?, ConditionalSect::IgnoreSect(ignore_sect) => ignore_sect.write(writer).await?, } Ok(()) } } /// [62] includeSect ::= '' impl<'s> Composer<'s> for IncludeSect<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [63] ignoreSect ::= '' impl<'s> Composer<'s> for IgnoreSect<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [64] ignoreSectContents ::= Ignore ('' Ignore)* impl<'s> Composer<'s> for IgnoreSectContents<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { self.ignore.write(writer).await?; for (ignore_sect_contents, ignore) in &self.ignore_list { writer.write_all("".as_bytes()).await?; ignore.write(writer).await?; } Ok(()) } } /// [65] Ignore ::= Char* - (Char* ('') Char*) impl<'s> Composer<'s> for Ignore<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all(self.0.as_bytes()).await?; Ok(()) } } /// [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';' impl<'s> Composer<'s> for CharRef<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { CharRef::Decimal(decimal) => { writer.write_all("&#".as_bytes()).await?; writer.write_all(decimal.as_bytes()).await?; writer.write_all(";".as_bytes()).await?; } CharRef::Hexadecimal(hexadecimal) => { writer.write_all("&#x".as_bytes()).await?; writer.write_all(hexadecimal.as_bytes()).await?; writer.write_all(";".as_bytes()).await?; } } Ok(()) } } /// [67] Reference ::= EntityRef | CharRef impl<'s> Composer<'s> for Reference<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { Reference::EntityRef(entity_ref) => entity_ref.write(writer).await?, Reference::CharRef(char_ref) => char_ref.write(writer).await?, } Ok(()) } } /// [68] EntityRef ::= '&' Name ';' impl<'s> Composer<'s> for EntityRef<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("&".as_bytes()).await?; self.0.write(writer).await?; writer.write_all(";".as_bytes()).await?; Ok(()) } } /// [69] PEReference ::= '%' Name ';' impl<'s> Composer<'s> for PEReference<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("%".as_bytes()).await?; self.0.write(writer).await?; writer.write_all(";".as_bytes()).await?; Ok(()) } } /// [70] EntityDecl ::= GEDecl | PEDecl impl<'s> Composer<'s> for EntityDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { EntityDecl::GEDecl(ge_decl) => ge_decl.write(writer).await?, EntityDecl::PEDecl(pe_decl) => pe_decl.write(writer).await?, } Ok(()) } } /// [71] GEDecl ::= '' impl<'s> Composer<'s> for GEDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [72] PEDecl ::= '' impl<'s> Composer<'s> for PEDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?) impl<'s> Composer<'s> for EntityDef<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { EntityDef::EntityValue(entity_value) => entity_value.write(writer).await?, EntityDef::ExternalID { external_id, n_data_decl, } => { external_id.write(writer).await?; if let Some(n_data_decl) = n_data_decl { n_data_decl.write(writer).await?; } } } Ok(()) } } /// [74] PEDef ::= EntityValue | ExternalID impl<'s> Composer<'s> for PEDef<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { PEDef::EntityValue(entity_value) => entity_value.write(writer).await?, PEDef::ExternalID(external_id) => external_id.write(writer).await?, } Ok(()) } } /// [75] ExternalID ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral impl<'s> Composer<'s> for ExternalID<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { match self { ExternalID::SYSTEM { system_identifier } => { writer.write_all("SYSTEM".as_bytes()).await?; S.write(writer).await?; system_identifier.write(writer).await?; } ExternalID::PUBLIC { public_identifier, system_identifier, } => { writer.write_all("PUBLIC".as_bytes()).await?; S.write(writer).await?; public_identifier.write(writer).await?; S.write(writer).await?; system_identifier.write(writer).await?; } } Ok(()) } } /// [76] NDataDecl ::= S 'NDATA' S Name impl<'s> Composer<'s> for NDataDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { S.write(writer).await?; writer.write_all("NDATA".as_bytes()).await?; S.write(writer).await?; self.0.write(writer).await?; Ok(()) } } /// [77] TextDecl ::= '' impl<'s> Composer<'s> for TextDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("".as_bytes()).await?; Ok(()) } } /// [78] extParsedEnt ::= TextDecl? content impl<'s> Composer<'s> for ExtParsedEnt<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { if let Some(text_decl) = &self.text_decl { text_decl.write(writer).await?; } self.content.write(writer).await?; Ok(()) } } /// [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName impl<'s> Composer<'s> for EncodingDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { S.write(writer).await?; writer.write_all("encoding".as_bytes()).await?; Eq.write(writer).await?; writer.write_all("\"".as_bytes()).await?; self.0.write(writer).await?; writer.write_all("\"".as_bytes()).await?; Ok(()) } } /// [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')* impl<'s> Composer<'s> for EncName<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all(self.0.as_bytes()).await?; Ok(()) } } /// [82] NotationDecl ::= '' impl<'s> Composer<'s> for NotationDecl<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all(" external_id.write(writer).await?, NotationDeclID::Public(public_id) => public_id.write(writer).await?, } writer.write_all(">".as_bytes()).await?; Ok(()) } } /// [83] PublicID ::= 'PUBLIC' S PubidLiteral impl<'s> Composer<'s> for PublicID<'s> { async fn write(&self, writer: &mut W) -> io::Result<()> where W: Unpin + AsyncWrite, { writer.write_all("PUBLIC".as_bytes()).await?; S.write(writer).await?; self.0.write(writer).await?; Ok(()) } } /// [1] NSAttName ::= PrefixedAttName | DefaultAttName impl<'s> Display for NSAttName<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { NSAttName::PrefixedAttName(prefixed_att_name) => prefixed_att_name.fmt(f)?, NSAttName::DefaultAttName => DefaultAttName.fmt(f)?, } Ok(()) } } /// [2] PrefixedAttName ::= 'xmlns:' NCName impl<'s> Display for PrefixedAttName<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("xmlns:")?; self.0.fmt(f)?; Ok(()) } } /// [3] DefaultAttName ::= 'xmlns'; impl Display for DefaultAttName { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("xmlns")?; Ok(()) } } /// [4] NCName ::= Name - (Char* ':' Char*) impl<'s> Display for NCName<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str(self.0)?; Ok(()) } } /// [7] QName ::= PrefixedName | UnprefixedName impl<'s> Display for QName<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { QName::PrefixedName(prefixed_name) => prefixed_name.fmt(f)?, QName::UnprefixedName(unprefixed_name) => unprefixed_name.fmt(f)?, } Ok(()) } } /// [8] PrefixedName ::= Prefix ':' LocalPart impl<'s> Display for PrefixedName<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.prefix.fmt(f)?; f.write_str(":")?; self.local_part.fmt(f)?; Ok(()) } } /// [9] UnprefixedName ::= LocalPart impl<'s> Display for UnprefixedName<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.0.fmt(f)?; Ok(()) } } /// [10] Prefix ::= NCName impl<'s> Display for Prefix<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.0.fmt(f)?; Ok(()) } } /// [11] LocalPart ::= NCName impl<'s> Display for LocalPart<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.0.fmt(f)?; Ok(()) } } // xml spec /// [1] document ::= prolog element Misc* impl<'s> Display for Document<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.prolog.fmt(f)?; self.element.fmt(f)?; for misc in &self.miscs { misc.fmt(f)? } Ok(()) } } /// [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */ impl Display for Char { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_char(self.0)?; Ok(()) } } /// [3] S ::= (#x20 | #x9 | #xD | #xA)+ impl<'s> Display for S { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("\u{20}")?; Ok(()) } } /// [4] NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF] impl Display for NameStartChar { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_char(self.0)?; Ok(()) } } /// [4a] NameChar ::= NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] impl Display for NameChar { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_char(self.0)?; Ok(()) } } /// [5] Name ::= NameStartChar (NameChar)* impl<'s> Display for Name<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str(self.0)?; Ok(()) } } /// [6] Names ::= Name (#x20 Name)* impl<'s> Display for Names<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let mut first = true; for name in &self.0 { if !first { f.write_str("\u{20}")?; } name.fmt(f)?; if first { first = false } } Ok(()) } } /// [7] Nmtoken ::= (NameChar)+ impl<'s> Display for Nmtoken<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str(self.0)?; Ok(()) } } /// [8] Nmtokens ::= Nmtoken (#x20 Nmtoken)* impl<'s> Display for Nmtokens<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let mut first = true; for nmtoken in &self.0 { if !first { f.write_str("\u{20}")?; } nmtoken.fmt(f)?; if first { first = false } } Ok(()) } } /// [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' /// | "'" ([^%&'] | PEReference | Reference)* "'" impl<'s> Display for EntityValue<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { EntityValue::DoubleQuoted(entity_value_data) => { f.write_str("\"")?; for entity_value_data in entity_value_data { match entity_value_data { EntityValueData::String(s) => f.write_str(s)?, EntityValueData::PEReference(pe_reference) => pe_reference.fmt(f)?, EntityValueData::Reference(reference) => reference.fmt(f)?, } } f.write_str("\"")?; } EntityValue::SingleQuoted(entity_value_data) => { f.write_str("'")?; for entity_value_data in entity_value_data { match entity_value_data { EntityValueData::String(s) => f.write_str(s)?, EntityValueData::PEReference(pe_reference) => pe_reference.fmt(f)?, EntityValueData::Reference(reference) => reference.fmt(f)?, } } f.write_str("'")?; } } Ok(()) } } /// [10] AttValue ::= '"' ([^<&"] | Reference)* '"' /// | "'" ([^<&'] | Reference)* "'" impl<'s> Display for AttValue<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { AttValue::DoubleQuoted(att_value_data) => { f.write_str("\"")?; for att_value_data in att_value_data { match att_value_data { AttValueData::String(s) => f.write_str(s)?, AttValueData::Reference(reference) => reference.fmt(f)?, } } f.write_str("\"")?; } AttValue::SingleQuoted(att_value_data) => { f.write_str("'")?; for att_value_data in att_value_data { match att_value_data { AttValueData::String(s) => f.write_str(s)?, AttValueData::Reference(reference) => reference.fmt(f)?, } } f.write_str("'")?; } } Ok(()) } } /// [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'") impl<'s> Display for SystemLiteral<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { SystemLiteral::DoubleQuoted(s) => { f.write_str("\"")?; f.write_str(s)?; f.write_str("\"")?; } SystemLiteral::SingleQuoted(s) => { f.write_str("'")?; f.write_str(s)?; f.write_str("'")?; } } Ok(()) } } /// [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'" impl<'s> Display for PubidLiteral<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { PubidLiteral::DoubleQuoted(s) => { f.write_str("\"")?; f.write_str(s)?; f.write_str("\"")?; } PubidLiteral::SingleQuoted(s) => { f.write_str("'")?; f.write_str(s)?; f.write_str("'")?; } } Ok(()) } } /// [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%] impl Display for PubidChar { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_char(self.0)?; Ok(()) } } /// [14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*) impl<'s> Display for CharData<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str(self.0)?; Ok(()) } } /// [15] Comment ::= '' impl<'s> Display for Comment<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [16] PI ::= '' Char*)))? '?>' impl<'s> Display for PI<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l')) impl<'s> Display for PITarget<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.0.fmt(f)?; Ok(()) } } /// [18] CDSect ::= CDStart CData CDEnd impl<'s> Display for CDSect<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { CDStart.fmt(f)?; self.0.fmt(f)?; CDEnd.fmt(f)?; Ok(()) } } /// [19] CDStart ::= ') -> fmt::Result { f.write_str("' Char*)) impl<'s> Display for CData<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str(self.0)?; Ok(()) } } /// [21] CDEnd ::= ']]>' impl Display for CDEnd { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("]]>")?; Ok(()) } } /// [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)? impl<'s> Display for Prolog<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { if let Some(xml_decl) = &self.xml_decl { xml_decl.fmt(f)?; } for misc in &self.miscs { misc.fmt(f)?; } if let Some((doctype_decl, miscs)) = &self.doctype_decl { doctype_decl.fmt(f)?; for misc in miscs { misc.fmt(f)?; } } Ok(()) } } /// [23] XMLDecl ::= '' impl<'s> Display for XMLDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [24] VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"') impl Display for VersionInfo { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { S.fmt(f)?; f.write_str("version")?; Eq.fmt(f)?; match self { VersionInfo::SingleQuoted(version_num) => { f.write_str("'")?; version_num.fmt(f)?; f.write_str("'")?; } VersionInfo::DoubleQuoted(version_num) => { f.write_str("\"")?; version_num.fmt(f)?; f.write_str("\"")?; } } Ok(()) } } /// [25] Eq ::= S? '=' S? impl Display for Eq { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("=")?; Ok(()) } } /// [26] VersionNum ::= '1.' [0-9]+ impl Display for VersionNum { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { VersionNum::One => f.write_str("1.0")?, VersionNum::OneDotOne => f.write_str("1.1")?, } Ok(()) } } /// [27] Misc ::= Comment | PI | S impl<'s> Display for Misc<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Misc::Comment(comment) => comment.fmt(f)?, Misc::PI(pi) => pi.fmt(f)?, Misc::S => {} } Ok(()) } } /// [16] doctypedecl ::= '' /// [28] doctypedecl ::= '' impl<'s> Display for DoctypeDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [28a] DeclSep ::= PEReference | S impl<'s> Display for DeclSep<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { DeclSep::PEReference(pe_reference) => pe_reference.fmt(f)?, DeclSep::S => S.fmt(f)?, } Ok(()) } } /// [28b] intSubset ::= (markupdecl | DeclSep)* impl<'s> Display for IntSubset<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { for declaration in &self.0 { match declaration { super::IntSubsetDeclaration::MarkupDecl(markup_decl) => markup_decl.fmt(f)?, super::IntSubsetDeclaration::DeclSep(decl_sep) => decl_sep.fmt(f)?, } } Ok(()) } } /// [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment impl<'s> Display for MarkupDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { MarkupDecl::Elementdecl(elementdecl) => elementdecl.fmt(f)?, MarkupDecl::AttlistDecl(attlist_decl) => attlist_decl.fmt(f)?, MarkupDecl::EntityDecl(entity_decl) => entity_decl.fmt(f)?, MarkupDecl::NotationDecl(notation_decl) => notation_decl.fmt(f)?, MarkupDecl::PI(pi) => pi.fmt(f)?, MarkupDecl::Comment(comment) => comment.fmt(f)?, } Ok(()) } } /// [30] extSubset ::= TextDecl? extSubsetDecl impl<'s> Display for ExtSubset<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { if let Some(text_decl) = &self.text_decl { text_decl.fmt(f)? } self.ext_subset_decl.fmt(f)?; Ok(()) } } /// [31] extSubsetDecl ::= ( markupdecl | conditionalSect | DeclSep)* impl<'s> Display for ExtSubsetDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { for declaration in &self.0 { match declaration { ExtSubsetDeclaration::MarkupDecl(markup_decl) => markup_decl.fmt(f)?, ExtSubsetDeclaration::ConditionalSect(conditional_sect) => { conditional_sect.fmt(f)? } ExtSubsetDeclaration::DeclSep(decl_sep) => decl_sep.fmt(f)?, } } Ok(()) } } /// [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"')) impl Display for SDDecl { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { S.fmt(f)?; f.write_str("standalone")?; Eq.fmt(f)?; match self { SDDecl::SingleQuoted(sd_decl) => { f.write_str("'")?; match sd_decl { true => f.write_str("yes")?, false => f.write_str("no")?, } f.write_str("'")?; } SDDecl::DoubleQuoted(sd_decl) => { f.write_str("\"")?; match sd_decl { true => f.write_str("yes")?, false => f.write_str("no")?, } f.write_str("\"")?; } } Ok(()) } } // (Productions 33 through 38 have been removed.) /// [39] element ::= EmptyElemTag | STag content ETag impl<'s> Display for Element<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Element::Empty(empty_elem_tag) => empty_elem_tag.fmt(f)?, Element::NotEmpty(s_tag, content, e_tag) => { s_tag.fmt(f)?; content.fmt(f)?; e_tag.fmt(f)?; } } Ok(()) } } /// [12] STag ::= '<' QName (S Attribute)* S? '>' /// [40] STag ::= '<' Name (S Attribute)* S? '>' impl<'s> Display for STag<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("<")?; self.name.fmt(f)?; for attribute in &self.attributes { S.fmt(f)?; attribute.fmt(f)?; } f.write_str(">")?; Ok(()) } } /// [15] Attribute ::= NSAttName Eq AttValue | QName Eq AttValue impl<'s> Display for Attribute<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Attribute::NamespaceDeclaration { ns_name, value } => { ns_name.fmt(f)?; Eq.fmt(f)?; value.fmt(f)?; } Attribute::Attribute { name, value } => { name.fmt(f)?; Eq.fmt(f)?; value.fmt(f)?; } } Ok(()) } } /// [13] ETag ::= '' impl<'s> Display for ETag<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [43] content ::= CharData? ((element | Reference | CDSect | PI | Comment) CharData?)* impl<'s> Display for Content<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { if let Some(char_data) = &self.char_data { char_data.fmt(f)?; } for (content, char_data) in &self.content { match content { ContentItem::Element(element) => element.fmt(f)?, ContentItem::Reference(reference) => reference.fmt(f)?, ContentItem::CDSect(cd_sect) => cd_sect.fmt(f)?, ContentItem::PI(pi) => pi.fmt(f)?, ContentItem::Comment(comment) => comment.fmt(f)?, // TODO: verify no split chardata // _ => todo!("verify no split chardata"), } if let Some(char_data) = char_data { char_data.fmt(f)?; } } Ok(()) } } /// [14] EmptyElemTag ::= '<' QName (S Attribute)* S? '/>' impl<'s> Display for EmptyElemTag<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("<")?; self.name.fmt(f)?; for attribute in &self.attributes { S.fmt(f)?; attribute.fmt(f)?; } f.write_str("/>")?; Ok(()) } } /// [17] elementdecl ::= '' impl<'s> Display for Elementdecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children impl<'s> Display for Contentspec<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Contentspec::Empty => f.write_str("EMPTY")?, Contentspec::Any => f.write_str("ANY")?, Contentspec::Mixed(mixed) => mixed.fmt(f)?, Contentspec::Children(children) => children.fmt(f)?, } Ok(()) } } /// Occurence ::= ('?' | '*' | '+')? impl Display for Occurence { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Occurence::Once => {} Occurence::Optional => f.write_str("?")?, Occurence::Many0 => f.write_str("*")?, Occurence::Many1 => f.write_str("+")?, } Ok(()) } } /// [47] children ::= (choice | seq) ('?' | '*' | '+')? impl<'s> Display for Children<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match &self.kind { ChildrenKind::Choice(choice) => choice.fmt(f)?, ChildrenKind::Seq(seq) => seq.fmt(f)?, } self.occurence.fmt(f)?; Ok(()) } } /// [18] cp ::= (QName | choice | seq) ('?' | '*' | '+')? impl<'s> Display for Cp<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match &self.kind { CpKind::Name(q_name) => q_name.fmt(f)?, CpKind::Choice(choice) => choice.fmt(f)?, CpKind::Seq(seq) => seq.fmt(f)?, } self.occurence.fmt(f)?; Ok(()) } } /// [49] choice ::= '(' S? cp ( S? '|' S? cp )+ S? ')' impl<'s> Display for Choice<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("(")?; let mut first = true; for cp in &self.0 { if !first { f.write_str("|")?; } cp.fmt(f)?; if first { first = false } } f.write_str(")")?; Ok(()) } } /// [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')' impl<'s> Display for Seq<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("(")?; let mut first = true; for cp in &self.0 { if !first { f.write_str(",")?; } cp.fmt(f)?; if first { first = false } } f.write_str(")")?; Ok(()) } } /// [19] Mixed ::= '(' S? '#PCDATA' (S? '|' S? QName)* S? ')*' | '(' S? '#PCDATA' S? ')' impl<'s> Display for Mixed<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("(#PCDATA")?; if !self.0.is_empty() { for q_name in &self.0 { f.write_str("|")?; q_name.fmt(f)?; } f.write_str(")*")?; } else { f.write_str(")")?; } Ok(()) } } /// [20] AttlistDecl ::= '' impl<'s> Display for AttlistDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [21] AttDef ::= S (QName | NSAttName) S AttType S DefaultDecl impl<'s> Display for AttDef<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { S.fmt(f)?; match &self.name { AttDefName::QName(q_name) => q_name.fmt(f)?, AttDefName::NSAttName(ns_att_name) => ns_att_name.fmt(f)?, } S.fmt(f)?; self.att_type.fmt(f)?; S.fmt(f)?; self.default_decl.fmt(f)?; Ok(()) } } /// [54] AttType ::= StringType | TokenizedType | EnumeratedType impl<'s> Display for AttType<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { AttType::StringType => StringType.fmt(f)?, AttType::TokenizedType(tokenized_type) => tokenized_type.fmt(f)?, AttType::EnumeratedType(enumerated_type) => enumerated_type.fmt(f)?, } Ok(()) } } /// [55] StringType ::= 'CDATA' impl Display for StringType { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("CDATA")?; Ok(()) } } /// [56] TokenizedType ::= 'ID' | 'IDREF' | 'IDREFS' | 'ENTITY' | 'ENTITIES' | 'NMTOKEN' | 'NMTOKENS' impl Display for TokenizedType { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { TokenizedType::ID => f.write_str("ID")?, TokenizedType::IDRef => f.write_str("IDREF")?, TokenizedType::IDRefs => f.write_str("IDREFS")?, TokenizedType::Entity => f.write_str("ENTITY")?, TokenizedType::Entities => f.write_str("ENTITIES")?, TokenizedType::NMToken => f.write_str("NMTOKEN")?, TokenizedType::NMTokens => f.write_str("NMTOKENS")?, } Ok(()) } } /// [57] EnumeratedType ::= NotationType | Enumeration impl<'s> Display for EnumeratedType<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { EnumeratedType::NotationType(notation_type) => notation_type.fmt(f)?, EnumeratedType::Enumeration(enumeration) => enumeration.fmt(f)?, } Ok(()) } } /// [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')' impl<'s> Display for NotationType<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("NOTATION")?; S.fmt(f)?; f.write_str("(")?; let mut first = true; for name in &self.0 { if !first { f.write_str("|")?; } name.fmt(f)?; if first { first = false } } f.write_str(")")?; Ok(()) } } /// [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')' impl<'s> Display for Enumeration<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("(")?; let mut first = true; for nm_token in &self.0 { if !first { f.write_str("|")?; } nm_token.fmt(f)?; if first { first = false } } f.write_str(")")?; Ok(()) } } /// [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue) impl<'s> Display for DefaultDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { DefaultDecl::Required => f.write_str("#REQUIRED")?, DefaultDecl::Implied => f.write_str("#IMPLIED")?, DefaultDecl::Fixed(fixed, att_value) => { if *fixed { f.write_str("#FIXED")?; S.fmt(f)?; } att_value.fmt(f)? } } Ok(()) } } /// [61] conditionalSect ::= includeSect | ignoreSect impl<'s> Display for ConditionalSect<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { ConditionalSect::IncludeSect(include_sect) => include_sect.fmt(f)?, ConditionalSect::IgnoreSect(ignore_sect) => ignore_sect.fmt(f)?, } Ok(()) } } /// [62] includeSect ::= '' impl<'s> Display for IncludeSect<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [63] ignoreSect ::= '' impl<'s> Display for IgnoreSect<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [64] ignoreSectContents ::= Ignore ('' Ignore)* impl<'s> Display for IgnoreSectContents<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.ignore.fmt(f)?; for (ignore_sect_contents, ignore) in &self.ignore_list { f.write_str("")?; ignore.fmt(f)?; } Ok(()) } } /// [65] Ignore ::= Char* - (Char* ('') Char*) impl<'s> Display for Ignore<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str(self.0)?; Ok(()) } } /// [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';' impl<'s> Display for CharRef<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { CharRef::Decimal(decimal) => { f.write_str("&#")?; f.write_str(decimal)?; f.write_str(";")?; } CharRef::Hexadecimal(hexadecimal) => { f.write_str("&#x")?; f.write_str(hexadecimal)?; f.write_str(";")?; } } Ok(()) } } /// [67] Reference ::= EntityRef | CharRef impl<'s> Display for Reference<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { Reference::EntityRef(entity_ref) => entity_ref.fmt(f)?, Reference::CharRef(char_ref) => char_ref.fmt(f)?, } Ok(()) } } /// [68] EntityRef ::= '&' Name ';' impl<'s> Display for EntityRef<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("&")?; self.0.fmt(f)?; f.write_str(";")?; Ok(()) } } /// [69] PEReference ::= '%' Name ';' impl<'s> Display for PEReference<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("%")?; self.0.fmt(f)?; f.write_str(";")?; Ok(()) } } /// [70] EntityDecl ::= GEDecl | PEDecl impl<'s> Display for EntityDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { EntityDecl::GEDecl(ge_decl) => ge_decl.fmt(f)?, EntityDecl::PEDecl(pe_decl) => pe_decl.fmt(f)?, } Ok(()) } } /// [71] GEDecl ::= '' impl<'s> Display for GEDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [72] PEDecl ::= '' impl<'s> Display for PEDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?) impl<'s> Display for EntityDef<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { EntityDef::EntityValue(entity_value) => entity_value.fmt(f)?, EntityDef::ExternalID { external_id, n_data_decl, } => { external_id.fmt(f)?; if let Some(n_data_decl) = n_data_decl { n_data_decl.fmt(f)?; } } } Ok(()) } } /// [74] PEDef ::= EntityValue | ExternalID impl<'s> Display for PEDef<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { PEDef::EntityValue(entity_value) => entity_value.fmt(f)?, PEDef::ExternalID(external_id) => external_id.fmt(f)?, } Ok(()) } } /// [75] ExternalID ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral impl<'s> Display for ExternalID<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { ExternalID::SYSTEM { system_identifier } => { f.write_str("SYSTEM")?; S.fmt(f)?; system_identifier.fmt(f)?; } ExternalID::PUBLIC { public_identifier, system_identifier, } => { f.write_str("PUBLIC")?; S.fmt(f)?; public_identifier.fmt(f)?; S.fmt(f)?; system_identifier.fmt(f)?; } } Ok(()) } } /// [76] NDataDecl ::= S 'NDATA' S Name impl<'s> Display for NDataDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { S.fmt(f)?; f.write_str("NDATA")?; S.fmt(f)?; self.0.fmt(f)?; Ok(()) } } /// [77] TextDecl ::= '' impl<'s> Display for TextDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("")?; Ok(()) } } /// [78] extParsedEnt ::= TextDecl? content impl<'s> Display for ExtParsedEnt<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { if let Some(text_decl) = &self.text_decl { text_decl.fmt(f)?; } self.content.fmt(f)?; Ok(()) } } /// [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName impl<'s> Display for EncodingDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { S.fmt(f)?; f.write_str("encoding")?; Eq.fmt(f)?; f.write_str("\"")?; self.0.fmt(f)?; f.write_str("\"")?; Ok(()) } } /// [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')* impl<'s> Display for EncName<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str(self.0)?; Ok(()) } } /// [82] NotationDecl ::= '' impl<'s> Display for NotationDecl<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str(" external_id.fmt(f)?, NotationDeclID::Public(public_id) => public_id.fmt(f)?, } f.write_str(">")?; Ok(()) } } /// [83] PublicID ::= 'PUBLIC' S PubidLiteral impl<'s> Display for PublicID<'s> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.write_str("PUBLIC")?; S.fmt(f)?; self.0.fmt(f)?; Ok(()) } }