use thiserror::Error;
#[derive(Debug, Error)]
pub enum CliError {
#[error("Authentication failed: {0}")]
AuthError(String),
#[error("API error: {0}")]
ApiError(String),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Not logged in. Run 'oauth-db login' first")]
NotLoggedIn,
#[error("Permission denied: {0}")]
PermissionDenied(String),
#[error("Permission denied for operation '{operation}'.\nrequired role: {required}\nYour role: {current}\n{hint}")]
RoleMissing {
current: String,
required: String,
operation: String,
hint: String,
},
#[error("Resource not found: {0}")]
NotFound(String),
#[error("Invalid input: {0}")]
InvalidInput(String),
#[error("HTTP request failed: {0}")]
HttpError(#[from] reqwest::Error),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Serialization error: {0}")]
SerdeError(#[from] serde_json::Error),
#[error("TOML error: {0}")]
TomlError(#[from] toml::de::Error),
#[error("Encryption error: {0}")]
CryptoError(String),
#[error("Encryption error: {0}")]
EncryptionError(String),
#[error("Serialization error: {0}")]
SerializationError(String),
#[error("Network error: {0}")]
NetworkError(String),
}
impl From<serde_yaml::Error> for CliError {
fn from(err: serde_yaml::Error) -> Self {
CliError::SerializationError(format!("YAML error: {}", err))
}
}
impl From<toml::ser::Error> for CliError {
fn from(err: toml::ser::Error) -> Self {
CliError::ConfigError(format!("TOML serialization error: {}", err))
}
}
pub type Result<T> = std::result::Result<T, CliError>;
impl CliError {
pub fn role_missing(current: impl Into<String>, required: impl Into<String>, operation: impl Into<String>) -> Self {
let current = current.into();
let required = required.into();
let operation = operation.into();
let hint = match required.as_str() {
"admin" => "Please switch to an account with admin privileges or contact your administrator.",
"developer" => "You need to register as a developer. Run 'oauth-db register' to create an account.",
_ => "Please check your account permissions.",
};
CliError::RoleMissing {
current,
required,
operation,
hint: hint.to_string(),
}
}
pub fn permission_denied(resource: impl Into<String>, action: impl Into<String>) -> Self {
CliError::PermissionDenied(format!(
"You don't have permission to {} {}. Please check your access rights.",
action.into(),
resource.into()
))
}
}