use crate::PackageId;
use std::error;
use std::fmt;
use crate::graph::feature::FeatureId;
use std::path::PathBuf;
use Error::*;
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
CommandError(Box<dyn error::Error + Send + Sync>),
MetadataParseError(serde_json::Error),
MetadataSerializeError(serde_json::Error),
PackageGraphConstructError(String),
UnknownPackageId(PackageId),
UnknownFeatureId(PackageId, Option<String>),
UnknownWorkspacePath(PathBuf),
UnknownWorkspaceName(String),
TargetSpecError(String, target_spec::Error),
CargoSetError(String),
PackageGraphInternalError(String),
FeatureGraphInternalError(String),
}
impl Error {
pub(crate) fn command_error(err: cargo_metadata::Error) -> Self {
Error::CommandError(Box::new(err))
}
pub(crate) fn unknown_feature_id(feature_id: FeatureId<'_>) -> Self {
let (package_id, feature) = feature_id.into();
Error::UnknownFeatureId(package_id, feature)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CommandError(err) => write!(f, "Error while executing 'cargo metadata': {}", err),
MetadataParseError(err) => write!(
f,
"Error while parsing 'cargo metadata' JSON output: {}",
err
),
MetadataSerializeError(err) => write!(
f,
"Error while serializing 'cargo metadata' JSON output: {}",
err
),
PackageGraphConstructError(msg) => {
write!(f, "Error while computing package graph: {}", msg)
}
UnknownPackageId(id) => write!(f, "Unknown package ID: {}", id),
UnknownFeatureId(package_id, feature) => match feature {
Some(feature) => write!(f, "Unknown feature ID: '{}' '{}'", package_id, feature),
None => write!(f, "Unknown feature ID: '{}' (base)", package_id),
},
UnknownWorkspacePath(path) => write!(f, "Unknown workspace path: {}", path.display()),
UnknownWorkspaceName(name) => write!(f, "Unknown workspace package name: {}", name),
TargetSpecError(msg, _) => write!(f, "Target spec error while {}", msg),
CargoSetError(msg) => write!(f, "Error while computing Cargo set: {}", msg),
PackageGraphInternalError(msg) => write!(f, "Internal error in package graph: {}", msg),
FeatureGraphInternalError(msg) => write!(f, "Internal error in feature graph: {}", msg),
}
}
}
impl error::Error for Error {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
MetadataParseError(err) => Some(err),
MetadataSerializeError(err) => Some(err),
CommandError(err) => Some(err.as_ref()),
PackageGraphConstructError(_) => None,
UnknownPackageId(_) => None,
UnknownFeatureId(_, _) => None,
UnknownWorkspacePath(_) => None,
UnknownWorkspaceName(_) => None,
TargetSpecError(_, err) => Some(err),
CargoSetError(_) => None,
PackageGraphInternalError(_) => None,
FeatureGraphInternalError(_) => None,
}
}
}
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
#[non_exhaustive]
pub enum FeatureGraphWarning {
MissingFeature {
stage: FeatureBuildStage,
package_id: PackageId,
feature_name: String,
},
}
impl fmt::Display for FeatureGraphWarning {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use FeatureGraphWarning::*;
match self {
MissingFeature {
stage,
package_id,
feature_name,
} => write!(
f,
"{}: for package '{}', missing feature '{}'",
stage, package_id, feature_name
),
}
}
}
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
#[non_exhaustive]
pub enum FeatureBuildStage {
AddNamedFeatureEdges {
package_id: PackageId,
from_feature: String,
},
AddDependencyEdges {
package_id: PackageId,
dep_name: String,
},
}
impl fmt::Display for FeatureBuildStage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use FeatureBuildStage::*;
match self {
AddNamedFeatureEdges {
package_id,
from_feature,
} => write!(
f,
"for package '{}', while adding named feature edges from '{}'",
package_id, from_feature
),
AddDependencyEdges {
package_id,
dep_name,
} => write!(
f,
"for package '{}', while adding edges for dependency '{}'",
package_id, dep_name,
),
}
}
}