#![doc = include_str!("../examples/list_public_api.rs")]
#![doc = include_str!("../examples/diff_public_api.rs")]
#![warn(clippy::all, clippy::pedantic, missing_docs)]
mod crate_wrapper;
mod error;
mod intermediate_public_item;
mod item_processor;
mod public_item;
mod render;
pub mod tokens;
pub mod diff;
use std::path::Path;
pub use error::{Error, Result};
pub use public_item::PublicItem;
pub const MINIMUM_NIGHTLY_VERSION: &str = "nightly-2023-01-04";
#[deprecated(since = "0.27.0", note = "Use MINIMUM_NIGHTLY_VERSION instead")]
pub const MINIMUM_RUSTDOC_JSON_VERSION: &str = MINIMUM_NIGHTLY_VERSION;
#[derive(Copy, Clone, Debug)]
#[non_exhaustive] #[allow(clippy::struct_excessive_bools)]
pub struct Options {
pub sorted: bool,
pub debug_sorting: bool,
pub omit_blanket_impls: bool,
pub omit_auto_trait_impls: bool,
pub omit_auto_derived_impls: bool,
}
impl Default for Options {
fn default() -> Self {
Self {
sorted: true,
debug_sorting: false,
omit_blanket_impls: false,
omit_auto_trait_impls: false,
omit_auto_derived_impls: false,
}
}
}
#[derive(Debug)]
#[non_exhaustive] pub struct PublicApi {
pub(crate) items: Vec<PublicItem>,
pub(crate) missing_item_ids: Vec<String>,
}
impl PublicApi {
pub fn from_rustdoc_json(path: impl AsRef<Path>, options: Options) -> Result<PublicApi> {
#[allow(deprecated)]
Self::from_rustdoc_json_str(std::fs::read_to_string(path)?, options)
}
#[deprecated(
since = "0.27.1",
note = "If you need this edge case API, you need to write your JSON to a temporary file and then use `PublicApi::from_rustdoc_json()` instead."
)]
pub fn from_rustdoc_json_str(
rustdoc_json_str: impl AsRef<str>,
options: Options,
) -> Result<PublicApi> {
let crate_ = deserialize_without_recursion_limit(rustdoc_json_str.as_ref())?;
let mut public_api = item_processor::public_api_in_crate(&crate_, options);
if options.sorted {
public_api.items.sort_by(PublicItem::grouping_cmp);
}
Ok(public_api)
}
pub fn items(&self) -> impl Iterator<Item = &'_ PublicItem> {
self.items.iter()
}
pub fn into_items(self) -> impl Iterator<Item = PublicItem> {
self.items.into_iter()
}
pub fn missing_item_ids(&self) -> impl Iterator<Item = &String> {
self.missing_item_ids.iter()
}
}
impl std::fmt::Display for PublicApi {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for item in self.items() {
writeln!(f, "{item}")?;
}
Ok(())
}
}
fn deserialize_without_recursion_limit(rustdoc_json_str: &str) -> Result<rustdoc_types::Crate> {
let mut deserializer = serde_json::Deserializer::from_str(rustdoc_json_str);
deserializer.disable_recursion_limit();
Ok(serde::de::Deserialize::deserialize(&mut deserializer)?)
}