candid
candid copied to clipboard
Add a proc-macro for a string principal constant
Is your feature request related to a problem? Please describe.
Principal::from_text is not const but there's many circumstances in which a principal constant is wanted in code. Principal::from_slice is const but it is much harder to inspect and verify as it just takes a byte slice
Describe the solution you'd like
principal!("...")
Describe alternatives you've considered
Principal::from_slice(&[...]), but as mentioned above, that is less than ideal.
Potential implementation
use candid::Principal;
use proc_macro::TokenStream;
use quote::{quote, ToTokens};
use syn::{parse_macro_input, LitStr, parse::Parse, parse::ParseStream};
struct CandidPrincipal(Principal);
impl Parse for CandidPrincipal {
fn parse(input: ParseStream) -> syn::Result<Self> {
let text = input.parse::<LitStr>()?.value();
Principal::from_text(&text)
.map(Self)
.map_err(|e| syn::Error::new(input.span(), e.to_string()))
}
}
impl ToTokens for CandidPrincipal {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let bytes = self.0.as_slice();
tokens.extend(quote! {
::candid::Principal::from_slice(&[#(#bytes),*])
})
}
}
#[proc_macro]
pub fn principal(tokens: TokenStream) -> TokenStream {
parse_macro_input!(tokens as CandidPrincipal)
.into_token_stream()
.into()
}
syn and quote are dependencies of ic-cdk anyway so this will not have any negative effects on compilation performance