Skip to main content
Glama
json.rs2.1 kB
use async_trait::async_trait; use bytes::Bytes; use serde::de::DeserializeOwned; use crate::{ extract::{ FromMessage, rejection::{ JsonDataError, JsonRejection, JsonSyntaxError, }, }, message::{ Message, MessageHead, }, }; #[derive(Clone, Copy, Default, Debug)] #[must_use] pub struct Json<T>(pub T); #[async_trait] impl<T, S, R> FromMessage<S, R> for Json<T> where T: DeserializeOwned, R: MessageHead + Send + 'static, S: Send + Sync, { type Rejection = JsonRejection; async fn from_message(req: Message<R>, state: &S) -> Result<Self, Self::Rejection> { let bytes = Bytes::from_message(req, state) .await .expect("from_message is infallible"); Self::from_bytes(&bytes) } } impl<T> Json<T> where T: DeserializeOwned, { pub fn from_bytes(bytes: &[u8]) -> Result<Self, JsonRejection> { let deserializer = &mut serde_json::Deserializer::from_slice(bytes); let value = match serde_path_to_error::deserialize(deserializer) { Ok(value) => value, Err(err) => { let rejection = match err.inner().classify() { serde_json::error::Category::Data => JsonDataError::from_err(err).into(), serde_json::error::Category::Syntax | serde_json::error::Category::Eof => { JsonSyntaxError::from_err(err).into() } serde_json::error::Category::Io => { if cfg!(debug_assertions) { // We don't use `serde_json::from_reader` and instead always buffer // bodies first, so we shouldn't encounter any IO errors unreachable!() } else { JsonSyntaxError::from_err(err).into() } } }; return Err(rejection); } }; Ok(Json(value)) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server