summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-03-04 13:18:33 +0100
committerHampusM <hampus@hampusmat.com>2023-03-04 13:18:33 +0100
commita15a878b87a4891ec856178c151faeaaa1799ad3 (patch)
tree8b72271476e8b4ca0cc89703d89ec736cd6febb8
parentf576587f8b872b6369c7079055944977f2293e5c (diff)
feat: add table support
-rw-r--r--src/description.rs53
-rw-r--r--src/lib.rs2
-rw-r--r--src/table.rs (renamed from src/informal_table.rs)119
3 files changed, 125 insertions, 49 deletions
diff --git a/src/description.rs b/src/description.rs
index e6cd1cd..615b0c2 100644
--- a/src/description.rs
+++ b/src/description.rs
@@ -1,6 +1,6 @@
//! Reference entry description.
-use crate::informal_table::{Error as InformalTableError, InformalTable};
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};
@@ -97,7 +97,7 @@ impl FromElements for Description
.unwrap_or_default(),
))),
"informaltable" => Some(
- InformalTable::from_elements(part_elem.child_elements())
+ Informal::from_elements(part_elem.child_elements())
.map(Part::InformalTable)
.map_err(Self::Error::InvalidInformalTable),
),
@@ -106,6 +106,11 @@ impl FromElements for Description
.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),
+ ),
"title" => None,
name => Some(Err(Self::Error::UnknownPartFound(name.to_string()))),
})
@@ -136,11 +141,15 @@ pub enum Error
/// Invalid informal table.
#[error("Invalid informal table")]
- InvalidInformalTable(#[source] InformalTableError),
+ InvalidInformalTable(#[source] TableError),
/// Invalid itemized list.
#[error("Invalid itemized list")]
InvalidItemizedList(#[source] ItemizedListError),
+
+ /// Invalid table.
+ #[error("Invalid table")]
+ InvalidTable(#[source] TableError),
}
/// Description part.
@@ -157,10 +166,13 @@ pub enum Part
ProgramListing(String),
/// Informal table.
- InformalTable(InformalTable),
+ InformalTable(Informal),
/// Itemized list.
ItemizedList(ItemizedList),
+
+ /// Table.
+ Table(Table),
}
/// Reference entry description paragraph.
@@ -258,13 +270,16 @@ pub enum ParagraphPart
ItemizedList(ItemizedList),
/// Informal table part.
- InformalTable(InformalTable),
+ InformalTable(Informal),
/// Paragraph part.
Paragraph(Paragraph),
/// Footnote part.
Footnote(Paragraph),
+
+ /// Table part.
+ Table(Table),
}
impl FromElements for ParagraphPart
@@ -300,11 +315,10 @@ impl ParagraphPart
"inlineequation" => Self::InlineEquation,
"programlisting" => Self::ProgramListing,
"citerefentry" => Self::Entry,
- "variablelist" | "itemizedlist" | "informaltable" | "para" | "footnote" => {
- |_| {
- unreachable!();
- }
- }
+ "variablelist" | "itemizedlist" | "informaltable" | "para" | "footnote"
+ | "table" => |_| {
+ unreachable!();
+ },
_ => {
return Err(<Self as FromElements>::Error::UnknownPart(
tagged_element.name().to_string(),
@@ -341,10 +355,8 @@ impl ParagraphPart
}
if tagged_element.name() == "informaltable" {
- let informal_table = InformalTable::from_elements(
- tagged_element.child_elements(),
- )
- .map_err(|err| ParagraphPartError::InvalidInformalTable(Box::new(err)))?;
+ let informal_table = Informal::from_elements(tagged_element.child_elements())
+ .map_err(|err| ParagraphPartError::InvalidInformalTable(Box::new(err)))?;
return Ok(Self::InformalTable(informal_table));
}
@@ -373,6 +385,13 @@ impl ParagraphPart
));
}
+ 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));
+ }
+
let text_element = tagged_element
.child_elements()
.get_first_text_element()
@@ -412,7 +431,7 @@ pub enum ParagraphPartError
/// Invalid informal table.
#[error("Invalid informal table")]
- InvalidInformalTable(#[source] Box<InformalTableError>),
+ InvalidInformalTable(#[source] Box<TableError>),
/// Invalid paragraph.
#[error("Invalid paragraph")]
@@ -421,4 +440,8 @@ pub enum ParagraphPartError
/// Invalid footnote.
#[error("Invalid footnote")]
InvalidFootnote(#[source] Box<ParagraphError>),
+
+ /// Invalid table.
+ #[error("Invalid table")]
+ InvalidTable(#[source] Box<TableError>),
}
diff --git a/src/lib.rs b/src/lib.rs
index f1e15cb..c02716f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,8 +14,8 @@ use crate::xml::element::{Elements, FromElements};
use crate::xml::parser::{Error as ParserError, Parser};
pub mod description;
-pub mod informal_table;
pub mod itemized_list;
+pub mod table;
pub mod variable_list;
mod xml;
diff --git a/src/informal_table.rs b/src/table.rs
index a940de4..b549b95 100644
--- a/src/informal_table.rs
+++ b/src/table.rs
@@ -1,25 +1,25 @@
-//! Informal table.
+//! Tables.
use crate::description::{Paragraph, ParagraphError};
use crate::xml::element::{Elements, FromElements, Tagged};
/// Informal table.
#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct InformalTable
+pub struct Informal
{
- groups: Vec<TableGroup>,
+ groups: Vec<Group>,
}
-impl InformalTable
+impl Informal
{
/// Returns the table groups.
#[must_use]
- pub fn groups(&self) -> &[TableGroup]
+ pub fn groups(&self) -> &[Group]
{
&self.groups
}
}
-impl FromElements for InformalTable
+impl FromElements for Informal
{
type Error = Error;
@@ -28,34 +28,87 @@ impl FromElements for InformalTable
let groups = elements
.get_all_tagged_elements_with_name("tgroup")
.into_iter()
- .map(TableGroup::from_tagged_element)
+ .map(Group::from_tagged_element)
.collect::<Result<Vec<_>, _>>()?;
Ok(Self { groups })
}
}
-/// [`InformalTable`] error.
+/// Table.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct Table
+{
+ title: String,
+ groups: Vec<Group>,
+}
+
+impl Table
+{
+ /// Returns the table title.
+ #[must_use]
+ pub fn title(&self) -> &str
+ {
+ &self.title
+ }
+
+ /// Returns the table groups.
+ #[must_use]
+ pub fn groups(&self) -> &[Group]
+ {
+ &self.groups
+ }
+}
+
+impl FromElements for Table
+{
+ type Error = Error;
+
+ fn from_elements(elements: &Elements) -> Result<Self, Self::Error>
+ {
+ let title = elements
+ .get_first_tagged_with_name("title")
+ .ok_or(Self::Error::MissingTitle)?
+ .child_elements()
+ .get_first_text_element()
+ .cloned()
+ .unwrap_or_default();
+
+ let groups = elements
+ .get_all_tagged_elements_with_name("tgroup")
+ .into_iter()
+ .map(Group::from_tagged_element)
+ .collect::<Result<Vec<_>, _>>()?;
+
+ Ok(Self { title, groups })
+ }
+}
+
+/// Table error.
#[derive(Debug, thiserror::Error)]
pub enum Error
{
/// Invalid group.
#[error("Invalid group")]
- InvalidGroup(#[from] TableGroupError),
+ InvalidGroup(#[from] GroupError),
+
+ /// Missing title.
+ #[error("Missing title")]
+ MissingTitle,
}
/// Table group
#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct TableGroup
+pub struct Group
{
cols: u32,
align: Option<String>,
column_specs: Vec<ColumnSpec>,
- head: Vec<TableRow>,
- body: Vec<TableRow>,
+ head: Vec<Row>,
+ body: Vec<Row>,
}
-impl TableGroup
+impl Group
{
/// Returns the column count.
#[must_use]
@@ -80,40 +133,40 @@ impl TableGroup
/// Returns the head.
#[must_use]
- pub fn head(&self) -> &[TableRow]
+ pub fn head(&self) -> &[Row]
{
&self.head
}
/// Returns the body.
#[must_use]
- pub fn body(&self) -> &[TableRow]
+ pub fn body(&self) -> &[Row]
{
&self.body
}
}
-impl TableGroup
+impl Group
{
- fn from_tagged_element(element: &Tagged) -> Result<Self, TableGroupError>
+ fn from_tagged_element(element: &Tagged) -> Result<Self, GroupError>
{
let cols = String::from_utf8(
element
.attributes()
.iter()
.find(|attr| attr.key == "cols")
- .ok_or(TableGroupError::MissingCols)?
+ .ok_or(GroupError::MissingCols)?
.value
.clone(),
)
- .map_err(|_| TableGroupError::ColsNotUTF8)?
+ .map_err(|_| GroupError::ColsNotUTF8)?
.parse::<u32>()
- .map_err(|_| TableGroupError::ColsNotNumber)?;
+ .map_err(|_| GroupError::ColsNotNumber)?;
let align = match element.attributes().iter().find(|attr| attr.key == "align") {
Some(attr) => Some(
String::from_utf8(attr.value.clone())
- .map_err(|_| TableGroupError::AlignNotUTF8)?,
+ .map_err(|_| GroupError::AlignNotUTF8)?,
),
None => None,
};
@@ -130,11 +183,11 @@ impl TableGroup
let mut body = element
.child_elements()
.get_first_tagged_with_name("tbody")
- .ok_or(TableGroupError::MissingBody)?
+ .ok_or(GroupError::MissingBody)?
.child_elements()
.get_all_tagged_elements_with_name("row")
.into_iter()
- .map(|row_element| TableRow::from_elements(row_element.child_elements()))
+ .map(|row_element| Row::from_elements(row_element.child_elements()))
.collect::<Result<Vec<_>, _>>()?;
let head = element
@@ -148,7 +201,7 @@ impl TableGroup
.get_all_tagged_elements_with_name("row")
.into_iter()
.map(|row_element| {
- TableRow::from_elements(row_element.child_elements())
+ Row::from_elements(row_element.child_elements())
})
.collect::<Result<Vec<_>, _>>()
},
@@ -164,9 +217,9 @@ impl TableGroup
}
}
-/// [`TableGroup`] error.
+/// [`Group`] error.
#[derive(Debug, thiserror::Error)]
-pub enum TableGroupError
+pub enum GroupError
{
/// Missing cols element attribute.
#[error("Missing cols")]
@@ -182,7 +235,7 @@ pub enum TableGroupError
/// Invalid row.
#[error("Invalid row")]
- InvalidRow(#[from] TableRowError),
+ InvalidRow(#[from] RowError),
/// Cols is not valid UTF-8.
#[error("Cols is not valid UTF-8")]
@@ -302,12 +355,12 @@ pub enum ColumnSpecError
/// Table row.
#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct TableRow
+pub struct Row
{
entries: Vec<Paragraph>,
}
-impl TableRow
+impl Row
{
/// Returns the entries.
#[must_use]
@@ -317,9 +370,9 @@ impl TableRow
}
}
-impl FromElements for TableRow
+impl FromElements for Row
{
- type Error = TableRowError;
+ type Error = RowError;
fn from_elements(elements: &Elements) -> Result<Self, Self::Error>
{
@@ -333,9 +386,9 @@ impl FromElements for TableRow
}
}
-/// [`TableRow`] error.
+/// [`Row`] error.
#[derive(Debug, thiserror::Error)]
-pub enum TableRowError
+pub enum RowError
{
/// Invalid paragraph.
#[error("Invalid paragraph")]