use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum WaymarkError {
Authoring(AuthoringError),
Semantic(SemanticError),
Topology(TopologyError),
Compatibility(CompatibilityError),
Canonical(CanonicalError),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AuthoringError {
UnknownTag(String),
UnknownSignal(String),
UnknownReceiver(String),
UnknownFunction(String),
InvalidPropertyType { key: String, expected: String, got: String },
InvalidTemplateReference(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SemanticError {
ConflictingTags(Vec<String>),
MissingRequiredReceiver(String),
InvalidSignalReceiverBinding { signal: String, receiver: String },
GraphConstraintViolation(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum TopologyError {
InvalidParentChildRelation { parent: String, child: String },
InvalidTransition { from: String, to: String },
InvalidTopologyBinding(String),
IllegalCrossLayerReference(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CompatibilityError {
PackVersionMismatch(String),
SchemaVersionMismatch(String),
ReducerContractMismatch(String),
UnsupportedRegistryVersion(String),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CanonicalError {
UnstableCanonicalOrdering(String),
MissingVersionedIdentity(String),
UnhashableDelta(String),
}
impl fmt::Display for WaymarkError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Authoring(e) => write!(f, "waymark_authoring: {e:?}"),
Self::Semantic(e) => write!(f, "waymark_semantic: {e:?}"),
Self::Topology(e) => write!(f, "waymark_topology: {e:?}"),
Self::Compatibility(e) => write!(f, "waymark_compatibility: {e:?}"),
Self::Canonical(e) => write!(f, "waymark_canonical: {e:?}"),
}
}
}
impl std::error::Error for WaymarkError {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn error_display_authoring() {
let e = WaymarkError::Authoring(AuthoringError::UnknownTag("foo".into()));
assert!(e.to_string().contains("waymark_authoring"));
}
#[test]
fn error_display_semantic() {
let e = WaymarkError::Semantic(SemanticError::ConflictingTags(vec!["a".into()]));
assert!(e.to_string().contains("waymark_semantic"));
}
#[test]
fn error_display_topology() {
let e = WaymarkError::Topology(TopologyError::InvalidTopologyBinding("x".into()));
assert!(e.to_string().contains("waymark_topology"));
}
#[test]
fn error_serde_roundtrip() {
let e = WaymarkError::Canonical(CanonicalError::UnhashableDelta("test".into()));
let json = serde_json::to_string(&e).unwrap();
let _: WaymarkError = serde_json::from_str(&json).unwrap();
}
}