rialo-sol-syn 0.4.2

Sol syntax parsing and code generation tools
// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use heck::ToSnakeCase;
use proc_macro2::TokenStream;
use quote::{format_ident, quote};

use super::common::{gen_print_section, get_idl_module_path};
use crate::Error;

pub fn gen_idl_print_fn_error(error: &Error) -> TokenStream {
    let idl = get_idl_module_path();

    let fn_name = format_ident!(
        "__sol_private_print_idl_error_{}",
        error.ident.to_string().to_snake_case()
    );
    let fn_name_test = format_ident!("{}__test", fn_name);
    let slice_entry = format_ident!(
        "__SOL_IDL_ENTRY_{}",
        error.ident.to_string().to_snake_case().to_uppercase()
    );

    let error_codes = error
        .codes
        .iter()
        .map(|code| {
            let id = code.id;
            let name = code.ident.to_string();
            let msg = match &code.msg {
                Some(msg) => quote! { Some(#msg.into()) },
                None => quote! { None },
            };

            quote! {
                #idl::IdlErrorCode {
                    code: rialo_sol_lang::error::ERROR_CODE_OFFSET + #id,
                    name: #name.into(),
                    msg: #msg,
                }
            }
        })
        .collect::<Vec<_>>();
    let fn_body = gen_print_section("errors", quote! { vec![#(#error_codes),*] });

    quote! {
        #[doc(hidden)]
        #[cfg(feature = "idl-build")]
        pub fn #fn_name() {
            #fn_body
        }

        // Register this IDL print function in the distributed slice for discovery.
        #[cfg(feature = "idl-build")]
        #[allow(unsafe_code)]
        #[rialo_sol_lang::linkme::distributed_slice(rialo_sol_lang::__SOL_IDL_PRINT_FNS)]
        #[linkme(crate = rialo_sol_lang::linkme)]
        #[doc(hidden)]
        static #slice_entry: (fn(), &'static str) = (#fn_name, module_path!());

        #[cfg(feature = "idl-build")]
        #[test]
        fn #fn_name_test() {
            #fn_name();
        }
    }
}