implement XML composers
This commit is contained in:
parent
d0a8d25d25
commit
009b53c4a9
|
@ -3,12 +3,18 @@ use std::io;
|
||||||
use tokio::io::{AsyncWrite, AsyncWriteExt};
|
use tokio::io::{AsyncWrite, AsyncWriteExt};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
AttValue, AttValueData, CDEnd, CDSect, CDStart, CData, Char, CharData, Comment, DeclSep,
|
AttDef, AttDefName, AttType, AttValue, AttValueData, AttlistDecl, Attribute, CDEnd, CDSect,
|
||||||
DefaultAttName, DoctypeDecl, Document, Element, EntityValue, EntityValueData, Eq, ExtSubset,
|
CDStart, CData, Char, CharData, CharRef, Children, ChildrenKind, Choice, Comment,
|
||||||
ExtSubsetDecl, IntSubset, LocalPart, MarkupDecl, Misc, NCName, NSAttName, Name, NameChar,
|
ConditionalSect, Content, ContentItem, Contentspec, Cp, CpKind, DeclSep, DefaultAttName,
|
||||||
NameStartChar, Names, Nmtoken, Nmtokens, PITarget, Prefix, PrefixedAttName, PrefixedName,
|
DefaultDecl, DoctypeDecl, Document, ETag, Element, Elementdecl, EmptyElemTag, EncName,
|
||||||
Prolog, PubidChar, PubidLiteral, QName, SDDecl, SystemLiteral, UnprefixedName, VersionInfo,
|
EncodingDecl, EntityDecl, EntityDef, EntityRef, EntityValue, EntityValueData, EnumeratedType,
|
||||||
VersionNum, XMLDecl, PI, S,
|
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
|
/// Compact Composer trait, can create different trait later for pretty composition
|
||||||
|
@ -508,10 +514,10 @@ impl<'s> Composer<'s> for XMLDecl<'s> {
|
||||||
{
|
{
|
||||||
writer.write_all("<?xml".as_bytes()).await?;
|
writer.write_all("<?xml".as_bytes()).await?;
|
||||||
self.version_info.write(writer).await?;
|
self.version_info.write(writer).await?;
|
||||||
if let Some(encoding_decl) = self.encoding_decl {
|
if let Some(encoding_decl) = &self.encoding_decl {
|
||||||
encoding_decl.write(writer).await?
|
encoding_decl.write(writer).await?
|
||||||
}
|
}
|
||||||
if let Some(sd_decl) = self.sd_decl {
|
if let Some(sd_decl) = &self.sd_decl {
|
||||||
sd_decl.write(writer).await?
|
sd_decl.write(writer).await?
|
||||||
}
|
}
|
||||||
writer.write_all("?>".as_bytes()).await?;
|
writer.write_all("?>".as_bytes()).await?;
|
||||||
|
@ -594,11 +600,11 @@ impl<'s> Composer<'s> for DoctypeDecl<'s> {
|
||||||
writer.write_all("<!DOCTYPE".as_bytes()).await?;
|
writer.write_all("<!DOCTYPE".as_bytes()).await?;
|
||||||
S.write(writer).await?;
|
S.write(writer).await?;
|
||||||
self.name.write(writer).await?;
|
self.name.write(writer).await?;
|
||||||
if let Some(external_id) = self.external_id {
|
if let Some(external_id) = &self.external_id {
|
||||||
S.write(writer).await?;
|
S.write(writer).await?;
|
||||||
external_id.write(writer).await?;
|
external_id.write(writer).await?;
|
||||||
}
|
}
|
||||||
if let Some(int_subset) = self.int_subset {
|
if let Some(int_subset) = &self.int_subset {
|
||||||
writer.write_all("[".as_bytes()).await?;
|
writer.write_all("[".as_bytes()).await?;
|
||||||
int_subset.write(writer).await?;
|
int_subset.write(writer).await?;
|
||||||
writer.write_all("]".as_bytes()).await?;
|
writer.write_all("]".as_bytes()).await?;
|
||||||
|
@ -664,7 +670,7 @@ impl<'s> Composer<'s> for ExtSubset<'s> {
|
||||||
where
|
where
|
||||||
W: Unpin + AsyncWrite,
|
W: Unpin + AsyncWrite,
|
||||||
{
|
{
|
||||||
if let Some(text_decl) = self.text_decl {
|
if let Some(text_decl) = &self.text_decl {
|
||||||
text_decl.write(writer).await?
|
text_decl.write(writer).await?
|
||||||
}
|
}
|
||||||
self.ext_subset_decl.write(writer).await?;
|
self.ext_subset_decl.write(writer).await?;
|
||||||
|
@ -680,13 +686,11 @@ impl<'s> Composer<'s> for ExtSubsetDecl<'s> {
|
||||||
{
|
{
|
||||||
for declaration in self {
|
for declaration in self {
|
||||||
match declaration {
|
match declaration {
|
||||||
super::ExtSubsetDeclaration::MarkupDecl(markup_decl) => {
|
ExtSubsetDeclaration::MarkupDecl(markup_decl) => markup_decl.write(writer).await?,
|
||||||
markup_decl.write(writer).await?
|
ExtSubsetDeclaration::ConditionalSect(conditional_sect) => {
|
||||||
|
Box::pin(conditional_sect.write(writer)).await?
|
||||||
}
|
}
|
||||||
super::ExtSubsetDeclaration::ConditionalSect(conditional_sect) => {
|
ExtSubsetDeclaration::DeclSep(decl_sep) => decl_sep.write(writer).await?,
|
||||||
conditional_sect.write(writer).await?
|
|
||||||
}
|
|
||||||
super::ExtSubsetDeclaration::DeclSep(decl_sep) => decl_sep.write(writer).await?,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -724,12 +728,768 @@ impl Composer<'_> for SDDecl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// (Productions 33 through 38 have been removed.)
|
||||||
|
|
||||||
/// [39] element ::= EmptyElemTag | STag content ETag
|
/// [39] element ::= EmptyElemTag | STag content ETag
|
||||||
impl<'s> Composer<'s> for Element<'s> {
|
impl<'s> Composer<'s> for Element<'s> {
|
||||||
async fn write<W>(&self, writer: &mut W) -> io::Result<()>
|
async fn write<W>(&self, writer: &mut W) -> io::Result<()>
|
||||||
where
|
where
|
||||||
W: Unpin + AsyncWrite,
|
W: Unpin + AsyncWrite,
|
||||||
{
|
{
|
||||||
todo!()
|
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<W>(&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<W>(&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 ::= '</' QName S? '>'
|
||||||
|
impl<'s> Composer<'s> for ETag<'s> {
|
||||||
|
async fn write<W>(&self, writer: &mut W) -> io::Result<()>
|
||||||
|
where
|
||||||
|
W: Unpin + AsyncWrite,
|
||||||
|
{
|
||||||
|
writer.write_all("</".as_bytes()).await?;
|
||||||
|
self.name.write(writer).await?;
|
||||||
|
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<W>(&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?,
|
||||||
|
}
|
||||||
|
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<W>(&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 ::= '<!ELEMENT' S QName S contentspec S? '>'
|
||||||
|
impl<'s> Composer<'s> for Elementdecl<'s> {
|
||||||
|
async fn write<W>(&self, writer: &mut W) -> io::Result<()>
|
||||||
|
where
|
||||||
|
W: Unpin + AsyncWrite,
|
||||||
|
{
|
||||||
|
writer.write_all("<!ELEMENT".as_bytes()).await?;
|
||||||
|
S.write(writer).await?;
|
||||||
|
self.name.write(writer).await?;
|
||||||
|
S.write(writer).await?;
|
||||||
|
self.contentspec.write(writer).await?;
|
||||||
|
writer.write_all(">".as_bytes()).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
|
||||||
|
impl<'s> Composer<'s> for Contentspec<'s> {
|
||||||
|
async fn write<W>(&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<W>(&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<W>(&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<W>(&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<W>(&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<W>(&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<W>(&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 ::= '<!ATTLIST' S QName AttDef* S? '>'
|
||||||
|
impl<'s> Composer<'s> for AttlistDecl<'s> {
|
||||||
|
async fn write<W>(&self, writer: &mut W) -> io::Result<()>
|
||||||
|
where
|
||||||
|
W: Unpin + AsyncWrite,
|
||||||
|
{
|
||||||
|
writer.write_all("<!ATTLIST".as_bytes()).await?;
|
||||||
|
S.write(writer).await?;
|
||||||
|
self.element_type.write(writer).await?;
|
||||||
|
for att_def in &self.att_defs {
|
||||||
|
att_def.write(writer).await?;
|
||||||
|
}
|
||||||
|
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<W>(&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<W>(&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<W>(&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<W>(&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<W>(&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<W>(&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<W>(&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<W>(&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<W>(&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 ::= '<![' S? 'INCLUDE' S? '[' extSubsetDecl ']]>'
|
||||||
|
impl<'s> Composer<'s> for IncludeSect<'s> {
|
||||||
|
async fn write<W>(&self, writer: &mut W) -> io::Result<()>
|
||||||
|
where
|
||||||
|
W: Unpin + AsyncWrite,
|
||||||
|
{
|
||||||
|
writer.write_all("<![INCLUDE[".as_bytes()).await?;
|
||||||
|
self.0.write(writer).await?;
|
||||||
|
writer.write_all("]]>".as_bytes()).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [63] ignoreSect ::= '<![' S? 'IGNORE' S? '[' ignoreSectContents* ']]>'
|
||||||
|
impl<'s> Composer<'s> for IgnoreSect<'s> {
|
||||||
|
async fn write<W>(&self, writer: &mut W) -> io::Result<()>
|
||||||
|
where
|
||||||
|
W: Unpin + AsyncWrite,
|
||||||
|
{
|
||||||
|
writer.write_all("<![IGNORE[".as_bytes()).await?;
|
||||||
|
for ignore_sect_contents in &self.0 {
|
||||||
|
ignore_sect_contents.write(writer).await?;
|
||||||
|
}
|
||||||
|
writer.write_all("]]>".as_bytes()).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [64] ignoreSectContents ::= Ignore ('<![' ignoreSectContents ']]>' Ignore)*
|
||||||
|
impl<'s> Composer<'s> for IgnoreSectContents<'s> {
|
||||||
|
async fn write<W>(&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?;
|
||||||
|
Box::pin(ignore_sect_contents.write(writer)).await?;
|
||||||
|
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<W>(&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<W>(&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<W>(&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<W>(&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<W>(&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<W>(&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 ::= '<!ENTITY' S Name S EntityDef S? '>'
|
||||||
|
impl<'s> Composer<'s> for GEDecl<'s> {
|
||||||
|
async fn write<W>(&self, writer: &mut W) -> io::Result<()>
|
||||||
|
where
|
||||||
|
W: Unpin + AsyncWrite,
|
||||||
|
{
|
||||||
|
writer.write_all("<!ENTITY".as_bytes()).await?;
|
||||||
|
S.write(writer).await?;
|
||||||
|
self.name.write(writer).await?;
|
||||||
|
S.write(writer).await?;
|
||||||
|
self.entity_def.write(writer).await?;
|
||||||
|
writer.write_all(">".as_bytes()).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
|
||||||
|
impl<'s> Composer<'s> for PEDecl<'s> {
|
||||||
|
async fn write<W>(&self, writer: &mut W) -> io::Result<()>
|
||||||
|
where
|
||||||
|
W: Unpin + AsyncWrite,
|
||||||
|
{
|
||||||
|
writer.write_all("<!ENTITY".as_bytes()).await?;
|
||||||
|
S.write(writer).await?;
|
||||||
|
writer.write_all("%".as_bytes()).await?;
|
||||||
|
S.write(writer).await?;
|
||||||
|
self.name.write(writer).await?;
|
||||||
|
S.write(writer).await?;
|
||||||
|
self.pe_def.write(writer).await?;
|
||||||
|
writer.write_all(">".as_bytes()).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
|
||||||
|
impl<'s> Composer<'s> for EntityDef<'s> {
|
||||||
|
async fn write<W>(&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<W>(&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<W>(&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<W>(&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 ::= '<?xml' VersionInfo? EncodingDecl S? '?>'
|
||||||
|
impl<'s> Composer<'s> for TextDecl<'s> {
|
||||||
|
async fn write<W>(&self, writer: &mut W) -> io::Result<()>
|
||||||
|
where
|
||||||
|
W: Unpin + AsyncWrite,
|
||||||
|
{
|
||||||
|
writer.write_all("<?xml".as_bytes()).await?;
|
||||||
|
if let Some(version_info) = &self.version_info {
|
||||||
|
version_info.write(writer).await?;
|
||||||
|
}
|
||||||
|
self.encoding_decl.write(writer).await?;
|
||||||
|
writer.write_all("?>".as_bytes()).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [78] extParsedEnt ::= TextDecl? content
|
||||||
|
impl<'s> Composer<'s> for ExtParsedEnt<'s> {
|
||||||
|
async fn write<W>(&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<W>(&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<W>(&self, writer: &mut W) -> io::Result<()>
|
||||||
|
where
|
||||||
|
W: Unpin + AsyncWrite,
|
||||||
|
{
|
||||||
|
writer.write_all(self.0.as_bytes()).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID | PublicID) S? '>'
|
||||||
|
impl<'s> Composer<'s> for NotationDecl<'s> {
|
||||||
|
async fn write<W>(&self, writer: &mut W) -> io::Result<()>
|
||||||
|
where
|
||||||
|
W: Unpin + AsyncWrite,
|
||||||
|
{
|
||||||
|
writer.write_all("<!NOTATION".as_bytes()).await?;
|
||||||
|
S.write(writer).await?;
|
||||||
|
self.name.write(writer).await?;
|
||||||
|
S.write(writer).await?;
|
||||||
|
match &self.id {
|
||||||
|
NotationDeclID::External(external_id) => 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<W>(&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(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -345,6 +345,7 @@ pub struct Elementdecl<'s> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: casings???
|
// TODO: casings???
|
||||||
|
// TODO: wtf does that todo mean?
|
||||||
/// [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
|
/// [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Contentspec<'s> {
|
pub enum Contentspec<'s> {
|
||||||
|
@ -469,7 +470,8 @@ pub struct Enumeration<'s>(Vec<Nmtoken<'s>>);
|
||||||
pub enum DefaultDecl<'s> {
|
pub enum DefaultDecl<'s> {
|
||||||
Required,
|
Required,
|
||||||
Implied,
|
Implied,
|
||||||
Fixed(AttValue<'s>),
|
/// if bool == true, attribute MUST always have default value
|
||||||
|
Fixed(bool, AttValue<'s>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [61] conditionalSect ::= includeSect | ignoreSect
|
/// [61] conditionalSect ::= includeSect | ignoreSect
|
||||||
|
@ -544,7 +546,7 @@ pub enum EntityDef<'s> {
|
||||||
EntityValue(EntityValue<'s>),
|
EntityValue(EntityValue<'s>),
|
||||||
ExternalID {
|
ExternalID {
|
||||||
external_id: ExternalID<'s>,
|
external_id: ExternalID<'s>,
|
||||||
ndata_decl: Option<NDataDecl<'s>>,
|
n_data_decl: Option<NDataDecl<'s>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,8 +585,9 @@ pub struct ExtParsedEnt<'s> {
|
||||||
content: Content<'s>,
|
content: Content<'s>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName
|
/// [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" )
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
// TODO?: select quote version
|
||||||
pub struct EncodingDecl<'s>(EncName<'s>);
|
pub struct EncodingDecl<'s>(EncName<'s>);
|
||||||
|
|
||||||
/// [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
|
/// [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*
|
||||||
|
|
|
@ -1082,8 +1082,8 @@ impl<'s> Parser<'s, DefaultDecl<'s>> for DefaultDecl<'s> {
|
||||||
value(DefaultDecl::Required, tag("#REQUIRED")),
|
value(DefaultDecl::Required, tag("#REQUIRED")),
|
||||||
value(DefaultDecl::Implied, tag("#IMPLIED")),
|
value(DefaultDecl::Implied, tag("#IMPLIED")),
|
||||||
map(
|
map(
|
||||||
preceded(opt(pair(tag("#FIXED"), S::parse)), AttValue::parse),
|
pair(opt(pair(tag("#FIXED"), S::parse)), AttValue::parse),
|
||||||
|att_value| DefaultDecl::Fixed(att_value),
|
|(must, att_value)| DefaultDecl::Fixed(must.is_some(), att_value),
|
||||||
),
|
),
|
||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
@ -1272,9 +1272,9 @@ impl<'s> Parser<'s, EntityDef<'s>> for EntityDef<'s> {
|
||||||
}),
|
}),
|
||||||
map(
|
map(
|
||||||
pair(ExternalID::parse, opt(NDataDecl::parse)),
|
pair(ExternalID::parse, opt(NDataDecl::parse)),
|
||||||
|(external_id, ndata_decl)| EntityDef::ExternalID {
|
|(external_id, n_data_decl)| EntityDef::ExternalID {
|
||||||
external_id,
|
external_id,
|
||||||
ndata_decl,
|
n_data_decl,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
))(input)
|
))(input)
|
||||||
|
|
Loading…
Reference in New Issue