#![deny(missing_docs)]
use std::path::Path;
use serde_json::Value;
pub use xuanji::{
Baseline, BoundaryKind, Outcome, Polarity, Report, Severity, Violation, ViolationId,
apply_baseline,
};
mod dsl;
pub use dsl::*;
mod rules;
pub use rules::*;
mod collect;
mod containment;
mod crate_scope;
mod driver;
mod emit;
mod errors;
mod file_scope;
mod finding;
mod module_resolve;
mod resolve;
mod scan;
mod syn_util;
mod async_exposure;
mod dyn_trait;
mod exposure;
mod forbidden_marker;
mod impl_trait;
mod trait_impl;
mod visibility;
pub use async_exposure::check_async_exposure;
pub use dyn_trait::check_dyn_trait;
pub use exposure::check;
pub use forbidden_marker::check_forbidden_marker;
pub use impl_trait::check_impl_trait;
pub use trait_impl::check_trait_impl_locality;
pub use visibility::check_visibility;
#[cfg(test)]
pub(crate) use async_exposure::async_exposure_module_findings;
#[cfg(test)]
pub(crate) use dyn_trait::{dyn_module_findings, dyn_operand_module_findings};
#[cfg(test)]
pub(crate) use exposure::module_findings;
#[cfg(test)]
pub(crate) use forbidden_marker::forbidden_marker_findings;
#[cfg(test)]
pub(crate) use impl_trait::{impl_trait_module_findings, impl_trait_operand_module_findings};
#[cfg(test)]
pub(crate) use trait_impl::trait_impl_findings;
#[cfg(test)]
pub(crate) use visibility::visibility_findings;
use crate::async_exposure::check_async_exposure_boundary;
use crate::driver::{eval_into, outcome_from, read_metadata};
use crate::dyn_trait::check_dyn_trait_boundary;
use crate::exposure::check_boundary;
use crate::forbidden_marker::check_forbidden_marker_boundary;
use crate::impl_trait::check_impl_trait_boundary;
use crate::trait_impl::check_trait_impl_boundary;
use crate::visibility::check_visibility_boundary;
#[derive(Debug, Clone, Default)]
pub struct SemanticBoundaries {
pub signature: Vec<SemanticBoundary>,
pub trait_impl: Vec<TraitImplBoundary>,
pub visibility: Vec<VisibilityBoundary>,
pub forbidden_marker: Vec<ForbiddenMarkerBoundary>,
pub dyn_trait: Vec<DynTraitBoundary>,
pub impl_trait: Vec<ImplTraitBoundary>,
pub async_exposure: Vec<AsyncExposureBoundary>,
}
impl SemanticBoundaries {
pub fn is_empty(&self) -> bool {
self.signature.is_empty()
&& self.trait_impl.is_empty()
&& self.visibility.is_empty()
&& self.forbidden_marker.is_empty()
&& self.dyn_trait.is_empty()
&& self.impl_trait.is_empty()
&& self.async_exposure.is_empty()
}
}
fn eval_all(
metadata: &Value,
boundaries: &SemanticBoundaries,
violations: &mut Vec<Violation>,
) -> Result<(), String> {
eval_into(metadata, &boundaries.signature, check_boundary, violations)?;
eval_into(
metadata,
&boundaries.trait_impl,
check_trait_impl_boundary,
violations,
)?;
eval_into(
metadata,
&boundaries.visibility,
check_visibility_boundary,
violations,
)?;
eval_into(
metadata,
&boundaries.forbidden_marker,
check_forbidden_marker_boundary,
violations,
)?;
eval_into(
metadata,
&boundaries.dyn_trait,
check_dyn_trait_boundary,
violations,
)?;
eval_into(
metadata,
&boundaries.impl_trait,
check_impl_trait_boundary,
violations,
)?;
eval_into(
metadata,
&boundaries.async_exposure,
check_async_exposure_boundary,
violations,
)?;
Ok(())
}
pub fn check_all(boundaries: &SemanticBoundaries, manifest_path: &Path) -> Outcome {
let metadata = match read_metadata(manifest_path) {
Ok(metadata) => metadata,
Err(outcome) => return outcome,
};
let mut violations = Vec::new();
match eval_all(&metadata, boundaries, &mut violations) {
Ok(()) => outcome_from(violations),
Err(error) => Outcome::ConstitutionError(error),
}
}
#[cfg(test)]
mod tests;