use std::path::Path;
pub(crate) fn unreadable_workspace_error(manifest_path: &Path, err: &str) -> String {
format!(
"a boundary is observed against a real workspace, so an unreadable one cannot be judged \
and its verdict would be a false pass: cannot read target workspace at {} ({err}); check \
the manifest path and that `cargo metadata` succeeds",
manifest_path.display()
)
}
pub(crate) fn crate_not_found_error(crate_package: &str) -> String {
format!(
"a boundary must govern a real crate or it silently never reacts: target crate \
'{crate_package}' is not a member of the target workspace — check the name or --manifest-path"
)
}
pub(crate) fn missing_src_error(crate_package: &str) -> String {
format!(
"a semantic boundary is observed from source, so with no src it could never react: cannot \
locate the crate root source for '{crate_package}'"
)
}
pub(crate) fn unknown_module_error(module: &str, crate_package: &str) -> String {
format!(
"a boundary must anchor to a real module or it silently never reacts: module '{module}' is \
not found among the modules of crate '{crate_package}' (declared via `mod`) — check the path"
)
}
pub(crate) fn unknown_trait_error(trait_path: &str, crate_package: &str) -> String {
format!(
"a trait-impl-locality boundary must anchor to a real local trait or it silently never \
reacts: trait '{trait_path}' is not found as a `trait` item (directly or via a local \
`pub use`) in crate '{crate_package}' — check the path"
)
}
pub(crate) fn ambiguous_trait_anchor_error(
trait_path: &str,
crate_package: &str,
anchors: &[String],
) -> String {
format!(
"a trait-impl-locality boundary must anchor to exactly one trait, but '{trait_path}' in \
crate '{crate_package}' reaches {} distinct trait definitions through this crate's own \
re-exports ({}) — two mutually-exclusive `#[cfg]` branches re-export different traits \
under that name, so the anchor cannot identify one. Declare the defining path instead of \
the facade",
anchors.len(),
anchors.join(", ")
)
}
pub(crate) fn unsafe_empty_allowed_error(crate_package: &str) -> String {
format!(
"an unsafe-confinement boundary on crate '{crate_package}' declares an empty `only_under([])`: \
this rule confines `unsafe` to a subtree, it does not ban it crate-wide — for that use \
`#![forbid(unsafe_code)]` (compile-time, unbypassable); name at least one allowed subtree"
)
}
pub(crate) fn unsafe_crate_root_allowed_error(crate_package: &str) -> String {
format!(
"an unsafe-confinement boundary on crate '{crate_package}' allows `unsafe` under `crate` \
(the crate root): the whole crate would be permitted, so the rule could never react — \
confine it to a submodule (e.g. `crate::ffi`) instead"
)
}
pub(crate) fn malformed_path_operand_error(operand: &str) -> String {
format!(
"a forbidden/allowed operand must be a `::`-delimited path with no empty segment: \
'{operand}' has a leading, trailing, or doubled `::` (or is empty) — no resolved path \
this system ever produces carries one, so the boundary could never react to it; write it \
as a bare path instead (e.g. `serde`, not `::serde` or `serde::`)"
)
}
pub(crate) fn missing_module_file_error(module: &str, crate_package: &str) -> String {
format!(
"module '{module}' of crate '{crate_package}' is declared (`mod …;`) but its source file \
could not be located (expected `<name>.rs` or `<name>/mod.rs`)"
)
}
pub(crate) fn dual_backed_module_error(
module: &str,
declaration: &str,
crate_package: &str,
flat: &Path,
nested: &Path,
) -> String {
format!(
"cannot resolve module '{module}' of crate '{crate_package}': its `mod {declaration};` \
declaration resolves to both '{}' and '{}' — a plain `mod` must be backed by exactly one \
file, so which of the two governs cannot be judged",
flat.display(),
nested.display()
)
}
pub(crate) fn unreadable_source_error(file: &Path, err: &str) -> String {
format!("cannot read source file '{}': {err}", file.display())
}
pub(crate) fn unparseable_source_error(file: &Path, err: &str) -> String {
format!("cannot parse source file '{}': {err}", file.display())
}
pub(crate) fn out_of_package_root_error(crate_package: &str, root: &std::path::Path) -> String {
format!(
"a violation's identity is labeled by the compilation unit it came from, relative to the \
package's own directory, so a crate root outside that directory cannot be judged without a \
checkout-dependent identity: crate '{crate_package}' declares a target rooted at '{}', which \
is not under the package's manifest directory; move the target's source under the package \
directory, or declare the boundary against the package that owns it",
root.display()
)
}