#[ohno::error]
#[from(
LoadMetadataError,
UnknownSelectorError,
InvalidFilterExpressionError,
InvalidTargetKindError,
PlaceholderMisuseError,
ChdirConflictsWithOnceError,
JobsConflictWithOnceError,
PackageFileReadError,
PackageFileUtf8Error,
InvalidPackageFileLineError,
WorkspaceManifestReadError,
WorkspaceManifestParseError,
WorkspaceRustVersionError
)]
pub(crate) struct EachError;
#[ohno::error]
#[display("failed to load workspace metadata")]
#[from(cargo_metadata::Error)]
pub(crate) struct LoadMetadataError;
#[ohno::error]
#[display("package selector `{selector}` did not match any workspace member")]
pub(crate) struct UnknownSelectorError {
pub(crate) selector: String,
}
#[ohno::error]
#[display("invalid filter expression `{expression}`: {reason}")]
pub(crate) struct InvalidFilterExpressionError {
pub(crate) expression: String,
pub(crate) reason: String,
}
#[ohno::error]
#[display(
"invalid target kind `{kind}`; expected one of: lib, rlib, dylib, cdylib, staticlib, proc-macro, bin, example, test, bench, custom-build"
)]
pub(crate) struct InvalidTargetKindError {
pub(crate) kind: String,
}
#[ohno::error]
#[display("placeholder `{token}` cannot be used here: {reason}")]
pub(crate) struct PlaceholderMisuseError {
pub(crate) token: String,
pub(crate) reason: String,
}
#[ohno::error]
#[display("`--chdir` cannot be combined with `--once`")]
pub(crate) struct ChdirConflictsWithOnceError;
#[ohno::error]
#[display("`--jobs` must be 1 when combined with `--once`")]
pub(crate) struct JobsConflictWithOnceError;
#[ohno::error]
#[display("could not read package file `{path}`")]
#[from(std::io::Error)]
pub(crate) struct PackageFileReadError {
pub(crate) path: String,
}
#[ohno::error]
#[display("package file `{path}` is not valid UTF-8")]
#[from(std::string::FromUtf8Error)]
pub(crate) struct PackageFileUtf8Error {
pub(crate) path: String,
}
#[ohno::error]
#[display("invalid package spec in `{path}` at line {line}: `{spec}` ({reason})")]
pub(crate) struct InvalidPackageFileLineError {
pub(crate) path: String,
pub(crate) line: usize,
pub(crate) spec: String,
pub(crate) reason: String,
}
#[ohno::error]
#[display("could not read workspace manifest `{path}`")]
#[from(std::io::Error)]
pub(crate) struct WorkspaceManifestReadError {
pub(crate) path: String,
}
#[ohno::error]
#[display("could not parse workspace manifest `{path}`")]
#[from(toml::de::Error)]
pub(crate) struct WorkspaceManifestParseError {
pub(crate) path: String,
}
#[ohno::error]
#[display("cannot resolve `{{workspace-rust-version}}`: {reason}")]
pub(crate) struct WorkspaceRustVersionError {
pub(crate) reason: String,
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
#[test]
fn umbrella_propagates_load_metadata_chain() {
let inner = LoadMetadataError::caused_by(std::io::Error::other("no manifest"));
let outer: EachError = inner.into();
let rendered = outer.to_string();
assert!(rendered.contains("failed to load workspace metadata"));
assert!(rendered.contains("no manifest"));
}
#[test]
fn unknown_selector_carries_pattern() {
let err = UnknownSelectorError::new("nope-*".to_owned());
let rendered = err.to_string();
assert!(rendered.contains("nope-*"));
assert!(rendered.contains("did not match"));
}
#[test]
fn invalid_filter_expression_renders_reason() {
let err = InvalidFilterExpressionError::new("dep:".to_owned(), "empty dependency name".to_owned());
let rendered = err.to_string();
assert!(rendered.contains("dep:"));
assert!(rendered.contains("empty dependency name"));
}
#[test]
fn invalid_target_kind_names_value() {
let err = InvalidTargetKindError::new("nope".to_owned());
let rendered = err.to_string();
assert!(rendered.contains("nope"));
assert!(rendered.contains("target kind"));
}
#[test]
fn placeholder_misuse_renders_token_and_reason() {
let err = PlaceholderMisuseError::new("{name}".to_owned(), "per-package token in --once mode".to_owned());
let rendered = err.to_string();
assert!(rendered.contains("{name}"));
assert!(rendered.contains("--once"));
}
#[test]
fn chdir_conflict_renders() {
let err = ChdirConflictsWithOnceError::new();
let rendered = err.to_string();
assert!(rendered.contains("--chdir"));
assert!(rendered.contains("--once"));
}
#[test]
fn package_file_line_error_names_source() {
let err = InvalidPackageFileLineError::new(
"affected.packages".to_owned(),
3_usize,
"--workspace".to_owned(),
"command-line tokens are not package specs".to_owned(),
);
let rendered = err.to_string();
assert!(rendered.contains("affected.packages"));
assert!(rendered.contains("line 3"));
assert!(rendered.contains("--workspace"));
}
#[test]
fn workspace_rust_version_error_renders_reason() {
let err = WorkspaceRustVersionError::new("member `alpha` does not declare `rust-version`".to_owned());
let rendered = err.to_string();
assert!(rendered.contains("{workspace-rust-version}"));
assert!(rendered.contains("alpha"));
}
}