diff options
Diffstat (limited to 'document_tree/src/elements.rs')
| -rw-r--r-- | document_tree/src/elements.rs | 546 | 
1 files changed, 303 insertions, 243 deletions
| diff --git a/document_tree/src/elements.rs b/document_tree/src/elements.rs index 1db0a24..4921e1a 100644 --- a/document_tree/src/elements.rs +++ b/document_tree/src/elements.rs @@ -1,288 +1,348 @@ -use std::path::PathBuf;  use serde_derive::Serialize; +use std::path::PathBuf; -use crate::attribute_types::{CanBeEmpty,ID,NameToken}; -use crate::extra_attributes::{self,ExtraAttributes}; +use crate::attribute_types::{CanBeEmpty, NameToken, ID};  use crate::element_categories::*; - +use crate::extra_attributes::{self, ExtraAttributes};  //-----------------\\  //Element hierarchy\\  //-----------------\\  pub trait Element { -	/// A list containing one or more unique identifier keys -	fn     ids    (&    self) -> &    Vec<ID>; -	fn     ids_mut(&mut self) -> &mut Vec<ID>; -	/// a list containing the names of an element, typically originating from the element's title or content. -	/// Each name in names must be unique; if there are name conflicts (two or more elements want to the same name), -	/// the contents will be transferred to the dupnames attribute on the duplicate elements. -	/// An element may have at most one of the names or dupnames attributes, but not both. -	fn   names    (&    self) -> &    Vec<NameToken>; -	fn   names_mut(&mut self) -> &mut Vec<NameToken>; -	fn  source    (&    self) -> &    Option<PathBuf>; -	fn  source_mut(&mut self) -> &mut Option<PathBuf>; -	fn classes    (&    self) -> &    Vec<String>; -	fn classes_mut(&mut self) -> &mut Vec<String>; +    /// A list containing one or more unique identifier keys +    fn ids(&self) -> &Vec<ID>; +    fn ids_mut(&mut self) -> &mut Vec<ID>; +    /// a list containing the names of an element, typically originating from the element's title or content. +    /// Each name in names must be unique; if there are name conflicts (two or more elements want to the same name), +    /// the contents will be transferred to the dupnames attribute on the duplicate elements. +    /// An element may have at most one of the names or dupnames attributes, but not both. +    fn names(&self) -> &Vec<NameToken>; +    fn names_mut(&mut self) -> &mut Vec<NameToken>; +    fn source(&self) -> &Option<PathBuf>; +    fn source_mut(&mut self) -> &mut Option<PathBuf>; +    fn classes(&self) -> &Vec<String>; +    fn classes_mut(&mut self) -> &mut Vec<String>;  } -#[derive(Debug,Default,PartialEq,Serialize,Clone)] +#[derive(Debug, Default, PartialEq, Serialize, Clone)]  pub struct CommonAttributes { -	#[serde(skip_serializing_if = "CanBeEmpty::is_empty")] -	ids: Vec<ID>, -	#[serde(skip_serializing_if = "CanBeEmpty::is_empty")] -	names: Vec<NameToken>, -	#[serde(skip_serializing_if = "CanBeEmpty::is_empty")] -	source: Option<PathBuf>, -	#[serde(skip_serializing_if = "CanBeEmpty::is_empty")] -	classes: Vec<String>, -	//TODO: dupnames +    #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] +    ids: Vec<ID>, +    #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] +    names: Vec<NameToken>, +    #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] +    source: Option<PathBuf>, +    #[serde(skip_serializing_if = "CanBeEmpty::is_empty")] +    classes: Vec<String>, +    //TODO: dupnames  }  //----\\  //impl\\  //----\\ -macro_rules! impl_element { ($name:ident) => ( -	impl Element for $name { -		fn     ids    (&    self) -> &    Vec<ID>         { &    self.common.ids     } -		fn     ids_mut(&mut self) -> &mut Vec<ID>         { &mut self.common.ids     } -		fn   names    (&    self) -> &    Vec<NameToken>  { &    self.common.names   } -		fn   names_mut(&mut self) -> &mut Vec<NameToken>  { &mut self.common.names   } -		fn  source    (&    self) -> &    Option<PathBuf> { &    self.common.source  } -		fn  source_mut(&mut self) -> &mut Option<PathBuf> { &mut self.common.source  } -		fn classes    (&    self) -> &    Vec<String> { &    self.common.classes } -		fn classes_mut(&mut self) -> &mut Vec<String> { &mut self.common.classes } -	} -)} +macro_rules! impl_element { +    ($name:ident) => { +        impl Element for $name { +            fn ids(&self) -> &Vec<ID> { +                &self.common.ids +            } +            fn ids_mut(&mut self) -> &mut Vec<ID> { +                &mut self.common.ids +            } +            fn names(&self) -> &Vec<NameToken> { +                &self.common.names +            } +            fn names_mut(&mut self) -> &mut Vec<NameToken> { +                &mut self.common.names +            } +            fn source(&self) -> &Option<PathBuf> { +                &self.common.source +            } +            fn source_mut(&mut self) -> &mut Option<PathBuf> { +                &mut self.common.source +            } +            fn classes(&self) -> &Vec<String> { +                &self.common.classes +            } +            fn classes_mut(&mut self) -> &mut Vec<String> { +                &mut self.common.classes +            } +        } +    }; +} -macro_rules! impl_children { ($name:ident, $childtype:ident) => ( -	impl HasChildren<$childtype> for $name { -		#[allow(clippy::needless_update)] -		fn with_children(children: Vec<$childtype>) -> $name { $name { children: children, ..Default::default() } } -		fn children    (&    self) -> &    Vec<$childtype> { &    self.children } -		fn children_mut(&mut self) -> &mut Vec<$childtype> { &mut self.children } -	} -)} +macro_rules! impl_children { +    ($name:ident, $childtype:ident) => { +        impl HasChildren<$childtype> for $name { +            #[allow(clippy::needless_update)] +            fn with_children(children: Vec<$childtype>) -> $name { +                $name { +                    children, +                    ..Default::default() +                } +            } +            fn children(&self) -> &Vec<$childtype> { +                &self.children +            } +            fn children_mut(&mut self) -> &mut Vec<$childtype> { +                &mut self.children +            } +        } +    }; +}  macro_rules! impl_extra { ($name:ident $($more:tt)*) => ( -	impl ExtraAttributes<extra_attributes::$name> for $name { -		#[allow(clippy::needless_update)] -		fn with_extra(extra: extra_attributes::$name) -> $name { $name { common: Default::default(), extra: extra $($more)* } } -		fn extra    (&    self) -> &    extra_attributes::$name { &    self.extra } -		fn extra_mut(&mut self) -> &mut extra_attributes::$name { &mut self.extra } -	} +    impl ExtraAttributes<extra_attributes::$name> for $name { +        #[allow(clippy::needless_update)] +        fn with_extra(extra: extra_attributes::$name) -> $name { $name { common: Default::default(), extra $($more)* } } +        fn extra    (&    self) -> &    extra_attributes::$name { &    self.extra } +        fn extra_mut(&mut self) -> &mut extra_attributes::$name { &mut self.extra } +    }  )}  trait HasExtraAndChildren<C, A> { -	fn with_extra_and_children(extra: A, children: Vec<C>) -> Self; +    fn with_extra_and_children(extra: A, children: Vec<C>) -> Self;  } -impl<T, C, A> HasExtraAndChildren<C, A> for T where T: HasChildren<C> + ExtraAttributes<A> { -	#[allow(clippy::needless_update)] -	fn with_extra_and_children(extra: A, mut children: Vec<C>) -> Self { -		let mut r = Self::with_extra(extra); -		r.children_mut().extend(children.drain(..)); -		r -	} +impl<T, C, A> HasExtraAndChildren<C, A> for T +where +    T: HasChildren<C> + ExtraAttributes<A>, +{ +    #[allow(clippy::needless_update)] +    fn with_extra_and_children(extra: A, mut children: Vec<C>) -> Self { +        let mut r = Self::with_extra(extra); +        r.children_mut().append(&mut children); +        r +    }  }  macro_rules! impl_new {( -	$(#[$attr:meta])* -	pub struct $name:ident { $( -		$(#[$fattr:meta])* -		$field:ident : $typ:path -	),* $(,)* } +    $(#[$attr:meta])* +    pub struct $name:ident { $( +        $(#[$fattr:meta])* +        $field:ident : $typ:path +    ),* $(,)* }  ) => ( -	$(#[$attr])* -	#[derive(Debug,PartialEq,Serialize,Clone)] -	pub struct $name { $(  -		$(#[$fattr])* $field: $typ, -	)* } -	impl $name { -		pub fn new( $( $field: $typ, )* ) -> $name { $name { $( $field: $field, )* } } -	} +    $(#[$attr])* +    #[derive(Debug,PartialEq,Serialize,Clone)] +    pub struct $name { $( +        $(#[$fattr])* $field: $typ, +    )* } +    impl $name { +        pub fn new( $( $field: $typ, )* ) -> $name { $name { $( $field, )* } } +    }  )}  macro_rules! impl_elem { -	($name:ident) => { -		impl_new!(#[derive(Default)] pub struct $name { -			#[serde(flatten)] common: CommonAttributes, -		}); -		impl_element!($name); -	}; -	($name:ident; +) => { -		impl_new!(#[derive(Default)] pub struct $name { -			#[serde(flatten)] common: CommonAttributes, -			#[serde(flatten)] extra: extra_attributes::$name, -		}); -		impl_element!($name); impl_extra!($name, ..Default::default()); -	}; -	($name:ident; *) => { //same as above with no default -		impl_new!(pub struct $name { -			#[serde(flatten)] common: CommonAttributes, -			#[serde(flatten)] extra: extra_attributes::$name -		}); -		impl_element!($name); impl_extra!($name); -	}; -	($name:ident, $childtype:ident) => { -		impl_new!(#[derive(Default)] pub struct $name { -			#[serde(flatten)] common: CommonAttributes, -			children: Vec<$childtype>, -		}); -		impl_element!($name); impl_children!($name, $childtype); -	}; -	($name:ident, $childtype:ident; +) => { -		impl_new!(#[derive(Default)] pub struct $name { -			#[serde(flatten)] common: CommonAttributes, -			#[serde(flatten)] extra: extra_attributes::$name, -			children: Vec<$childtype>, -		}); -		impl_element!($name); impl_extra!($name, ..Default::default()); impl_children!($name, $childtype); -	}; +    ($name:ident) => { +        impl_new!( +            #[derive(Default)] +            pub struct $name { +                #[serde(flatten)] +                common: CommonAttributes, +            } +        ); +        impl_element!($name); +    }; +    ($name:ident; +) => { +        impl_new!( +            #[derive(Default)] +            pub struct $name { +                #[serde(flatten)] +                common: CommonAttributes, +                #[serde(flatten)] +                extra: extra_attributes::$name, +            } +        ); +        impl_element!($name); +        impl_extra!($name, ..Default::default()); +    }; +    ($name:ident; *) => { +        //same as above with no default +        impl_new!( +            pub struct $name { +                #[serde(flatten)] +                common: CommonAttributes, +                #[serde(flatten)] +                extra: extra_attributes::$name, +            } +        ); +        impl_element!($name); +        impl_extra!($name); +    }; +    ($name:ident, $childtype:ident) => { +        impl_new!( +            #[derive(Default)] +            pub struct $name { +                #[serde(flatten)] +                common: CommonAttributes, +                children: Vec<$childtype>, +            } +        ); +        impl_element!($name); +        impl_children!($name, $childtype); +    }; +    ($name:ident, $childtype:ident; +) => { +        impl_new!( +            #[derive(Default)] +            pub struct $name { +                #[serde(flatten)] +                common: CommonAttributes, +                #[serde(flatten)] +                extra: extra_attributes::$name, +                children: Vec<$childtype>, +            } +        ); +        impl_element!($name); +        impl_extra!($name, ..Default::default()); +        impl_children!($name, $childtype); +    };  }  macro_rules! impl_elems { ( $( ($($args:tt)*) )* ) => ( -	$( impl_elem!($($args)*); )* +    $( impl_elem!($($args)*); )*  )} - -#[derive(Default,Debug,Serialize)] -pub struct Document { children: Vec<StructuralSubElement> } +#[derive(Default, Debug, Serialize)] +pub struct Document { +    children: Vec<StructuralSubElement>, +}  impl_children!(Document, StructuralSubElement);  impl_elems!( -	//structual elements -	(Section, StructuralSubElement) -	(Topic,   SubTopic) -	(Sidebar, SubSidebar) -	 -	//structural subelements -	(Title,      TextOrInlineElement) -	(Subtitle,   TextOrInlineElement) -	(Decoration, DecorationElement) -	(Docinfo,    BibliographicElement) -	(Transition) -	 -	//bibliographic elements -	(Author,       TextOrInlineElement) -	(Authors,      AuthorInfo) -	(Organization, TextOrInlineElement) -	(Address,      TextOrInlineElement; +) -	(Contact,      TextOrInlineElement) -	(Version,      TextOrInlineElement) -	(Revision,     TextOrInlineElement) -	(Status,       TextOrInlineElement) -	(Date,         TextOrInlineElement) -	(Copyright,    TextOrInlineElement) -	(Field,        SubField) -	 -	//decoration elements -	(Header, BodyElement) -	(Footer, BodyElement) -	 -	//simple body elements -	(Paragraph,              TextOrInlineElement) -	(LiteralBlock,           TextOrInlineElement; +) -	(DoctestBlock,           TextOrInlineElement; +) -	(MathBlock,              String) -	(Rubric,                 TextOrInlineElement) -	(SubstitutionDefinition, TextOrInlineElement; +) -	(Comment,                TextOrInlineElement; +) -	(Pending) -	(Target; +) -	(Raw, String; +) -	(Image; *) -	 -	//compound body elements -	(Compound,  BodyElement) -	(Container, BodyElement) -	 -	(BulletList,     ListItem; +) -	(EnumeratedList, ListItem; +) -	(DefinitionList, DefinitionListItem) -	(FieldList,      Field) -	(OptionList,     OptionListItem) -	 -	(LineBlock,     SubLineBlock) -	(BlockQuote,    SubBlockQuote) -	(Admonition,    SubTopic) -	(Attention,     BodyElement) -	(Hint,          BodyElement) -	(Note,          BodyElement) -	(Caution,       BodyElement) -	(Danger,        BodyElement) -	(Error,         BodyElement) -	(Important,     BodyElement) -	(Tip,           BodyElement) -	(Warning,       BodyElement) -	(Footnote,      SubFootnote; +) -	(Citation,      SubFootnote; +) -	(SystemMessage, BodyElement; +) -	(Figure,        SubFigure;   +) -	(Table,         SubTable;    +) - -	//table elements -	(TableGroup, SubTableGroup; +) -	(TableHead,  TableRow;      +) -	(TableBody,  TableRow;      +) -	(TableRow,   TableEntry;    +) -	(TableEntry, BodyElement;   +) -	(TableColspec; +) -	 -	//body sub elements -	(ListItem, BodyElement) -	 -	(DefinitionListItem, SubDLItem) -	(Term,               TextOrInlineElement) -	(Classifier,         TextOrInlineElement) -	(Definition,         BodyElement) -	 -	(FieldName, TextOrInlineElement) -	(FieldBody, BodyElement) -	 -	(OptionListItem, SubOptionListItem) -	(OptionGroup,    Option_) -	(Description,    BodyElement) -	(Option_,        SubOption) -	(OptionString,   String) -	(OptionArgument, String; +) -	 -	(Line,        TextOrInlineElement) -	(Attribution, TextOrInlineElement) -	(Label,       TextOrInlineElement) -	 -	(Caption, TextOrInlineElement) -	(Legend,  BodyElement) -	 -	//inline elements -	(Emphasis,              TextOrInlineElement) -	(Literal,               String) -	(Reference,             TextOrInlineElement; +) -	(Strong,                TextOrInlineElement) -	(FootnoteReference,     TextOrInlineElement; +) -	(CitationReference,     TextOrInlineElement; +) -	(SubstitutionReference, TextOrInlineElement; +) -	(TitleReference,        TextOrInlineElement) -	(Abbreviation,          TextOrInlineElement) -	(Acronym,               TextOrInlineElement) -	(Superscript,           TextOrInlineElement) -	(Subscript,             TextOrInlineElement) -	(Inline,                TextOrInlineElement) -	(Problematic,           TextOrInlineElement; +) -	(Generated,             TextOrInlineElement) -	(Math,                  String) -	 -	//also have non-inline versions. Inline image is no figure child, inline target has content -	(TargetInline, String; +) -	(RawInline,    String; +) -	(ImageInline; *) -	 -	//text element = String +    //structual elements +    (Section, StructuralSubElement) +    (Topic,   SubTopic) +    (Sidebar, SubSidebar) + +    //structural subelements +    (Title,      TextOrInlineElement) +    (Subtitle,   TextOrInlineElement) +    (Decoration, DecorationElement) +    (Docinfo,    BibliographicElement) +    (Transition) + +    //bibliographic elements +    (Author,       TextOrInlineElement) +    (Authors,      AuthorInfo) +    (Organization, TextOrInlineElement) +    (Address,      TextOrInlineElement; +) +    (Contact,      TextOrInlineElement) +    (Version,      TextOrInlineElement) +    (Revision,     TextOrInlineElement) +    (Status,       TextOrInlineElement) +    (Date,         TextOrInlineElement) +    (Copyright,    TextOrInlineElement) +    (Field,        SubField) + +    //decoration elements +    (Header, BodyElement) +    (Footer, BodyElement) + +    //simple body elements +    (Paragraph,              TextOrInlineElement) +    (LiteralBlock,           TextOrInlineElement; +) +    (DoctestBlock,           TextOrInlineElement; +) +    (MathBlock,              String) +    (Rubric,                 TextOrInlineElement) +    (SubstitutionDefinition, TextOrInlineElement; +) +    (Comment,                TextOrInlineElement; +) +    (Pending) +    (Target; +) +    (Raw, String; +) +    (Image; *) + +    //compound body elements +    (Compound,  BodyElement) +    (Container, BodyElement) + +    (BulletList,     ListItem; +) +    (EnumeratedList, ListItem; +) +    (DefinitionList, DefinitionListItem) +    (FieldList,      Field) +    (OptionList,     OptionListItem) + +    (LineBlock,     SubLineBlock) +    (BlockQuote,    SubBlockQuote) +    (Admonition,    SubTopic) +    (Attention,     BodyElement) +    (Hint,          BodyElement) +    (Note,          BodyElement) +    (Caution,       BodyElement) +    (Danger,        BodyElement) +    (Error,         BodyElement) +    (Important,     BodyElement) +    (Tip,           BodyElement) +    (Warning,       BodyElement) +    (Footnote,      SubFootnote; +) +    (Citation,      SubFootnote; +) +    (SystemMessage, BodyElement; +) +    (Figure,        SubFigure;   +) +    (Table,         SubTable;    +) + +    //table elements +    (TableGroup, SubTableGroup; +) +    (TableHead,  TableRow;      +) +    (TableBody,  TableRow;      +) +    (TableRow,   TableEntry;    +) +    (TableEntry, BodyElement;   +) +    (TableColspec; +) + +    //body sub elements +    (ListItem, BodyElement) + +    (DefinitionListItem, SubDLItem) +    (Term,               TextOrInlineElement) +    (Classifier,         TextOrInlineElement) +    (Definition,         BodyElement) + +    (FieldName, TextOrInlineElement) +    (FieldBody, BodyElement) + +    (OptionListItem, SubOptionListItem) +    (OptionGroup,    Option_) +    (Description,    BodyElement) +    (Option_,        SubOption) +    (OptionString,   String) +    (OptionArgument, String; +) + +    (Line,        TextOrInlineElement) +    (Attribution, TextOrInlineElement) +    (Label,       TextOrInlineElement) + +    (Caption, TextOrInlineElement) +    (Legend,  BodyElement) + +    //inline elements +    (Emphasis,              TextOrInlineElement) +    (Literal,               String) +    (Reference,             TextOrInlineElement; +) +    (Strong,                TextOrInlineElement) +    (FootnoteReference,     TextOrInlineElement; +) +    (CitationReference,     TextOrInlineElement; +) +    (SubstitutionReference, TextOrInlineElement; +) +    (TitleReference,        TextOrInlineElement) +    (Abbreviation,          TextOrInlineElement) +    (Acronym,               TextOrInlineElement) +    (Superscript,           TextOrInlineElement) +    (Subscript,             TextOrInlineElement) +    (Inline,                TextOrInlineElement) +    (Problematic,           TextOrInlineElement; +) +    (Generated,             TextOrInlineElement) +    (Math,                  String) + +    //also have non-inline versions. Inline image is no figure child, inline target has content +    (TargetInline, String; +) +    (RawInline,    String; +) +    (ImageInline; *) + +    //text element = String  );  impl<'a> From<&'a str> for TextOrInlineElement { -	fn from(s: &'a str) -> Self { -		s.to_owned().into() -	} +    fn from(s: &'a str) -> Self { +        s.to_owned().into() +    }  } | 
