airy 0.1.1

Airy is an AI tool for interacting with databases.
Documentation
use rmcp::{Error as McpError, ServiceError};
use serde::Serialize;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum AppError {
    #[error("internal error: {0}")]
    Internal(#[from] Box<dyn std::error::Error>),
    #[error("service error: {0}")]
    Service(#[from] ServiceError),
    #[error("request error: {0}")]
    Request(#[from] reqwest::Error),
    #[error("sql error: {0}")]
    Sql(#[from] sqlx::Error),
    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),
    #[error("JSON error: {0}")]
    Json(#[from] serde_json::Error),
    #[error("serde deserialize error: {0}")]
    JsonDeserialize(#[from] serde::de::value::Error),
    #[error("missing OpenRouter API key")]
    MissingApiKey,
    #[error("missing database URL")]
    MissingDatabaseUrl,
}

pub type AppResult<T> = Result<T, AppError>;

impl Serialize for AppError {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        #[derive(Serialize)]
        struct ErrorProto {
            message: String,
        }

        ErrorProto {
            message: self.to_string(),
        }
        .serialize(serializer)
    }
}

impl From<AppError> for McpError {
    fn from(err: AppError) -> Self {
        match err {
            AppError::Internal(err) => McpError::internal_error(err.to_string(), None),
            AppError::Service(err) => McpError::internal_error(err.to_string(), None),
            AppError::Request(err) => McpError::invalid_request(err.to_string(), None),
            AppError::Sql(err) => McpError::internal_error(err.to_string(), None),
            AppError::Io(err) => McpError::internal_error(err.to_string(), None),
            AppError::Json(err) => McpError::parse_error(err.to_string(), None),
            AppError::JsonDeserialize(err) => McpError::parse_error(err.to_string(), None),
            AppError::MissingApiKey => {
                McpError::invalid_request("Missing OpenRouter API key", None)
            }
            AppError::MissingDatabaseUrl => McpError::invalid_request("Missing database URL", None),
        }
    }
}