use crate::domain::error::DomainError;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ApplicationError {
#[error("Domain error: {0}")]
Domain(#[from] DomainError),
#[error("Bookmark not found with ID {0}")]
BookmarkNotFound(i32),
#[error("Bookmark already exists: Id {0}: {1}")]
BookmarkExists(i32, String),
#[error("Validation failed: {0}")]
Validation(String),
#[error("Duplicate name '{name}' found in {file_path}. Existing bookmark with same name already exists (ID: {existing_id}). Use --update flag to overwrite existing bookmarks with changed content")]
DuplicateName {
name: String,
existing_id: i32,
file_path: String,
},
#[error("{0}")]
Other(String),
}
impl ApplicationError {
pub fn context<C: Into<String>>(self, context: C) -> Self {
match self {
ApplicationError::Other(msg) => {
ApplicationError::Other(format!("{}: {}", context.into(), msg))
}
ApplicationError::Domain(err) => ApplicationError::Domain(err.context(context)),
ApplicationError::Validation(msg) => {
ApplicationError::Validation(format!("{}: {}", context.into(), msg))
}
err => ApplicationError::Other(format!("{}: {}", context.into(), err)),
}
}
}
impl From<std::io::Error> for ApplicationError {
fn from(err: std::io::Error) -> Self {
ApplicationError::Domain(DomainError::Io(err))
}
}
impl From<std::time::SystemTimeError> for ApplicationError {
fn from(err: std::time::SystemTimeError) -> Self {
ApplicationError::Other(format!("System time error: {}", err))
}
}
pub type ApplicationResult<T> = Result<T, ApplicationError>;