use std::fmt;
use std::io;
use serde_json::Value;
use thiserror::Error;
pub type Result<T, E = FastMcpError> = std::result::Result<T, E>;
#[derive(Debug, Error)]
pub enum FastMcpError {
#[error("tool '{0}' already registered")]
DuplicateTool(String),
#[error("tool '{0}' not found")]
ToolNotFound(String),
#[error("resource '{0}' already registered")]
DuplicateResource(String),
#[error("resource '{0}' not found")]
ResourceNotFound(String),
#[error("prompt '{0}' already registered")]
DuplicatePrompt(String),
#[error("prompt '{0}' not found")]
PromptNotFound(String),
#[error("invalid invocation payload: {0}")]
InvalidInvocation(String),
#[error("handler error: {0}")]
HandlerError(String),
#[error("serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("io error: {0}")]
Io(#[from] io::Error),
}
impl FastMcpError {
pub fn handler_error(err: impl fmt::Display) -> Self {
Self::HandlerError(err.to_string())
}
}
pub fn expect_object<'a>(
payload: &'a Value,
context: &'static str,
) -> Result<&'a serde_json::Map<String, Value>> {
payload
.as_object()
.ok_or_else(|| FastMcpError::InvalidInvocation(format!("{context} expects a JSON object")))
}