use std::error::Error;
use std::fmt;
#[derive(Debug, Clone)]
pub enum VersioningError {
VersionOutsideEnum { target: String },
DuplicateVersionEnum { first: String, second: String },
EmptyVersionEnum { ident: String },
DuplicateVersionValue {
value: String,
first: String,
second: String,
},
MissingVersionEnum { annotation: String, decl: String },
MalformedVersionReference { annotation: String, decl: String },
MalformedVersionMarker { decl: String },
MalformedVersionParameter { decl: String, reason: String },
DuplicateVersionParameter { decl: String },
UnknownVersionReference {
annotation: String,
decl: String,
reference: String,
declared: String,
},
UnsupportedVersionAnnotation { name: String, decl: String },
UnsupportedVersionTarget { annotation: String, target: String },
VersionedVersionEnum { annotation: String, ident: String },
DuplicateLifecycleAnnotation { annotation: String, decl: String },
EmptyAvailability {
decl: String,
added: String,
removed: String,
},
ChildOutsideParent {
decl: String,
parent: String,
version: String,
},
DanglingReference {
decl: String,
reference: String,
version: String,
},
UnversionedSpecification { selection: String },
UnknownSelectedVersion { selection: String, declared: String },
AmbiguousSelectedVersion {
selection: String,
first: String,
second: String,
},
UnknownVersion { index: usize },
ConflictingSelection { first: String, second: String },
EmptySelection,
SelectionRequiresOneVersion { selection: String },
UnknownVersionLayout { value: String },
DuplicateWireName {
container: String,
wire: String,
first: String,
second: String,
version: Option<String>,
},
}
impl fmt::Display for VersioningError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::VersionOutsideEnum { target } => write!(
f,
"xidl versioning: @version is only valid on an enum declaration, not on {target}"
),
Self::DuplicateVersionEnum { first, second } => write!(
f,
"xidl versioning: multiple @version enums declared: {first} and {second}"
),
Self::EmptyVersionEnum { ident } => write!(
f,
"xidl versioning: the @version enum {ident} declares no versions"
),
Self::DuplicateVersionValue {
value,
first,
second,
} => write!(
f,
"xidl versioning: versions {first} and {second} both resolve to value \"{value}\""
),
Self::MissingVersionEnum { annotation, decl } => write!(
f,
"xidl versioning: {annotation} on {decl} requires a @version enum in the specification"
),
Self::MalformedVersionReference { annotation, decl } => write!(
f,
"xidl versioning: {annotation} on {decl} requires a version reference like Versions::v1"
),
Self::MalformedVersionMarker { decl } => {
write!(
f,
"xidl versioning: @version on {decl} must be bare or declare in=... and name=..."
)
}
Self::MalformedVersionParameter { decl, reason } => {
write!(f, "xidl versioning: @version on {decl}: {reason}")
}
Self::DuplicateVersionParameter { decl } => write!(
f,
"xidl versioning: @version on {decl} is declared more than once"
),
Self::UnknownVersionReference {
annotation,
decl,
reference,
declared,
} => write!(
f,
"xidl versioning: {annotation} on {decl} references {reference}, which is not declared ({declared})"
),
Self::UnsupportedVersionAnnotation { name, decl } => {
write!(f, "xidl versioning: {name} on {decl} is not supported; ")?;
if name.eq_ignore_ascii_case("@renamedFrom") {
write!(
f,
"use @rename(\"wire_name\") for the serialized name; use @added/@removed declarations for changes between versions"
)
} else {
write!(
f,
"use @version, @added and @removed for version availability"
)
}
}
Self::UnsupportedVersionTarget { annotation, target } => write!(
f,
"xidl versioning: {annotation} cannot be applied to {target}"
),
Self::VersionedVersionEnum { annotation, ident } => write!(
f,
"xidl versioning: the @version enum {ident} cannot carry {annotation}"
),
Self::DuplicateLifecycleAnnotation { annotation, decl } => {
write!(f, "xidl versioning: duplicate {annotation} on {decl}")
}
Self::EmptyAvailability {
decl,
added,
removed,
} => write!(
f,
"xidl versioning: {decl} is unavailable in every version (@added({added}) and @removed({removed}) leave an empty interval)"
),
Self::ChildOutsideParent {
decl,
parent,
version,
} => write!(
f,
"xidl versioning: {decl} is annotated at {version}, outside the availability of {parent}"
),
Self::DanglingReference {
decl,
reference,
version,
} => write!(
f,
"xidl versioning: {decl} references {reference}, which does not exist in {version}"
),
Self::UnversionedSpecification { selection } => write!(
f,
"xidl versioning: version selection {selection} requires a @version enum in the specification"
),
Self::UnknownSelectedVersion {
selection,
declared,
} => write!(
f,
"xidl versioning: version {selection} is not declared ({declared})"
),
Self::AmbiguousSelectedVersion {
selection,
first,
second,
} => write!(
f,
"xidl versioning: version {selection} matches both {first} and {second}; use the member ident"
),
Self::UnknownVersion { index } => write!(
f,
"xidl versioning: version position {index} is not part of the declared timeline"
),
Self::ConflictingSelection { first, second } => write!(
f,
"xidl versioning: {first} and {second} cannot both be set"
),
Self::EmptySelection => write!(
f,
"xidl versioning: the version selection is empty; name at least one version or use \"*\""
),
Self::SelectionRequiresOneVersion { selection } => write!(
f,
"xidl versioning: {selection} selects one version; use the plural version property with \"*\" for every version"
),
Self::UnknownVersionLayout { value } => write!(
f,
"xidl versioning: unknown version layout \"{value}\"; expected \"merged\" or \"per_version\""
),
Self::DuplicateWireName {
container,
wire,
first,
second,
version,
} => match version {
Some(version) => write!(
f,
"xidl versioning: {first} and {second} both serialize as \"{wire}\" in version {version}; effective wire names must stay unique inside {container} for every version"
),
None => write!(
f,
"xidl versioning: {first} and {second} both serialize as \"{wire}\"; effective wire names must stay unique inside {container}"
),
},
}
}
}
impl Error for VersioningError {}