use anyhow::{bail, Error}; use proc_macro2::{Span, TokenStream}; use quote::quote; use syn::punctuated::Punctuated; use syn::{Expr, ExprLit, Ident, Lit, Meta, MetaNameValue, Token};
/// Returns a statement which encodes the map field. pubfn encode(&self, ident: TokenStream) -> TokenStream { let tag = self.tag; let key_mod = self.key_ty.module(); let ke = quote!(::prost::encoding::#key_mod::encode); let kl = quote!(::prost::encoding::#key_mod::encoded_len); let module = self.map_ty.module(); match &self.value_ty {
ValueTy::Scalar(scalar::Ty::Enumeration(ty)) => { let default = quote!(#ty::default() as i32);
quote! {
::prost::encoding::#module::encode_with_default( #ke, #kl,
::prost::encoding::int32::encode,
::prost::encoding::int32::encoded_len,
&(#default), #tag,
&#ident,
buf,
);
}
}
ValueTy::Scalar(value_ty) => { let val_mod = value_ty.module(); let ve = quote!(::prost::encoding::#val_mod::encode); let vl = quote!(::prost::encoding::#val_mod::encoded_len);
quote! {
::prost::encoding::#module::encode( #ke, #kl, #ve, #vl, #tag,
&#ident,
buf,
);
}
}
ValueTy::Message => quote! {
::prost::encoding::#module::encode( #ke, #kl,
::prost::encoding::message::encode,
::prost::encoding::message::encoded_len, #tag,
&#ident,
buf,
);
},
}
}
/// Returns an expression which evaluates to the result of merging a decoded key value pair /// into the map. pubfn merge(&self, ident: TokenStream) -> TokenStream { let key_mod = self.key_ty.module(); let km = quote!(::prost::encoding::#key_mod::merge); let module = self.map_ty.module(); match &self.value_ty {
ValueTy::Scalar(scalar::Ty::Enumeration(ty)) => { let default = quote!(#ty::default() as i32);
quote! {
::prost::encoding::#module::merge_with_default( #km,
::prost::encoding::int32::merge, #default,
&mut#ident,
buf,
ctx,
)
}
}
ValueTy::Scalar(value_ty) => { let val_mod = value_ty.module(); let vm = quote!(::prost::encoding::#val_mod::merge);
quote!(::prost::encoding::#module::merge(#km, #vm, &mut#ident, buf, ctx))
}
ValueTy::Message => quote! {
::prost::encoding::#module::merge( #km,
::prost::encoding::message::merge,
&mut#ident,
buf,
ctx,
)
},
}
}
/// Returns an expression which evaluates to the encoded length of the map. pubfn encoded_len(&self, ident: TokenStream) -> TokenStream { let tag = self.tag; let key_mod = self.key_ty.module(); let kl = quote!(::prost::encoding::#key_mod::encoded_len); let module = self.map_ty.module(); match &self.value_ty {
ValueTy::Scalar(scalar::Ty::Enumeration(ty)) => { let default = quote!(#ty::default() as i32);
quote! {
::prost::encoding::#module::encoded_len_with_default( #kl,
::prost::encoding::int32::encoded_len,
&(#default), #tag,
&#ident,
)
}
}
ValueTy::Scalar(value_ty) => { let val_mod = value_ty.module(); let vl = quote!(::prost::encoding::#val_mod::encoded_len);
quote!(::prost::encoding::#module::encoded_len(#kl, #vl, #tag, &#ident))
}
ValueTy::Message => quote! {
::prost::encoding::#module::encoded_len( #kl,
::prost::encoding::message::encoded_len, #tag,
&#ident,
)
},
}
}
/// Returns methods to embed in the message. pubfn methods(&self, ident: &TokenStream) -> Option<TokenStream> { iflet ValueTy::Scalar(scalar::Ty::Enumeration(ty)) = &self.value_ty { let key_ty = self.key_ty.rust_type(); let key_ref_ty = self.key_ty.rust_ref_type();
let get = Ident::new(&format!("get_{}", ident), Span::call_site()); let insert = Ident::new(&format!("insert_{}", ident), Span::call_site()); let take_ref = ifself.key_ty.is_numeric() {
quote!(&)
} else {
quote!()
};
let get_doc = format!( "Returns the enum value for the corresponding key in `{}`, \
or `None` if the entry does not exist or it is not a valid enum value.",
ident,
); let insert_doc = format!("Inserts a key value pair into `{}`.", ident);
Some(quote! { #[doc=#get_doc] pubfn#get(&self, key: #key_ref_ty) -> ::core::option::Option<#ty> { self.#ident.get(#take_ref key).cloned().and_then(|x| { let result: ::core::result::Result<#ty, _> = ::core::convert::TryFrom::try_from(x);
result.ok()
})
} #[doc=#insert_doc] pubfn#insert(&mutself, key: #key_ty, value: #ty) -> ::core::option::Option<#ty> { self.#ident.insert(key, value as i32).and_then(|x| { let result: ::core::result::Result<#ty, _> = ::core::convert::TryFrom::try_from(x);
result.ok()
})
}
})
} else {
None
}
}
/// Returns a newtype wrapper around the map, implementing nicer Debug /// /// The Debug tries to convert any enumerations met into the variants if possible, instead of /// outputting the raw numbers. pubfn debug(&self, wrapper_name: TokenStream) -> TokenStream { let type_name = matchself.map_ty {
MapTy::HashMap => Ident::new("HashMap", Span::call_site()),
MapTy::BTreeMap => Ident::new("BTreeMap", Span::call_site()),
};
// A fake field for generating the debug wrapper let key_wrapper = fake_scalar(self.key_ty.clone()).debug(quote!(KeyWrapper)); let key = self.key_ty.rust_type(); let value_wrapper = self.value_ty.debug(); let libname = self.map_ty.lib(); let fmt = quote! { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { #key_wrapper #value_wrapper letmut builder = f.debug_map(); for (k, v) inself.0 {
builder.entry(&KeyWrapper(k), &ValueWrapper(v));
}
builder.finish()
}
}; match &self.value_ty {
ValueTy::Scalar(ty) => { iflet scalar::Ty::Bytes(_) = *ty { return quote! { struct#wrapper_name<'a>(&'a dyn ::core::fmt::Debug); impl<'a> ::core::fmt::Debug for #wrapper_name<'a> { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { self.0.fmt(f)
}
}
};
}
let value = ty.rust_type();
quote! { struct#wrapper_name<'a>(&'a ::#libname::collections::#type_name<#key, #value>); impl<'a> ::core::fmt::Debug for #wrapper_name<'a> { #fmt
}
}
}
ValueTy::Message => quote! { struct#wrapper_name<'a, V: 'a>(&'a ::#libname::collections::#type_name<#key, V>); impl<'a, V> ::core::fmt::Debug for #wrapper_name<'a, V> where
V: ::core::fmt::Debug + 'a,
{ #fmt
}
},
}
}
}
/// Returns a newtype wrapper around the ValueTy for nicer debug. /// /// If the contained value is enumeration, it tries to convert it to the variant. If not, it /// just forwards the implementation. fn debug(&self) -> TokenStream { matchself {
ValueTy::Scalar(ty) => fake_scalar(ty.clone()).debug(quote!(ValueWrapper)),
ValueTy::Message => quote!( fn ValueWrapper<T>(v: T) -> T {
v
}
),
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-18)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.