use std::fmt;
use std::path::PathBuf;
use crate::{DecoderError, InferError};
#[derive(Debug)]
#[non_exhaustive]
pub enum ModelConfigError {
Io {
path: PathBuf,
source: std::io::Error,
},
Container(String),
InvalidField {
file: String,
field: String,
reason: String,
},
NotSupported {
field: String,
reason: String,
},
UnsupportedArchitecture(String),
Override(String),
LabelCountMismatch {
expected: usize,
found: usize,
},
Unresolved {
missing: String,
overrides: String,
},
Infer(InferError),
Schema(DecoderError),
}
impl fmt::Display for ModelConfigError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Io { path, source } => write!(f, "cannot read {}: {source}", path.display()),
Self::Container(s) => write!(f, "malformed model container: {s}"),
Self::InvalidField {
file,
field,
reason,
} => write!(f, "{file}: field `{field}` {reason}"),
Self::NotSupported { field, reason } => {
write!(f, "`{field}` is not supported: {reason}")
}
Self::UnsupportedArchitecture(t) => write!(
f,
"Hugging Face model_type `{t}` has no decoder; supported: *ForSemanticSegmentation"
),
Self::Override(s) => write!(f, "invalid override: {s}"),
Self::LabelCountMismatch { expected, found } => write!(
f,
"invalid override: labels names {found} classes but the model has {expected}"
),
Self::Unresolved { missing, overrides } => {
write!(f, "missing {missing}; supply {overrides}")
}
Self::Infer(e) => write!(f, "Ultralytics metadata: {e}"),
Self::Schema(e) => write!(f, "invalid model schema: {e}"),
}
}
}
impl std::error::Error for ModelConfigError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Io { source, .. } => Some(source),
Self::Infer(e) => Some(e),
Self::Schema(e) => Some(e),
_ => None,
}
}
}
impl From<InferError> for ModelConfigError {
fn from(e: InferError) -> Self {
Self::Infer(e)
}
}
impl From<DecoderError> for ModelConfigError {
fn from(e: DecoderError) -> Self {
Self::Schema(e)
}
}
pub(crate) fn invalid(file: &str, field: &str, reason: impl Into<String>) -> ModelConfigError {
ModelConfigError::InvalidField {
file: file.to_owned(),
field: field.to_owned(),
reason: reason.into(),
}
}