Skip to main content
Glama
content_info.rs5.24 kB
use std::{ borrow::Cow, fmt, num::ParseIntError, str::FromStr, }; use crate::container::Container; #[cfg(feature = "nats-headers")] use crate::error::HeaderMapParseMessageInfoError; /// Content metadata information for a message. #[derive(Clone, Debug)] pub struct ContentInfo<'a> { /// The type of the content in the message. pub content_type: ContentType<'a>, /// The type of the message. pub message_type: MessageType, /// The version of the message. pub message_version: MessageVersion, } impl<T> From<&T> for ContentInfo<'static> where T: Container, { fn from(_value: &T) -> Self { Self { content_type: T::default_content_type().into(), message_type: T::message_type().into(), message_version: T::message_version().into(), } } } #[cfg(feature = "nats-headers")] impl ContentInfo<'_> { /// Injects the content information into NATS message headers. pub fn inject_into_headers(&self, headers: &mut async_nats::HeaderMap) { headers.insert(nats_std::header::CONTENT_TYPE, self.content_type.as_str()); headers.insert(nats_std::header::MESSAGE_TYPE, self.message_type.as_str()); headers.insert( nats_std::header::MESSAGE_VERSION, self.message_version.to_string(), ); } } #[cfg(feature = "nats-headers")] impl TryFrom<&async_nats::HeaderMap> for ContentInfo<'_> { type Error = HeaderMapParseMessageInfoError; fn try_from(map: &async_nats::HeaderMap) -> Result<Self, Self::Error> { let content_type = ContentType::from(map.get(nats_std::header::CONTENT_TYPE).ok_or( HeaderMapParseMessageInfoError::MissingHeader(nats_std::header::CONTENT_TYPE), )?); let message_type = MessageType::from(map.get(nats_std::header::MESSAGE_TYPE).ok_or( HeaderMapParseMessageInfoError::MissingHeader(nats_std::header::MESSAGE_TYPE), )?); let message_version = MessageVersion::try_from(map.get(nats_std::header::MESSAGE_VERSION).ok_or( HeaderMapParseMessageInfoError::MissingHeader(nats_std::header::MESSAGE_VERSION), )?) .map_err(HeaderMapParseMessageInfoError::ParseVersion)?; Ok(Self { content_type, message_type, message_version, }) } } #[cfg(feature = "nats-headers")] impl TryFrom<Option<&async_nats::HeaderMap>> for ContentInfo<'_> { type Error = HeaderMapParseMessageInfoError; fn try_from(value: Option<&async_nats::HeaderMap>) -> Result<Self, Self::Error> { let headers = value.ok_or(Self::Error::MissingHeaders)?; Self::try_from(headers) } } /// The content type of a message. #[derive(Clone, Debug, Eq, PartialEq)] pub struct ContentType<'a>(Cow<'a, str>); impl ContentType<'_> { /// Returns the interior data as a borrowed string. pub fn as_str(&self) -> &str { self.0.as_ref() } } impl fmt::Display for ContentType<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } impl From<String> for ContentType<'_> { fn from(value: String) -> Self { Self(Cow::Owned(value)) } } impl<'a> From<&'a str> for ContentType<'a> { fn from(value: &'a str) -> Self { Self(Cow::Borrowed(value)) } } #[cfg(feature = "nats-headers")] impl From<&async_nats::HeaderValue> for ContentType<'_> { fn from(value: &async_nats::HeaderValue) -> Self { Self(Cow::Owned(value.as_str().to_string())) } } /// The type of a message. #[derive(Clone, Debug, Eq, PartialEq)] pub struct MessageType(String); impl MessageType { /// Returns the interior data as a borrowed string. pub fn as_str(&self) -> &str { self.0.as_str() } } impl fmt::Display for MessageType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } } impl From<String> for MessageType { fn from(value: String) -> Self { Self(value) } } impl From<&str> for MessageType { fn from(value: &str) -> Self { Self(value.to_string()) } } #[cfg(feature = "nats-headers")] impl From<&async_nats::HeaderValue> for MessageType { fn from(value: &async_nats::HeaderValue) -> Self { Self::from(value.as_str()) } } /// The version of a message. #[derive(Clone, Debug, Eq, PartialEq)] pub struct MessageVersion(u64); impl MessageVersion { /// Returns the interior data as an unsigned integer. pub fn as_u64(&self) -> u64 { self.0 } } impl fmt::Display for MessageVersion { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) } } impl From<u64> for MessageVersion { fn from(value: u64) -> Self { Self(value) } } impl FromStr for MessageVersion { type Err = ParseIntError; fn from_str(s: &str) -> Result<Self, Self::Err> { u64::from_str(s).map(Self) } } #[cfg(feature = "nats-headers")] impl TryFrom<&async_nats::HeaderValue> for MessageVersion { type Error = ParseIntError; fn try_from(value: &async_nats::HeaderValue) -> Result<Self, Self::Error> { Self::from_str(value.as_str()) } }

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