Add tag handler for collecting crate items from rustdoc output (#12903)

This PR adds a tag handler for collecting crate items from rustdoc's
HTML output.

This will serve as the foundation for getting more insight into a
crate's contents.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-06-11 15:56:37 -04:00 committed by GitHub
parent 57b87be3a0
commit 8ccd2a0c99
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 237 additions and 75 deletions

View file

@ -1,4 +1,6 @@
use std::cell::RefCell;
use std::collections::VecDeque;
use std::rc::Rc;
use std::sync::OnceLock;
use anyhow::Result;
@ -22,6 +24,8 @@ pub enum StartTagOutcome {
Skip,
}
pub type TagHandler = Rc<RefCell<dyn HandleTag>>;
pub struct MarkdownWriter {
current_element_stack: VecDeque<HtmlElement>,
pub(crate) markdown: String,
@ -60,12 +64,8 @@ impl MarkdownWriter {
self.push_str("\n\n");
}
pub fn run(
mut self,
root_node: &Handle,
mut handlers: Vec<Box<dyn HandleTag>>,
) -> Result<String> {
self.visit_node(&root_node, &mut handlers)?;
pub fn run(mut self, root_node: &Handle, handlers: &mut Vec<TagHandler>) -> Result<String> {
self.visit_node(&root_node, handlers)?;
Ok(Self::prettify_markdown(self.markdown))
}
@ -76,7 +76,7 @@ impl MarkdownWriter {
markdown.trim().to_string()
}
fn visit_node(&mut self, node: &Handle, handlers: &mut [Box<dyn HandleTag>]) -> Result<()> {
fn visit_node(&mut self, node: &Handle, handlers: &mut [TagHandler]) -> Result<()> {
let mut current_element = None;
match node.data {
@ -128,14 +128,10 @@ impl MarkdownWriter {
Ok(())
}
fn start_tag(
&mut self,
tag: &HtmlElement,
handlers: &mut [Box<dyn HandleTag>],
) -> StartTagOutcome {
fn start_tag(&mut self, tag: &HtmlElement, handlers: &mut [TagHandler]) -> StartTagOutcome {
for handler in handlers {
if handler.should_handle(tag.tag.as_str()) {
match handler.handle_tag_start(tag, self) {
if handler.borrow().should_handle(tag.tag.as_str()) {
match handler.borrow_mut().handle_tag_start(tag, self) {
StartTagOutcome::Continue => {}
StartTagOutcome::Skip => return StartTagOutcome::Skip,
}
@ -145,17 +141,17 @@ impl MarkdownWriter {
StartTagOutcome::Continue
}
fn end_tag(&mut self, tag: &HtmlElement, handlers: &mut [Box<dyn HandleTag>]) {
fn end_tag(&mut self, tag: &HtmlElement, handlers: &mut [TagHandler]) {
for handler in handlers {
if handler.should_handle(tag.tag.as_str()) {
handler.handle_tag_end(tag, self);
if handler.borrow().should_handle(tag.tag.as_str()) {
handler.borrow_mut().handle_tag_end(tag, self);
}
}
}
fn visit_text(&mut self, text: String, handlers: &mut [Box<dyn HandleTag>]) -> Result<()> {
fn visit_text(&mut self, text: String, handlers: &mut [TagHandler]) -> Result<()> {
for handler in handlers {
match handler.handle_text(&text, self) {
match handler.borrow_mut().handle_text(&text, self) {
HandlerOutcome::Handled => return Ok(()),
HandlerOutcome::NoOp => {}
}