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)",
|
||||
"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)",
|
||||
"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)",
|
||||
"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)",
|
||||
|
@ -16,6 +16,7 @@ license = "MIT"
|
||||
anyhow = "1.0.31"
|
||||
html2text = "0.1.12"
|
||||
kuchiki = "0.8.0"
|
||||
markup5ever = "0.10.0"
|
||||
pager = "0.15.0"
|
||||
serde_json = "1.0.56"
|
||||
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 {
|
||||
match self {
|
||||
ItemType::Module => "Modules",
|
||||
|
@ -47,7 +47,7 @@ pub fn find_member<P: AsRef<path::Path>>(
|
||||
.as_node()
|
||||
.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()?;
|
||||
return Ok(Some(doc::Item::new(
|
||||
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);
|
||||
doc.description = description.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)
|
||||
}
|
||||
|
||||
@ -135,6 +141,52 @@ pub fn parse_member_doc(item: &doc::Item) -> anyhow::Result<doc::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(
|
||||
document: &kuchiki::NodeRef,
|
||||
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)
|
||||
}
|
||||
|
||||
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> {
|
||||
let mut vec: Vec<u8> = Vec::new();
|
||||
node.serialize(&mut vec)?;
|
||||
|
Loading…
Reference in New Issue
Block a user