pub struct Inventory {
pub items: Vec<Item>,
pub in_file_tests: BTreeMap<String, InFileTests>,
pub named_by_tests: BTreeSet<String>,
pub test_files: Vec<String>,
pub reexported: BTreeSet<String>,
pub reexport_aliases: BTreeMap<String, String>,
}Expand description
Everything the walk found: the items, the in-file tests per module, and what the crate’s integration tests name.
Fields§
§items: Vec<Item>Every item found, exported or not, in declaration order of the walk.
in_file_tests: BTreeMap<String, InFileTests>Module path to the in-file tests declared in that module’s file.
named_by_tests: BTreeSet<String>Module paths named by the crate’s integration tests and benches: every
majordomus_cli::a::b path those files mention, expanded to every prefix.
test_files: Vec<String>The test files that were read, crate-relative, so a report can say what it looked at.
reexported: BTreeSet<String>The crate paths a pub use in an exported module makes reachable, resolved to the
item they name. An item in a private module that a public module re-exports is part
of the crate’s surface, which is what missing_docs also thinks, so the inventory
has to think it too.
reexport_aliases: BTreeMap<String, String>The name a re-export offers an item under, mapped to the item it names:
majordomus_cli::capability::builtin::GetInput to
majordomus_cli::capability::builtin::objects::GetInput.
A consumer writes the alias, so a test that exercises a module through one would
otherwise look like a test that names no module at all. This is what carries the
credit back to the module that declares the item. pub use x as y offers y; a glob,
pub use m::*, offers every item of m in the re-exporting module and is recorded
as <module>::* to m.
The same map is where rustdoc documents a re-exported item whose own module is
private: under the alias, which is why the offered name is the one as chose.
Implementations§
Source§impl Inventory
impl Inventory
Sourcepub fn of_crate(crate_dir: &Path) -> Result<Self, Error>
pub fn of_crate(crate_dir: &Path) -> Result<Self, Error>
Walk a crate directory: src/lib.rs and every file its module graph reaches, then
tests/ and benches/ for the module paths they name.
The directory is the crate’s, the one holding Cargo.toml. A crate whose root is
missing is an error rather than an empty inventory: a quality report over nothing
is the one result that must never be mistaken for a clean one.
use majordomus_cli::quality::source::Inventory;
let dir = tempfile::tempdir().unwrap();
assert!(Inventory::of_crate(dir.path()).is_err(), "no crate root, no inventory");Sourcepub fn item(&self, path: &str) -> Option<&Item>
pub fn item(&self, path: &str) -> Option<&Item>
One item by its full path.
use majordomus_cli::quality::source::Inventory;
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(src.join("lib.rs"), "//! Root.\n/// A type.\npub struct T;\n").unwrap();
let inv = Inventory::of_crate(dir.path()).unwrap();
assert!(inv.item("majordomus_cli::T").is_some());
assert!(inv.item("majordomus_cli::Nope").is_none());Sourcepub fn item_of(&self, path: &str, kind: ItemKind) -> Option<&Item>
pub fn item_of(&self, path: &str, kind: ItemKind) -> Option<&Item>
One item by its path and its kind.
A struct’s field and one of its methods can share a path — T::n names both — because
Rust keeps them in different namespaces and a path does not say which. Every caller
that cares says so.
use majordomus_cli::quality::source::{Inventory, ItemKind};
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(src.join("lib.rs"), concat!(
"//! Root.\n",
"/// A counter.\n",
"pub struct T { n: usize }\n",
"impl T { /// The count.\n pub fn n(&self) -> usize { self.n } }\n",
)).unwrap();
let inv = Inventory::of_crate(dir.path()).unwrap();
let method = inv.item_of("majordomus_cli::T::n", ItemKind::Method).unwrap();
assert!(method.trivial_accessor);
assert!(inv.item_of("majordomus_cli::T::n", ItemKind::Field).is_some());Sourcepub fn exported(&self) -> Vec<&Item>
pub fn exported(&self) -> Vec<&Item>
Every exported item, in walk order.
use majordomus_cli::quality::source::Inventory;
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(&src).unwrap();
std::fs::write(src.join("lib.rs"), "//! Root.\nmod hidden;\n").unwrap();
std::fs::write(src.join("hidden.rs"), "/// Not reachable.\npub fn inner() {}\n").unwrap();
let inv = Inventory::of_crate(dir.path()).unwrap();
assert!(inv.item("majordomus_cli::hidden::inner").unwrap().exported == false);
assert!(inv.exported().iter().all(|i| i.path != "majordomus_cli::hidden::inner"));Sourcepub fn exercised_by_a_test(&self, path: &str) -> bool
pub fn exercised_by_a_test(&self, path: &str) -> bool
Does any test of this crate exercise the module at path?
A test counts when it names the module, names something under it, or names an item
through the alias a pub use offers it under — which is how these tests are actually
written: use majordomus_cli::capability::builtin::GetInput exercises
capability::builtin::objects, and nothing in the text says so.
use majordomus_cli::quality::source::Inventory;
let dir = tempfile::tempdir().unwrap();
let src = dir.path().join("src");
std::fs::create_dir_all(src.join("outer")).unwrap();
std::fs::write(src.join("lib.rs"), "//! Root.\npub mod outer;\n").unwrap();
std::fs::write(src.join("outer/mod.rs"),
"//! Outer.\npub mod inner;\npub use inner::Thing;\n").unwrap();
std::fs::write(src.join("outer/inner.rs"), "//! Inner.\n/// A thing.\npub struct Thing;\n").unwrap();
std::fs::create_dir_all(dir.path().join("tests")).unwrap();
std::fs::write(dir.path().join("tests/it.rs"),
"use majordomus_cli::outer::Thing;\n#[test]\nfn t() { let _ = Thing; }\n").unwrap();
let inv = Inventory::of_crate(dir.path()).unwrap();
assert!(inv.exercised_by_a_test("majordomus_cli::outer::inner"),
"the test reaches inner through the alias outer::Thing");Sourcepub fn exported_modules(&self) -> Vec<&Item>
pub fn exported_modules(&self) -> Vec<&Item>
Every exported module, in walk order. The crate root is one of them.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Inventory
impl<'de> Deserialize<'de> for Inventory
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for Inventory
Source§impl JsonSchema for Inventory
impl JsonSchema for Inventory
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn inline_schema() -> bool
fn inline_schema() -> bool
$ref keyword. Read moreimpl StructuralPartialEq for Inventory
Auto Trait Implementations§
impl Freeze for Inventory
impl RefUnwindSafe for Inventory
impl Send for Inventory
impl Sync for Inventory
impl Unpin for Inventory
impl UnsafeUnpin for Inventory
impl UnwindSafe for Inventory
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.