Skip to main content
Glama
all_versions.rs3.29 kB
use std::str::FromStr; use darling::FromAttributes; use manyhow::{ Result, bail, emit, }; use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::quote; use syn::{ Data, DataEnum, DeriveInput, Error, Fields, Ident, }; #[derive(Debug, FromAttributes)] #[darling(attributes(acceptable))] struct Config {} pub(crate) fn expand(input: TokenStream, errors: &mut manyhow::Emitter) -> Result<TokenStream2> { let input = syn::parse::<DeriveInput>(input)?; let DeriveInput { ident, data, attrs, .. } = input; let config = Config::from_attributes(&attrs)?; match data { Data::Enum(data_enum) => derive_from_enum(ident, data_enum, config, errors), Data::Struct(_) | Data::Union(_) => { bail!("current only enum types are supported for `#[derive(AllVersions)]`") } } } fn derive_from_enum( ident: Ident, data: DataEnum, _config: Config, errors: &mut manyhow::Emitter, ) -> Result<TokenStream2> { let mut versions = Vec::with_capacity(data.variants.len()); let mut variants = Vec::with_capacity(versions.len()); for variant in &data.variants { let variant_ident = &variant.ident; let variant_name = variant_ident.to_string(); if !variant_name.starts_with('V') { emit!( errors, Error::new_spanned(variant, "variant name must begin with 'V'") ); continue; } let Ok(variant_version) = u64::from_str(&variant_name[1..]) else { emit!( errors, Error::new_spanned(variant, "variant name must end with a u64 version number") ); continue; }; let _variant_ty = match &variant.fields { Fields::Unnamed(fields_unnamed) => { let mut iter = fields_unnamed.unnamed.iter(); match (iter.next(), iter.next()) { (Some(field), None) => &field.ty, (None, None) | (None, Some(_)) | (Some(_), Some(_)) => { emit!( errors, Error::new_spanned( variant, "only 1-tuple style variants are supported" ) ); continue; } } } Fields::Named(_) | Fields::Unit => { emit!( errors, Error::new_spanned(variant, "only tuple style variants are supported") ); continue; } }; versions.push(variant_version); variants.push(variant_ident); } errors.into_result()?; Ok(quote! { impl acceptable::AllVersions for #ident { #[inline] fn version(&self) -> u64 { match self { #(Self::#variants(inner) => acceptable::Versioned::version(inner)),* } } #[inline] fn all_versions() -> &'static [u64] { &[#(#versions),*] } } }) }

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