use std::sync::Arc;
use lampada::error::{ConnectionError, ReadError, WriteError};
use stanza::client::Stanza;
use thiserror::Error;
pub use lampada::error::CommandError;
// for the client logic impl
#[derive(Debug, Error, Clone)]
pub enum Error {
#[error("core error: {0}")]
Connection(#[from] ConnectionError),
#[error("received unrecognized/unsupported content")]
UnrecognizedContent,
// TODO: include content
// UnrecognizedContent(peanuts::element::Content),
#[error("iq receive error: {0}")]
Iq(IqError),
// TODO: change to Connecting(ConnectingError)
#[error("connecting: {0}")]
Connecting(#[from] ConnectionJobError),
#[error("presence: {0}")]
Presence(#[from] PresenceError),
#[error("set status: {0}")]
SetStatus(#[from] StatusError),
// TODO: have different ones for get/update/set
#[error("roster: {0}")]
Roster(RosterError),
#[error("stream error: {0}")]
Stream(#[from] stanza::stream::Error),
#[error("message send error: {0}")]
MessageSend(MessageSendError),
#[error("message receive error: {0}")]
MessageRecv(MessageRecvError),
}
#[derive(Debug, Error, Clone)]
pub enum MessageSendError {
#[error("could not add to message history: {0}")]
MessageHistory(#[from] DatabaseError),
}
#[derive(Debug, Error, Clone)]
pub enum MessageRecvError {
#[error("could not add to message history: {0}")]
MessageHistory(#[from] DatabaseError),
#[error("missing from")]
MissingFrom,
}
#[derive(Debug, Error, Clone)]
pub enum StatusError {
#[error("cache: {0}")]
Cache(#[from] DatabaseError),
#[error("stream write: {0}")]
Write(#[from] WriteError),
}
#[derive(Debug, Clone, Error)]
pub enum ConnectionJobError {
// #[error("connection failed: {0}")]
// ConnectionFailed(#[from] luz::Error),
#[error("failed roster retreival: {0}")]
RosterRetreival(#[from] RosterError),
#[error("failed to send available presence: {0}")]
SendPresence(#[from] WriteError),
#[error("cached status: {0}")]
StatusCacheError(#[from] DatabaseError),
}
#[derive(Debug, Error, Clone)]
pub enum RosterError {
#[error("cache: {0}")]
Cache(#[from] DatabaseError),
#[error("stream write: {0}")]
Write(#[from] WriteError),
// TODO: display for stanza, to show as xml, same for read error types.
#[error("unexpected reply: {0:?}")]
UnexpectedStanza(Stanza),
#[error("stream read: {0}")]
Read(#[from] ReadError),
#[error("stanza error: {0}")]
StanzaError(#[from] stanza::client::error::Error),
}
#[derive(Debug, Error, Clone)]
#[error("database error: {0}")]
pub struct DatabaseError(Arc<sqlx::Error>);
impl From<sqlx::Error> for DatabaseError {
fn from(e: sqlx::Error) -> Self {
Self(Arc::new(e))
}
}
impl From<sqlx::Error> for DatabaseOpenError {
fn from(e: sqlx::Error) -> Self {
Self::Error(Arc::new(e))
}
}
#[derive(Debug, Error, Clone)]
// TODO: should probably have all iq query related errors here, including read, write, stanza error, etc.
pub enum IqError {
#[error("no iq with id matching `{0}`")]
NoMatchingId(String),
}
#[derive(Debug, Error, Clone)]
pub enum DatabaseOpenError {
#[error("error: {0}")]
Error(Arc<sqlx::Error>),
#[error("migration: {0}")]
Migration(Arc<sqlx::migrate::MigrateError>),
#[error("io: {0}")]
Io(Arc<tokio::io::Error>),
#[error("invalid path")]
InvalidPath,
}
impl From<sqlx::migrate::MigrateError> for DatabaseOpenError {
fn from(e: sqlx::migrate::MigrateError) -> Self {
Self::Migration(Arc::new(e))
}
}
impl From<tokio::io::Error> for DatabaseOpenError {
fn from(e: tokio::io::Error) -> Self {
Self::Io(Arc::new(e))
}
}
#[derive(Debug, Error, Clone)]
pub enum PresenceError {
#[error("unsupported")]
Unsupported,
#[error("missing from")]
MissingFrom,
#[error("stanza error: {0}")]
StanzaError(#[from] stanza::client::error::Error),
}