#![warn(missing_docs)]
use std::path::{Path, PathBuf};
pub mod config;
pub mod error;
pub mod generate;
pub mod index;
pub mod lint;
pub mod platform;
mod rustdoc;
pub use config::{Config, Platform, Preset, UnknownPlatform};
pub use error::{Error, Result};
pub use generate::{Artifact, ArtifactLocation};
pub use index::{IndexedCrate, IndexedWorkspace};
pub use lint::{Diagnostic, Level};
#[derive(Debug, Clone)]
pub struct Report {
pub artifacts: Vec<Artifact>,
pub diagnostics: Vec<Diagnostic>,
}
impl Report {
pub fn has_errors(&self) -> bool {
self.diagnostics
.iter()
.any(|d| matches!(d.level, Level::Error))
}
}
pub fn run(workspace_root: &Path, config: &Config) -> Result<Report> {
let workspace = IndexedWorkspace::build(workspace_root, config)?;
let index_summary = format!("indexed {} crate(s)", workspace.crates.len());
let mut artifacts =
generate::render_all(&workspace, None).map_err(|source| Error::Generate {
source: Box::new(source),
index_summary,
})?;
platform::apply_overlays(&workspace, &mut artifacts, &config.platforms)?;
let diagnostics = lint::lint(&workspace, &artifacts, config);
Ok(Report {
artifacts,
diagnostics,
})
}
fn resolve_path(artifact: &Artifact, out_dir: &Path, workspace_root: &Path) -> PathBuf {
let base = match artifact.location {
ArtifactLocation::OutDir => out_dir,
ArtifactLocation::WorkspaceRoot => workspace_root,
};
base.join(&artifact.path)
}
pub fn write_report(report: &Report, out_dir: &Path, workspace_root: &Path) -> Result<()> {
for artifact in &report.artifacts {
let path = resolve_path(artifact, out_dir, workspace_root);
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(&path, artifact.body.as_bytes())?;
}
Ok(())
}
pub fn diff_report(report: &Report, out_dir: &Path, workspace_root: &Path) -> Result<Vec<String>> {
let mut diffs = Vec::new();
for artifact in &report.artifacts {
let path = resolve_path(artifact, out_dir, workspace_root);
match std::fs::read(&path) {
Ok(bytes) => {
if bytes != artifact.body.as_bytes() {
diffs.push(artifact.path.clone());
}
}
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
diffs.push(artifact.path.clone());
}
Err(err) => return Err(err.into()),
}
}
Ok(diffs)
}