tauri-plugin-persistence 0.2.0

A wrapper plugin for several persistence backends, focused on managing complex project folders with less boilerplate.
Documentation
use serde::{Deserialize, Serialize};
use specta::Type;

#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error, Type)]
#[serde(rename_all = "snake_case", tag = "kind")]
pub enum Error {
    #[error("An unexpected error occurred: {reason}")]
    Unknown{ reason: String },

    #[error("Failed to open context {name} at {path}: {reason}")]
    OpenContext {
        name: String,
        path: String,
        reason: String
    },

    #[error("Failed to open database {name} in context {context} at {path}: {reason}")]
    OpenDatabase {
        name: String,
        context: String,
        path: String,
        reason: String
    },

    #[error("Failed to open {path} in {context}: {reason}")]
    OpenFileHandle {
        path: String,
        context: String,
        reason: String
    },

    #[error("The requested context ({reason}) has not been initialized.")]
    UnknownContext{ reason: String },

    #[error("The requested database ({reason}) has not been opened.")]
    UnknownDatabase{ reason: String },

    #[error("The file handle with ID {reason} does not exist.")]
    UnknownFileHandle{ reason: String },

    #[error("Unknown transaction ID {reason} in current database.")]
    UnknownTransaction{ reason: String },

    #[error("Invalid path: {reason}")]
    InvalidPath{ reason: String },

    #[error("Cannot use an absolute path in this context: {reason}")]
    NoAbsolutePaths{ reason: String },

    #[error("Specified relative path escapes root path of this context: {reason}")]
    PathEscapesContext{ reason: String },

    #[error("Encountered a database error: {reason}")]
    DatabaseError{ reason: String },

    #[error("Serialization error: {reason}")]
    SerializationError{ reason: String },

    #[error("Deserialization error: {reason}")]
    DeserializationError{ reason: String },

    #[error("Encountered an IO error: {reason}")]
    IOError{ reason: String },

    #[error("Failed to encode {reason} bytes as UTF-8 string.")]
    StringEncodingError{ reason: String },

    #[error("Filesystem operation failed ({operation}): {reason}")]
    FilesystemError {operation: String, reason: String}
}

impl From<anyhow::Error> for Error {
    fn from(value: anyhow::Error) -> Self {
        Self::Unknown{reason: value.to_string()}
    }
}

impl From<polodb_core::Error> for Error {
    fn from(value: polodb_core::Error) -> Self {
        Self::DatabaseError{reason: value.to_string()}
    }
}

impl From<bson::ser::Error> for Error {
    fn from(value: bson::ser::Error) -> Self {
        Self::SerializationError{reason: value.to_string()}
    }
}

impl From<bson::de::Error> for Error {
    fn from(value: bson::de::Error) -> Self {
        Self::DeserializationError{reason: value.to_string()}
    }
}

impl From<std::io::Error> for Error {
    fn from(value: std::io::Error) -> Self {
        Self::IOError {reason: value.to_string()}
    }
}

impl Error {
    pub fn open_context(name: impl AsRef<str>, path: impl AsRef<str>, reason: impl AsRef<str>) -> Self {
        Self::OpenContext { name: name.as_ref().to_string(), path: path.as_ref().to_string(), reason: reason.as_ref().to_string() }
    }

    pub fn invalid_path(path: impl AsRef<str>) -> Self {
        Self::InvalidPath{reason: path.as_ref().to_string()}
    }

    pub fn unknown_context(name: impl AsRef<str>) -> Self {
        Self::UnknownContext{reason: name.as_ref().to_string()}
    }

    pub fn open_database(name: impl AsRef<str>, context: impl AsRef<str>, path: impl AsRef<str>, reason: impl AsRef<str>) -> Self {
        Self::OpenDatabase { name: name.as_ref().to_string(), context: context.as_ref().to_string(), path: path.as_ref().to_string(), reason: reason.as_ref().to_string() }
    }

    pub fn unknown_database(name: impl AsRef<str>) -> Self {
        Self::UnknownDatabase{reason: name.as_ref().to_string()}
    }

    pub fn no_absolute_path(path: impl AsRef<str>) -> Self {
        Self::NoAbsolutePaths{reason: path.as_ref().to_string()}
    }

    pub fn path_escapes_context(path: impl AsRef<str>) -> Self {
        Self::PathEscapesContext{reason: path.as_ref().to_string()}
    }

    pub fn open_file_handle(path: impl AsRef<str>, context: impl AsRef<str>, reason: impl AsRef<str>) -> Self {
        Self::OpenFileHandle { context: context.as_ref().to_string(), path: path.as_ref().to_string(), reason: reason.as_ref().to_string() }
    }

    pub fn unknown_file_handle(id: impl AsRef<str>) -> Self {
        Self::UnknownFileHandle{reason: id.as_ref().to_string()}
    }

    pub fn unknown_transaction(id: impl AsRef<str>) -> Self {
        Self::UnknownTransaction{reason: id.as_ref().to_string()}
    }

    pub fn string_encoding(size: usize) -> Self {
        Self::StringEncodingError{reason: size.to_string()}
    }

    pub fn filesystem(operation: impl AsRef<str>, reason: impl AsRef<str>) -> Self {
        Self::FilesystemError { operation: operation.as_ref().to_string(), reason: reason.as_ref().to_string() }
    }
}

pub type Result<T> = std::result::Result<T, Error>;