cgp-macro-lib 0.7.0

Context-generic programming core component macros implemented as a library.
Documentation
use proc_macro2::{Span, TokenStream};
use quote::{ToTokens, quote};
use syn::spanned::Spanned;
use syn::token::Colon;
use syn::{
    AngleBracketedGenericArguments, Field, FieldValue, Generics, Ident, LitInt, Member, Type,
    parse2,
};

use crate::symbol::symbol_from_string;

pub fn to_generic_args(generics: &Generics) -> syn::Result<AngleBracketedGenericArguments> {
    if generics.params.is_empty() {
        parse2(quote! { < > })
    } else {
        parse2(generics.split_for_impl().1.to_token_stream())
    }
}

pub fn field_to_member(index: usize, field: &Field) -> Member {
    match &field.ident {
        Some(ident) => Member::Named(ident.clone()),
        None => Member::Unnamed(index.into()),
    }
}

pub fn field_to_tag(index: usize, field: &Field) -> syn::Result<Type> {
    match &field.ident {
        Some(ident) => Ok(symbol_from_string(&ident.to_string())),
        None => {
            let index = LitInt::new(&format!("{index}"), field.span());
            parse2(quote! { δ< #index > })
        }
    }
}

pub fn index_to_generic_ident(index: usize) -> Ident {
    Ident::new(&format!("__F{index}__"), Span::call_site())
}

pub fn field_value_expr(field_member: Member, expr: TokenStream) -> syn::Result<FieldValue> {
    Ok(FieldValue {
        attrs: Vec::new(),
        member: field_member,
        colon_token: Some(Colon(Span::call_site())),
        expr: parse2(expr)?,
    })
}