1use itertools::Itertools;
2use proc_macro2::TokenStream;
3use quote::quote;
4use syn::{
5 Error,
6 Path,
7};
8
9use crate::{
10 format_err_spanned,
11 utils::into_u32,
12};
13
14pub fn generate(input: TokenStream) -> Result<TokenStream, Error> {
15 let path: Path = syn::parse2(input)?;
16
17 match path.segments.len() {
18 1 => {
19 let extension = path.segments.first().unwrap();
20
21 Ok(quote! {
22 <dyn #extension as ::obce::codegen::ExtensionDescription>::ID
23 })
24 }
25 2 => {
26 let (extension, method) = path.segments.iter().tuple_windows().next().unwrap();
27
28 let method_hash = into_u32(&method.ident);
29
30 Ok(quote! {
31 <dyn #extension as ::obce::codegen::MethodDescription<#method_hash>>::ID
32 })
33 }
34 _ => {
38 return Err(format_err_spanned!(
39 path,
40 "id macro supports only two-segment paths (ChainExtension, ChainExtension::method)"
41 ))
42 }
43 }
44}