List variants for enums
This patch updates parse_item_doc to look for variants.
This commit is contained in:
parent
958019449d
commit
8bfb7393e5
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -477,6 +477,7 @@ dependencies = [
|
|||||||
"anyhow 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
"anyhow 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html2text 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html2text 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"kuchiki 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"kuchiki 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"markup5ever 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pager 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pager 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -16,6 +16,7 @@ license = "MIT"
|
|||||||
anyhow = "1.0.31"
|
anyhow = "1.0.31"
|
||||||
html2text = "0.1.12"
|
html2text = "0.1.12"
|
||||||
kuchiki = "0.8.0"
|
kuchiki = "0.8.0"
|
||||||
|
markup5ever = "0.10.0"
|
||||||
pager = "0.15.0"
|
pager = "0.15.0"
|
||||||
serde_json = "1.0.56"
|
serde_json = "1.0.56"
|
||||||
serde_repr = "0.1.6"
|
serde_repr = "0.1.6"
|
||||||
|
31
src/doc.rs
31
src/doc.rs
@ -245,6 +245,37 @@ impl ItemType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn class(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
ItemType::Module => "module",
|
||||||
|
ItemType::ExternCrate => "extern-crate",
|
||||||
|
ItemType::Import => "import",
|
||||||
|
ItemType::Struct => "struct",
|
||||||
|
ItemType::Enum => "enum",
|
||||||
|
ItemType::Function => "function",
|
||||||
|
ItemType::Typedef => "typedef",
|
||||||
|
ItemType::Static => "static",
|
||||||
|
ItemType::Trait => "trait",
|
||||||
|
ItemType::Impl => "impl",
|
||||||
|
ItemType::TyMethod => "required-method",
|
||||||
|
ItemType::Method => "method",
|
||||||
|
ItemType::StructField => "field",
|
||||||
|
ItemType::Variant => "variant",
|
||||||
|
ItemType::Macro => "macro",
|
||||||
|
ItemType::Primitive => "primitive",
|
||||||
|
ItemType::AssocType => "associated-type",
|
||||||
|
ItemType::Constant => "constant",
|
||||||
|
ItemType::AssocConst => "associated-const",
|
||||||
|
ItemType::Union => "union",
|
||||||
|
ItemType::ForeignType => "foreign-type",
|
||||||
|
ItemType::Keyword => "keyword",
|
||||||
|
ItemType::OpaqueTy => "opaque-type",
|
||||||
|
ItemType::ProcAttribute => "proc-attribute",
|
||||||
|
ItemType::ProcDerive => "proc-derive",
|
||||||
|
ItemType::TraitAlias => "trait-alias",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn group_name(&self) -> &str {
|
pub fn group_name(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
ItemType::Module => "Modules",
|
ItemType::Module => "Modules",
|
||||||
|
@ -47,7 +47,7 @@ pub fn find_member<P: AsRef<path::Path>>(
|
|||||||
.as_node()
|
.as_node()
|
||||||
.parent()
|
.parent()
|
||||||
.context("Member element does not have a parent")?;
|
.context("Member element does not have a parent")?;
|
||||||
if let Some(parent_id) = get_attribute(parent.as_element().unwrap(), "id") {
|
if let Some(parent_id) = get_node_attribute(&parent, "id") {
|
||||||
let item_type: doc::ItemType = parent_id.splitn(2, '.').next().unwrap().parse()?;
|
let item_type: doc::ItemType = parent_id.splitn(2, '.').next().unwrap().parse()?;
|
||||||
return Ok(Some(doc::Item::new(
|
return Ok(Some(doc::Item::new(
|
||||||
name.clone(),
|
name.clone(),
|
||||||
@ -84,6 +84,12 @@ pub fn parse_item_doc(item: &doc::Item) -> anyhow::Result<doc::Doc> {
|
|||||||
let mut doc = doc::Doc::new(item.name.clone(), item.ty);
|
let mut doc = doc::Doc::new(item.name.clone(), item.ty);
|
||||||
doc.description = description.map(|n| get_html(n.as_node())).transpose()?;
|
doc.description = description.map(|n| get_html(n.as_node())).transpose()?;
|
||||||
doc.definition = definition.map(|n| get_html(n.as_node())).transpose()?;
|
doc.definition = definition.map(|n| get_html(n.as_node())).transpose()?;
|
||||||
|
|
||||||
|
let (ty, groups) = get_variants(&document, item)?;
|
||||||
|
if !groups.is_empty() {
|
||||||
|
doc.groups.push((ty, groups));
|
||||||
|
}
|
||||||
|
|
||||||
Ok(doc)
|
Ok(doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,6 +141,52 @@ pub fn parse_member_doc(item: &doc::Item) -> anyhow::Result<doc::Doc> {
|
|||||||
Ok(doc)
|
Ok(doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_variants(
|
||||||
|
document: &kuchiki::NodeRef,
|
||||||
|
parent: &doc::Item,
|
||||||
|
) -> anyhow::Result<(doc::ItemType, Vec<doc::MemberGroup>)> {
|
||||||
|
let ty = doc::ItemType::Variant;
|
||||||
|
let mut variants: Vec<doc::Doc> = Vec::new();
|
||||||
|
let heading = select_first(document, &format!("#{}", ty.group_id()))?;
|
||||||
|
|
||||||
|
let mut next = heading.and_then(|n| next_sibling_element(n.as_node()));
|
||||||
|
let mut name: Option<String> = None;
|
||||||
|
while let Some(element) = &next {
|
||||||
|
if is_element(element, markup5ever::local_name!("div")) {
|
||||||
|
if has_class(element, ty.class()) {
|
||||||
|
if let Some(name) = &name {
|
||||||
|
variants.push(doc::Doc::new(parent.name.child(name), ty));
|
||||||
|
}
|
||||||
|
name = get_node_attribute(element, "id")
|
||||||
|
.and_then(|s| s.splitn(2, '.').nth(1).map(ToOwned::to_owned));
|
||||||
|
} else if has_class(element, "docblock") {
|
||||||
|
if let Some(name) = &name {
|
||||||
|
let mut doc = doc::Doc::new(parent.name.child(name), ty);
|
||||||
|
// TODO: use inner_html() instead
|
||||||
|
doc.description = Some(element.text_contents());
|
||||||
|
variants.push(doc);
|
||||||
|
}
|
||||||
|
name = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
next = element.next_sibling();
|
||||||
|
} else {
|
||||||
|
if let Some(name) = &name {
|
||||||
|
variants.push(doc::Doc::new(parent.name.child(name), ty));
|
||||||
|
}
|
||||||
|
next = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut groups: Vec<doc::MemberGroup> = Vec::new();
|
||||||
|
if !variants.is_empty() {
|
||||||
|
let mut group = doc::MemberGroup::new();
|
||||||
|
group.members = variants;
|
||||||
|
groups.push(group);
|
||||||
|
}
|
||||||
|
Ok((ty, groups))
|
||||||
|
}
|
||||||
|
|
||||||
fn get_members(
|
fn get_members(
|
||||||
document: &kuchiki::NodeRef,
|
document: &kuchiki::NodeRef,
|
||||||
parent: &doc::Item,
|
parent: &doc::Item,
|
||||||
@ -168,6 +220,34 @@ fn get_attribute(element: &kuchiki::ElementData, name: &str) -> Option<String> {
|
|||||||
element.attributes.borrow().get(name).map(ToOwned::to_owned)
|
element.attributes.borrow().get(name).map(ToOwned::to_owned)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_node_attribute(node: &kuchiki::NodeRef, name: &str) -> Option<String> {
|
||||||
|
node.as_element().and_then(|e| get_attribute(e, name))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_sibling_element(node: &kuchiki::NodeRef) -> Option<kuchiki::NodeRef> {
|
||||||
|
let mut next = node.next_sibling();
|
||||||
|
while let Some(node) = &next {
|
||||||
|
if node.as_element().is_some() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next = node.next_sibling();
|
||||||
|
}
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_element(node: &kuchiki::NodeRef, name: markup5ever::LocalName) -> bool {
|
||||||
|
node.as_element()
|
||||||
|
.map(|e| e.name.local == name)
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_class(node: &kuchiki::NodeRef, class: &str) -> bool {
|
||||||
|
node.as_element()
|
||||||
|
.and_then(|e| get_attribute(&e, "class"))
|
||||||
|
.map(|a| a.split(' ').any(|s| s == class))
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
fn get_html(node: &kuchiki::NodeRef) -> anyhow::Result<String> {
|
fn get_html(node: &kuchiki::NodeRef) -> anyhow::Result<String> {
|
||||||
let mut vec: Vec<u8> = Vec::new();
|
let mut vec: Vec<u8> = Vec::new();
|
||||||
node.serialize(&mut vec)?;
|
node.serialize(&mut vec)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user