Skip to main content
Glama
lib.rs5.14 kB
#[cfg(test)] mod tests { use acceptable::{ AllVersions, Container, CurrentContainer, DeserializeContainer, IntoContainer, RequestId, SerializeContainer, SupportsContainers as _, UpgradeError, Versioned, }; use serde::{ Deserialize, Serialize, }; #[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq, Versioned)] #[serde(rename_all = "camelCase")] #[acceptable(version = 1)] struct CoolRequestV1 { id: RequestId, } #[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq, Versioned)] #[serde(rename_all = "camelCase")] #[acceptable(version = 2)] struct CoolRequestV2 { id: RequestId, } impl TryFrom<CoolRequestV1> for CoolRequestV2 { type Error = UpgradeError; fn try_from(value: CoolRequestV1) -> Result<Self, Self::Error> { Ok(Self { id: value.id }) } } #[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq, Versioned)] #[serde(rename_all = "camelCase")] #[acceptable(version = 3)] struct CoolRequestV3 { id: RequestId, name: String, } impl TryFrom<CoolRequestV2> for CoolRequestV3 { type Error = UpgradeError; fn try_from(value: CoolRequestV2) -> Result<Self, Self::Error> { Ok(Self { id: value.id, name: "<unknown>".to_string(), }) } } #[derive(Clone, Debug, Deserialize, Eq, Serialize, PartialEq, Versioned)] #[serde(rename_all = "camelCase")] #[acceptable(version = 4)] struct CoolRequestV4 { id: RequestId, name: String, organization: Option<String>, } impl TryFrom<CoolRequestV3> for CoolRequestV4 { type Error = UpgradeError; fn try_from(value: CoolRequestV3) -> Result<Self, Self::Error> { Ok(Self { id: value.id, name: value.name, organization: None, }) } } #[derive(AllVersions, CurrentContainer, Debug, Deserialize)] #[serde(rename_all = "camelCase")] enum CoolRequestAllVersions { V1(CoolRequestV1), V2(CoolRequestV2), V3(CoolRequestV3), #[acceptable(current)] V4(CoolRequestV4), } impl IntoContainer for CoolRequestAllVersions { type Container = CoolRequest; fn into_container(mut self) -> Result<Self::Container, UpgradeError> { loop { match self { Self::V1(inner) => self = Self::V2(CoolRequestV2::try_from(inner)?), Self::V2(inner) => self = Self::V3(CoolRequestV3::try_from(inner)?), Self::V3(inner) => self = Self::V4(CoolRequestV4::try_from(inner)?), Self::V4(inner) => return Ok(Self::Container::new(inner)), } } } } #[test] fn derived_types() { assert!(CoolRequest::is_message_type_supported("CoolRequest")); assert!(!CoolRequest::is_message_type_supported("Nope")); assert!(CoolRequest::is_content_type_supported("application/cbor")); assert!(!CoolRequest::is_content_type_supported("text/plain")); assert!(CoolRequest::is_message_version_supported(1)); assert!(CoolRequest::is_message_version_supported(2)); assert!(CoolRequest::is_message_version_supported(3)); assert!(CoolRequest::is_message_version_supported(4)); assert!(!CoolRequest::is_message_version_supported(0)); assert!(!CoolRequest::is_message_version_supported(5)); assert!(!CoolRequest::is_message_version_supported(42)); let older_request = CoolRequestAllVersions::V2(CoolRequestV2 { id: RequestId::new(), }); // Older version is queryable assert_eq!(older_request.version(), 2); dbg!(&older_request); // Older version can be upgraded into container type let mut request = older_request.into_container().expect("failed to upgrade"); // Current version container type is queryable assert_eq!(request.version(), 4); assert_eq!(CoolRequest::message_version(), 4); // Current version has upgraded logic data assert_eq!(request.organization, None); dbg!(&request); // Current version can be mutated request.organization = Some("acme".to_string()); assert_eq!(request.organization, Some("acme".to_string())); dbg!(&request); // Current container type can serialize let bytes = request.to_json_vec().expect("failed to serialize"); let json_s = String::from_utf8(bytes.clone()).expect("failed to decode utf8 string"); dbg!(json_s); // Serialized bytes can be deserialized via `AllVersions` helper back into current // container type let de_request = CoolRequest::from_json_slice(&bytes).expect("failed to deserialize"); dbg!(&de_request); assert_eq!(request, de_request); } }

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