diff options
author | HampusM <hampus@hampusmat.com> | 2023-05-16 21:59:46 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2023-05-16 21:59:46 +0200 |
commit | cc30a537284871d668911353bd121e38d0353eb0 (patch) | |
tree | 121976a44346f5979447d9d9052372246d4ff66c /src/paragraph/part.rs | |
parent | b336066d6067a0eb9ff9fc34c5aa062b86e56c62 (diff) |
Diffstat (limited to 'src/paragraph/part.rs')
-rw-r--r-- | src/paragraph/part.rs | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/src/paragraph/part.rs b/src/paragraph/part.rs new file mode 100644 index 0000000..5e5a846 --- /dev/null +++ b/src/paragraph/part.rs @@ -0,0 +1,247 @@ +use crate::emphasis::{Emphasis, Error as EmphasisError}; +use crate::itemized_list::{Error as ItemizedListError, ItemizedList}; +use crate::paragraph::{Error as ParagraphError, Paragraph}; +use crate::table::{Error as TableError, Informal as InformalTable, Table}; +use crate::variable_list::{Error as VariableListError, VariableList}; +use crate::xml::element::{Elements, FromElements, Tagged}; + +/// Paragraph part. +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Part +{ + /// Text part. + Text(String), + + /// <constant>..</constant> part. + Constant(String), + + /// <function>..</function> part. + Function(String), + + /// <parameter>..</parameter> part. + Parameter(String), + + /// Emphasis part. + Emphasis(Emphasis), + + /// Code part. + Code(String), + + /// Inline equation part. + InlineEquation(String), + + /// Program listing part. + ProgramListing(String), + + /// Reference entry citation part. + Entry(String), + + /// Variable list part. + VariableList(VariableList), + + /// Itemized list part. + ItemizedList(ItemizedList), + + /// Informal table part. + InformalTable(InformalTable), + + /// Paragraph part. + Paragraph(Paragraph), + + /// Footnote part. + Footnote(Paragraph), + + /// Table part. + Table(Table), + + /// Informal equation part. + InformalEquation(String), + + /// Superscript part. + Superscript(String), +} + +impl FromElements for Part +{ + type Error = Error; + + fn from_elements(elements: &Elements) -> Result<Self, Self::Error> + { + if let Some(tagged_element) = elements.get_first_tagged() { + return Self::from_tagged_element(tagged_element); + } + + let text = elements + .get_first_text_element() + .ok_or(Self::Error::ExpectedTextElement)?; + + Ok(Self::Text(text.clone())) + } +} + +impl Part +{ + fn from_tagged_element( + tagged_element: &Tagged, + ) -> Result<Self, <Self as FromElements>::Error> + { + let create: fn(String) -> Self = match tagged_element.name() { + "constant" => Self::Constant, + "function" => Self::Function, + "parameter" => Self::Parameter, + "code" => Self::Code, + "inlineequation" => Self::InlineEquation, + "programlisting" => Self::ProgramListing, + "citerefentry" => Self::Entry, + "superscript" => Self::Superscript, + "variablelist" | "itemizedlist" | "informaltable" | "para" | "footnote" + | "table" | "informalequation" | "emphasis" => |_| { + unreachable!(); + }, + _ => { + return Err(<Self as FromElements>::Error::UnknownPart( + tagged_element.name().to_string(), + )); + } + }; + + if tagged_element.name() == "citerefentry" { + let title_element = tagged_element + .child_elements() + .get_first_tagged_with_name("refentrytitle") + .ok_or(<Self as FromElements>::Error::NoEntryTitleFound)?; + + let title = title_element + .child_elements() + .get_first_text_element() + .ok_or(<Self as FromElements>::Error::NoTextInTagged)?; + + return Ok(Self::Entry(title.clone())); + } + + if tagged_element.name() == "variablelist" { + let variable_list = + VariableList::from_elements(tagged_element.child_elements())?; + + return Ok(Self::VariableList(variable_list)); + } + + if tagged_element.name() == "itemizedlist" { + let itemized_list = + ItemizedList::from_elements(tagged_element.child_elements())?; + + return Ok(Self::ItemizedList(itemized_list)); + } + + if tagged_element.name() == "informaltable" { + let informal_table = + InformalTable::from_elements(tagged_element.child_elements()) + .map_err(|err| Error::InvalidInformalTable(Box::new(err)))?; + + return Ok(Self::InformalTable(informal_table)); + } + + if tagged_element.name() == "inlineequation" { + return Ok(Self::InlineEquation( + tagged_element + .child_elements() + .into_iter() + .map(ToString::to_string) + .collect::<String>(), + )); + } + + if tagged_element.name() == "para" { + return Ok(Self::Paragraph( + Paragraph::from_elements(tagged_element.child_elements()) + .map_err(|err| Error::InvalidParagraph(Box::new(err)))?, + )); + } + + if tagged_element.name() == "footnote" { + return Ok(Self::Footnote( + Paragraph::from_elements(tagged_element.child_elements()) + .map_err(|err| Error::InvalidFootnote(Box::new(err)))?, + )); + } + + if tagged_element.name() == "table" { + let table = Table::from_elements(tagged_element.child_elements()) + .map_err(|err| Error::InvalidInformalTable(Box::new(err)))?; + + return Ok(Self::Table(table)); + } + + if tagged_element.name() == "informalequation" { + return Ok(Self::InlineEquation( + tagged_element + .child_elements() + .into_iter() + .map(ToString::to_string) + .collect::<String>(), + )); + } + + if tagged_element.name() == "emphasis" { + return Ok(Self::Emphasis(Emphasis::from_tagged_element( + tagged_element, + )?)); + } + + let text_element = tagged_element + .child_elements() + .get_first_text_element() + .ok_or(<Self as FromElements>::Error::NoTextInTagged)?; + + Ok(create(text_element.clone())) + } +} + +/// [`Part`] error. +#[derive(Debug, thiserror::Error)] +pub enum Error +{ + /// Expected a text element. + #[error("Expected a text element")] + ExpectedTextElement, + + /// A input element is a unknown paragraph part. + #[error("Input element with name '{0}' is a unknown paragraph part")] + UnknownPart(String), + + /// No text was found in tagged input element. + #[error("No text was found in tagged input element")] + NoTextInTagged, + + /// No entry title found. + #[error("No entry title found")] + NoEntryTitleFound, + + /// Invalid variable list. + #[error("Invalid variable list")] + InvalidVariableList(#[from] VariableListError), + + /// Invalid itemized list. + #[error("Invalid itemized list")] + InvalidItemizedList(#[from] ItemizedListError), + + /// Invalid informal table. + #[error("Invalid informal table")] + InvalidInformalTable(#[source] Box<TableError>), + + /// Invalid paragraph. + #[error("Invalid paragraph")] + InvalidParagraph(#[source] Box<ParagraphError>), + + /// Invalid footnote. + #[error("Invalid footnote")] + InvalidFootnote(#[source] Box<ParagraphError>), + + /// Invalid table. + #[error("Invalid table")] + InvalidTable(#[source] Box<TableError>), + + /// Invalid emphasis. + #[error("Invalid emphasis")] + InvalidEmphasis(#[from] EmphasisError), +} |