~ireas/rustdoc-parser-rs

a63a9e07e271c03b452d856f9dcc7d1ed554ddda — Robin Krahl 6 months ago d20132a
Add modules function to Crate

This patch adds the module function to the Crate trait that lists all
modules in a crate.
M src/html.rs => src/html.rs +24 -1
@@ 44,7 44,7 @@ mod util;

use std::{convert::TryFrom, error, fmt, fs, io, path};

use crate::{Error, Ident, Item};
use crate::{Error, Fqn, Ident, Item};

/// A parser for HTML documentation generated by rustdoc.
///


@@ 143,6 143,29 @@ impl crate::Crate for Crate {
    fn items(&self) -> Result<Vec<Item>, Error> {
        Document::from_file(self.path.join("all.html"))?.parse_crate_index(self.ident.clone())
    }

    fn modules(&self) -> Result<Vec<Fqn>, Error> {
        let root = Fqn::from(self.ident.clone());
        let mut modules = Vec::new();
        extend_modules(&mut modules, &root, &self.path)?;
        modules.push(root);
        Ok(modules)
    }
}

fn extend_modules(modules: &mut Vec<Fqn>, parent: &Fqn, path: &path::Path) -> Result<(), Error> {
    for entry in fs::read_dir(&path)? {
        let entry = entry?;
        let path = entry.path();
        if path.is_dir() && path.join("index.html").is_file() {
            if let Some(s) = entry.file_name().to_str() {
                let fqn = parent.clone().child(s.parse()?);
                extend_modules(modules, &fqn, &path)?;
                modules.push(fqn);
            }
        }
    }
    Ok(())
}

/// An HTML document.

M src/json.rs => src/json.rs +10 -0
@@ 213,6 213,16 @@ impl crate::Crate for Crate {
            .map(|item| self.item(&item.id))
            .collect()
    }

    fn modules(&self) -> Result<Vec<Fqn>, Error> {
        self.krate
            .index
            .values()
            .filter(|item| item.crate_id == 0)
            .filter(|item| item.ty() == ItemType::Module)
            .map(|item| self.fqn(item))
            .collect()
    }
}

impl TryFrom<model::Crate> for Crate {

M src/model.rs => src/model.rs +17 -1
@@ 57,7 57,7 @@ pub trait Crate: fmt::Debug {
    /// ```no_run
    /// let dir = rustdoc_parser::Dir::open("target/doc");
    /// for krate in dir.list_crates().expect("failed to list crates") {
    ///     println!("{}:", krate);
    ///     println!("{} items:", krate);
    ///     let krate = dir.open_crate(krate).expect("failed to open crate documentation");
    ///     for item in krate.items().unwrap() {
    ///         println!("- {}", item.fqn);


@@ 65,6 65,22 @@ pub trait Crate: fmt::Debug {
    /// }
    /// ```
    fn items(&self) -> Result<Vec<Item>, Error>;

    /// Lists the modules in this crate.
    ///
    /// # Example
    ///
    /// ```no_run
    /// let dir = rustdoc_parser::Dir::open("target/doc");
    /// for krate in dir.list_crates().expect("failed to list crates") {
    ///     println!("{} modules:", krate);
    ///     let krate = dir.open_crate(krate).expect("failed to open crate documentation");
    ///     for module in krate.modules().unwrap() {
    ///         println!("- {}", module);
    ///     }
    /// }
    /// ```
    fn modules(&self) -> Result<Vec<Fqn>, Error>;
}

/// A Rust item.

M tests/parser.rs => tests/parser.rs +9 -0
@@ 57,3 57,12 @@ fn test_items() {
        insta::assert_debug_snapshot!(format!("items__{}", krate.ident()), items);
    });
}

#[test]
fn test_modules() {
    test_with_crates(&["anyhow", "log", "rand_core"], |krate| {
        let mut modules = krate.modules().unwrap();
        modules.sort();
        insta::assert_debug_snapshot!(format!("modules__{}", krate.ident()), modules);
    });
}

A tests/snapshots/parser__modules__anyhow.snap => tests/snapshots/parser__modules__anyhow.snap +8 -0
@@ 0,0 1,8 @@
---
source: tests/parser.rs
expression: modules

---
[
    Fqn("anyhow"),
]

A tests/snapshots/parser__modules__log.snap => tests/snapshots/parser__modules__log.snap +8 -0
@@ 0,0 1,8 @@
---
source: tests/parser.rs
expression: modules

---
[
    Fqn("log"),
]

A tests/snapshots/parser__modules__rand_core.snap => tests/snapshots/parser__modules__rand_core.snap +11 -0
@@ 0,0 1,11 @@
---
source: tests/parser.rs
expression: modules

---
[
    Fqn("rand_core"),
    Fqn("rand_core::block"),
    Fqn("rand_core::impls"),
    Fqn("rand_core::le"),
]