aboutsummaryrefslogtreecommitdiffstats
path: root/filamento/src/error.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--filamento/src/error.rs84
1 files changed, 80 insertions, 4 deletions
diff --git a/filamento/src/error.rs b/filamento/src/error.rs
index 6b7d0ae..bf28160 100644
--- a/filamento/src/error.rs
+++ b/filamento/src/error.rs
@@ -3,11 +3,12 @@ use std::{num::TryFromIntError, string::FromUtf8Error, sync::Arc};
use base64::DecodeError;
use image::ImageError;
use jid::JID;
-use lampada::error::{ActorError, ConnectionError, ReadError, WriteError};
-use stanza::client::{Stanza, iq::Query};
+use lampada::error::{ActorError, ReadError, WriteError};
+use stanza::client::{iq::Query, Stanza};
use thiserror::Error;
pub use lampada::error::CommandError;
+pub use lampada::error::ConnectionError;
use crate::files::FileStore;
@@ -166,11 +167,86 @@ pub enum ResponseError {
#[derive(Debug, Error, Clone)]
#[error("database error: {0}")]
-pub struct DatabaseError(pub Arc<rusqlite::Error>);
+pub struct DatabaseError(pub Serializeable<Arc<rusqlite::Error>>);
+
+pub enum Serializeable<T> {
+ String(String),
+ Unserialized(T),
+}
+
+impl<T: std::fmt::Display> std::fmt::Display for Serializeable<T> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match &self {
+ Serializeable::String(s) => s.fmt(f),
+ Serializeable::Unserialized(t) => t.fmt(f),
+ }
+ }
+}
+
+impl<T: std::fmt::Debug> std::fmt::Debug for Serializeable<T> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match &self {
+ Serializeable::String(s) => s.fmt(f),
+ Serializeable::Unserialized(t) => t.fmt(f),
+ }
+ }
+}
+
+impl<T: Clone> Clone for Serializeable<T> {
+ fn clone(&self) -> Self {
+ match self {
+ Serializeable::String(s) => Self::String(s.clone()),
+ Serializeable::Unserialized(t) => Self::Unserialized(t.clone()),
+ }
+ }
+}
+
+#[cfg(feature = "serde")]
+struct StringVisitor;
+
+#[cfg(feature = "serde")]
+impl<'de> serde::de::Visitor<'de> for StringVisitor {
+ type Value = String;
+
+ fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+ formatter.write_str("a string")
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: serde::de::Error,
+ {
+ Ok(v)
+ }
+}
+
+#[cfg(feature = "serde")]
+impl<'de> serde::Deserialize<'de> for DatabaseError {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let string = deserializer.deserialize_string(StringVisitor)?;
+ Ok(Self(Serializeable::String(string)))
+ }
+}
+
+#[cfg(feature = "serde")]
+impl serde::Serialize for DatabaseError {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ match &self.0 {
+ Serializeable::String(s) => serializer.serialize_str(s),
+ Serializeable::Unserialized(u) => serializer.serialize_str(&u.to_string()),
+ }
+ }
+}
impl From<rusqlite::Error> for DatabaseError {
fn from(e: rusqlite::Error) -> Self {
- Self(Arc::new(e))
+ Self(Serializeable::Unserialized(Arc::new(e)))
}
}