summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-02-26 14:45:20 +0100
committerHampusM <hampus@hampusmat.com>2023-02-26 14:45:20 +0100
commit5ab5fafd8f3cab7f82c11e7ad89f8fefd66e911c (patch)
tree221f9a936320a894ec5706ce7a8720648e8fe497 /src
parent2d633644a53dfe278b681a911b2eaea1230a07cc (diff)
feat: add multiple description support
Diffstat (limited to 'src')
-rw-r--r--src/description.rs41
-rw-r--r--src/lib.rs46
-rw-r--r--src/xml/element.rs40
3 files changed, 84 insertions, 43 deletions
diff --git a/src/description.rs b/src/description.rs
index f536b4f..ccd95b2 100644
--- a/src/description.rs
+++ b/src/description.rs
@@ -7,16 +7,27 @@ use crate::xml::element::{Elements, FromElements, Tagged};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Description
{
+ for_function: Option<String>,
parts: Vec<Part>,
}
impl Description
{
- /// Returns a new `ReferenceDescription`.
+ /// Returns a new empty `Description`.
#[must_use]
pub fn new() -> Self
{
- Self { parts: Vec::new() }
+ 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.
@@ -41,6 +52,27 @@ impl FromElements for Description
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()
@@ -61,7 +93,10 @@ impl FromElements for Description
})
.collect::<Result<Vec<_>, Self::Error>>()?;
- Ok(Description { parts })
+ Ok(Description {
+ for_function,
+ parts,
+ })
}
}
diff --git a/src/lib.rs b/src/lib.rs
index c0a300b..7a715f1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -10,7 +10,7 @@ use std::os::unix::prelude::OsStrExt;
use include_dir::{include_dir, Dir};
use crate::description::{Description, Error as DescriptionError};
-use crate::xml::element::{Attribute, Elements, FromElements};
+use crate::xml::element::{Elements, FromElements};
use crate::xml::parser::{Error as ParserError, Parser};
pub mod description;
@@ -26,17 +26,20 @@ static GL4_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/OpenGL-Refpages/gl4");
pub struct ReferenceEntry
{
purpose: String,
- description: Description,
+ descriptions: Vec<Description>,
}
impl ReferenceEntry
{
/// Returns a new `ReferenceEntry`.
- pub fn new(purpose: &impl ToString, description: Description) -> Self
+ pub fn new(
+ purpose: &impl ToString,
+ descriptions: impl IntoIterator<Item = Description>,
+ ) -> Self
{
Self {
purpose: purpose.to_string(),
- description,
+ descriptions: descriptions.into_iter().collect(),
}
}
@@ -106,11 +109,11 @@ impl ReferenceEntry
&self.purpose
}
- /// Returns the reference entry description.
+ /// Returns the reference entry descriptions.
#[must_use]
- pub fn description(&self) -> &Description
+ pub fn descriptions(&self) -> &[Description]
{
- &self.description
+ &self.descriptions
}
}
@@ -140,23 +143,26 @@ impl FromElements for ReferenceEntry
.cloned()
.unwrap_or_default();
- let description_refsect = refentry_element
+ let description_elements = refentry_element
.child_elements()
- .get_first_tagged_with_name_and_attr(
- "refsect1",
- &Attribute {
- key: "xml:id".to_string(),
- value: b"description".to_vec(),
- },
- )
- .ok_or(Self::Error::MissingDescriptionRefSect)?;
-
- let description =
- Description::from_elements(description_refsect.child_elements())?;
+ .get_all_tagged_with_name_and_attr("refsect1", |attr| {
+ attr.key == "xml:id" && attr.value.starts_with(b"description")
+ });
+
+ if description_elements.is_empty() {
+ return Err(Self::Error::MissingDescriptionRefSect);
+ }
+
+ let descriptions = description_elements
+ .iter()
+ .map(|description_element| {
+ Description::from_elements(description_element.child_elements())
+ })
+ .collect::<Result<Vec<_>, _>>()?;
Ok(ReferenceEntry {
purpose,
- description,
+ descriptions,
})
}
}
diff --git a/src/xml/element.rs b/src/xml/element.rs
index b778dac..91e4130 100644
--- a/src/xml/element.rs
+++ b/src/xml/element.rs
@@ -24,26 +24,6 @@ impl Elements
})
}
- pub fn get_first_tagged_with_name_and_attr(
- &self,
- tag_name: &str,
- attribute: &Attribute,
- ) -> Option<&Tagged>
- {
- self.elements.iter().find_map(|element| match element {
- Element::Tagged(tagged_element)
- if tagged_element.name == tag_name
- && tagged_element
- .attributes
- .iter()
- .any(|attr| attr == attribute) =>
- {
- Some(tagged_element)
- }
- _ => None,
- })
- }
-
pub fn get_all_tagged_elements(&self) -> Vec<&Tagged>
{
self.elements
@@ -68,6 +48,26 @@ impl Elements
.collect()
}
+ pub fn get_all_tagged_with_name_and_attr(
+ &self,
+ tag_name: &str,
+ attr_is_match: fn(&Attribute) -> bool,
+ ) -> Vec<&Tagged>
+ {
+ self.elements
+ .iter()
+ .filter_map(|element| match element {
+ Element::Tagged(tagged_element)
+ if tagged_element.name == tag_name
+ && tagged_element.attributes.iter().any(attr_is_match) =>
+ {
+ Some(tagged_element)
+ }
+ _ => None,
+ })
+ .collect()
+ }
+
pub fn get_first_text_element(&self) -> Option<&String>
{
self.elements.iter().find_map(|element| match element {