diff options
Diffstat (limited to 'src/description.rs')
-rw-r--r-- | src/description.rs | 550 |
1 files changed, 0 insertions, 550 deletions
diff --git a/src/description.rs b/src/description.rs deleted file mode 100644 index d55737d..0000000 --- a/src/description.rs +++ /dev/null @@ -1,550 +0,0 @@ -//! Reference entry description. -use crate::gloss_list::{Error as GlossListError, GlossList}; -use crate::itemized_list::{Error as ItemizedListError, ItemizedList}; -use crate::table::{Error as TableError, Informal, Table}; -use crate::variable_list::{Error as VariableListError, VariableList}; -use crate::xml::element::{Element, Elements, FromElements, Tagged}; - -/// Reference entry description. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Description -{ - for_function: Option<String>, - parts: Vec<Part>, -} - -impl Description -{ - /// Returns a new empty `Description`. - #[must_use] - pub fn new() -> Self - { - Self { - for_function: None, - parts: Vec::new(), - } - } - - /// Returns what function this description is specific for. - #[must_use] - pub fn for_function(&self) -> &Option<String> - { - &self.for_function - } - - /// Returns the description's parts. - #[must_use] - pub fn parts(&self) -> &[Part] - { - &self.parts - } -} - -impl Default for Description -{ - fn default() -> Self - { - Self::new() - } -} - -impl FromElements for Description -{ - type Error = Error; - - fn from_elements(elements: &Elements) -> Result<Self, Self::Error> - { - let for_function = - elements - .get_first_tagged_with_name("title") - .and_then(|title_element| { - let title_text = - title_element.child_elements().get_first_text_element()?; - - if title_text != "Description for " { - return None; - } - - let function_element = title_element - .child_elements() - .get_first_tagged_with_name("function")?; - - function_element - .child_elements() - .get_first_text_element() - .cloned() - }); - - let parts = elements - .get_all_tagged_elements() - .into_iter() - .filter_map(|part_elem| match part_elem.name() { - "para" => Some( - Paragraph::from_elements(part_elem.child_elements()) - .map(Part::Paragraph) - .map_err(Self::Error::InvalidParagraph), - ), - - "variablelist" => Some( - VariableList::from_elements(part_elem.child_elements()) - .map(Part::VariableList) - .map_err(Self::Error::InvalidVariableList), - ), - "programlisting" => Some(Ok(Part::ProgramListing( - part_elem - .child_elements() - .get_first_text_element() - .cloned() - .unwrap_or_default(), - ))), - "informaltable" => Some( - Informal::from_elements(part_elem.child_elements()) - .map(Part::InformalTable) - .map_err(Self::Error::InvalidInformalTable), - ), - "itemizedlist" => Some( - ItemizedList::from_elements(part_elem.child_elements()) - .map(Part::ItemizedList) - .map_err(Self::Error::InvalidItemizedList), - ), - "table" => Some( - Table::from_elements(part_elem.child_elements()) - .map(Part::Table) - .map_err(Self::Error::InvalidTable), - ), - "glosslist" => Some( - GlossList::from_elements(part_elem.child_elements()) - .map(Part::GlossList) - .map_err(Self::Error::InvalidGlossList), - ), - "title" => None, - name => Some(Err(Self::Error::UnknownPartFound(name.to_string()))), - }) - .collect::<Result<Vec<_>, Self::Error>>()?; - - Ok(Description { - for_function, - parts, - }) - } -} - -/// [`Description`] error. -#[derive(Debug, thiserror::Error)] -pub enum Error -{ - /// Unknown part element found. - #[error("Unknown part element with name '{0}' found")] - UnknownPartFound(String), - - /// Invalid paragraph. - #[error("Invalid paragraph")] - InvalidParagraph(#[source] ParagraphError), - - /// Invalid variable list. - #[error("Invalid variable list")] - InvalidVariableList(#[source] VariableListError), - - /// Invalid informal table. - #[error("Invalid informal table")] - InvalidInformalTable(#[source] TableError), - - /// Invalid itemized list. - #[error("Invalid itemized list")] - InvalidItemizedList(#[source] ItemizedListError), - - /// Invalid table. - #[error("Invalid table")] - InvalidTable(#[source] TableError), - - /// Invalid gloss list. - #[error("Invalid gloss list")] - InvalidGlossList(#[source] GlossListError), -} - -/// Description part. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum Part -{ - /// Paragraph. - Paragraph(Paragraph), - - /// Variable list. - VariableList(VariableList), - - /// Program listing. - ProgramListing(String), - - /// Informal table. - InformalTable(Informal), - - /// Itemized list. - ItemizedList(ItemizedList), - - /// Table. - Table(Table), - - /// Gloss list. - GlossList(GlossList), -} - -/// Reference entry description paragraph. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Paragraph -{ - parts: Vec<ParagraphPart>, -} - -impl Paragraph -{ - /// Returns a new `Paragraph`. - pub fn new(parts: impl IntoIterator<Item = ParagraphPart>) -> Self - { - Self { - parts: parts.into_iter().collect(), - } - } - - /// Returns the parts of the paragraph. - #[must_use] - pub fn parts(&self) -> &[ParagraphPart] - { - &self.parts - } -} - -impl FromElements for Paragraph -{ - type Error = ParagraphError; - - fn from_elements(elements: &Elements) -> Result<Self, Self::Error> - { - let parts = elements - .into_iter() - .filter_map(|element| { - if matches!(element, Element::Comment(_)) { - return None; - } - - Some(ParagraphPart::from_elements(&Elements::from([ - element.clone() - ]))) - }) - .collect::<Result<Vec<_>, _>>()?; - - Ok(Self { parts }) - } -} - -/// [`Paragraph`] error. -#[derive(Debug, thiserror::Error)] -pub enum ParagraphError -{ - /// Invalid reference description part. - #[error("Invalid part")] - InvalidPart(#[from] ParagraphPartError), -} - -/// Reference entry description paragraph part. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ParagraphPart -{ - /// 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(Informal), - - /// Paragraph part. - Paragraph(Paragraph), - - /// Footnote part. - Footnote(Paragraph), - - /// Table part. - Table(Table), - - /// Informal equation part. - InformalEquation(String), - - /// Superscript part. - Superscript(String), -} - -impl FromElements for ParagraphPart -{ - type Error = ParagraphPartError; - - 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 ParagraphPart -{ - 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 = Informal::from_elements(tagged_element.child_elements()) - .map_err(|err| ParagraphPartError::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| ParagraphPartError::InvalidParagraph(Box::new(err)))?, - )); - } - - if tagged_element.name() == "footnote" { - return Ok(Self::Footnote( - Paragraph::from_elements(tagged_element.child_elements()) - .map_err(|err| ParagraphPartError::InvalidFootnote(Box::new(err)))?, - )); - } - - if tagged_element.name() == "table" { - let table = Table::from_elements(tagged_element.child_elements()) - .map_err(|err| ParagraphPartError::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())) - } -} - -/// [`ParagraphPart`] error. -#[derive(Debug, thiserror::Error)] -pub enum ParagraphPartError -{ - /// 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), -} - -/// Emphasis. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Emphasis -{ - /// The emphasised text. - pub text: String, - - /// Emphasis role. - pub role: EmphasisRole, -} - -impl Emphasis -{ - fn from_tagged_element(tagged_element: &Tagged) -> Result<Self, EmphasisError> - { - return Ok(Emphasis { - text: tagged_element - .child_elements() - .get_first_text_element() - .cloned() - .unwrap_or_default(), - role: tagged_element - .attributes() - .iter() - .find(|attr| attr.key == "role") - .map(|attr| { - let value = String::from_utf8(attr.value.clone()) - .map_err(|_| EmphasisError::EmphasisRoleNotUTF8)?; - - if value == "bold" { - return Ok(EmphasisRole::Bold); - } - - Err(EmphasisError::UnknownEmphasisRole(value)) - }) - .unwrap_or(Ok(EmphasisRole::None))?, - }); - } -} - -/// [`Emphasis`] error. -#[derive(Debug, thiserror::Error)] -pub enum EmphasisError -{ - /// Emphasis role is not valid UTF-8. - #[error("Emphasis role is not valid UTF-8")] - EmphasisRoleNotUTF8, - - /// Unknown emphasis role. - #[error("Unknown emphasis role '{0}'")] - UnknownEmphasisRole(String), -} - -/// Emphasis role. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum EmphasisRole -{ - /// Bold. - Bold, - - /// None. - None, -} |