#![allow(dead_code)]
#![warn(missing_docs)]
use std::fmt;
pub mod base;
pub mod types;
pub mod sealed {
#[derive(Debug, Clone, Default)]
pub struct Token(pub(crate) ());
}
pub trait CalMessage: Send + Sync + 'static {
fn message_type_name() -> crate::QName
where
Self: Sized;
#[doc(hidden)]
fn cal_create() -> Self
where
Self: Sized;
fn is_valid(&self) -> Result<(), ValidationError> {
Ok(())
}
fn as_message_type_mut(&mut self) -> Option<&mut dyn crate::uci::types::MessageType> {
None
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ValidationError {
pub path: String,
pub reason: String,
}
impl fmt::Display for ValidationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.path, self.reason)
}
}
impl std::error::Error for ValidationError {}
pub trait CalSubMessage: Send + Sync + 'static {}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CalErrorKind {
InitializationFailure,
TopicUnavailable,
ResourcesUnavailable,
InvalidState {
current: crate::asb::AsbConnectionState,
},
UuidConformanceError,
OperationNotPermitted,
AsbFailed,
InvalidServiceIdentifier,
SerializationError,
AbstractInstantiation,
ImplementationError {
kind: Option<CalImplementationErrorKind>,
},
ValidationError(ValidationError),
}
impl fmt::Display for CalErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InitializationFailure => write!(f, "CAL initialization failure"),
Self::TopicUnavailable => write!(f, "Client topic unavailable"),
Self::ResourcesUnavailable => write!(f, "Required resources unavailable"),
Self::InvalidState { current } => {
write!(f, "Operation invalid in ASB state '{current}'")
}
Self::UuidConformanceError => write!(f, "UUID does not conform to RFC 4122"),
Self::OperationNotPermitted => write!(f, "Operation not permitted"),
Self::AsbFailed => write!(f, "Abstract Service Bus has permanently failed"),
Self::InvalidServiceIdentifier => {
write!(f, "Invalid or unregistered service identifier")
}
Self::SerializationError => write!(f, "CAL Message (de)serialization error"),
Self::AbstractInstantiation => {
write!(f, "Cannot instantiate abstract CAL Message type")
}
Self::ImplementationError { kind: None } => {
write!(f, "Internal CAL implementation error")
}
Self::ImplementationError {
kind: Some(CalImplementationErrorKind::ConfigError),
} => write!(f, "Unable to parse or interpret CAL configuration"),
Self::ImplementationError {
kind: Some(CalImplementationErrorKind::ListenerError),
} => write!(f, "Status listener error"),
Self::ValidationError(e) => write!(f, "Message validation failed: {e}"),
}
}
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CalImplementationErrorKind {
ConfigError,
ListenerError,
}
#[derive(Debug)]
pub struct CalError {
kind: CalErrorKind,
message: String,
source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
}
impl CalError {
pub fn new(kind: CalErrorKind, message: impl Into<String>) -> Self {
Self {
kind,
message: message.into(),
source: None,
}
}
pub fn with_source(
kind: CalErrorKind,
message: impl Into<String>,
source: impl std::error::Error + Send + Sync + 'static,
) -> Self {
Self {
kind,
message: message.into(),
source: Some(Box::new(source)),
}
}
pub fn new_impl(kind: CalImplementationErrorKind, message: impl Into<String>) -> Self {
Self::new(
CalErrorKind::ImplementationError { kind: Some(kind) },
message,
)
}
pub fn with_impl_source(
kind: CalImplementationErrorKind,
message: impl Into<String>,
source: impl std::error::Error + Send + Sync + 'static,
) -> Self {
Self::with_source(
CalErrorKind::ImplementationError { kind: Some(kind) },
message,
source,
)
}
pub fn kind(&self) -> &CalErrorKind {
&self.kind
}
pub fn message(&self) -> &str {
&self.message
}
pub fn is_asb_failure(&self) -> bool {
self.kind == CalErrorKind::AsbFailed
}
}
impl fmt::Display for CalError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.source {
Some(src) => write!(f, "{}: {}\n caused by: {src}", self.kind, self.message),
None => write!(f, "{}: {}", self.kind, self.message),
}
}
}
impl std::error::Error for CalError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.source
.as_deref()
.map(|s| s as &(dyn std::error::Error + 'static))
}
}
pub type CalResult<T> = Result<T, CalError>;