rustra-macros 0.11.0

Rust → TypeScript bridge framework with auto-generated type-safe clients
Documentation
/// `build!` 매크로의 파싱 결과입니다.
///
/// 형태: `"package.name", <fn_ident>, <fn_ident>, ...`
struct BuildInput {
    package_name: LitStr,
    commands: Vec<Ident>,
}

impl Parse for BuildInput {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        let package_name: LitStr = input.parse()?;
        let _: Token![,] = input.parse()?;

        let mut commands = Vec::new();
        loop {
            if input.is_empty() {
                break;
            }
            let name: Ident = input.parse()?;
            commands.push(name);
            if input.parse::<Token![,]>().is_err() {
                break;
            }
        }

        if commands.is_empty() {
            return Err(syn::Error::new(
                package_name.span(),
                "build! requires at least one command function after the package name",
            ));
        }

        Ok(BuildInput {
            package_name,
            commands,
        })
    }
}

/// `#[command]` 함수들을 간결하게 등록하는 매크로입니다.
///
/// `register!(Package::builder("name"), fn1, fn2).build()` 대신
/// `rustra::build!("name", fn1, fn2).done()`을 사용할 수 있습니다.
///
/// ## 예제
///
/// ```rust
/// use rustra::prelude::*;
///
/// #[bridge_type]
/// struct AddInput { a: i64, b: i64 }
/// #[bridge_type]
/// struct AddOutput { sum: i64 }
///
/// #[command]
/// fn add_numbers(input: AddInput) -> Result<AddOutput> {
///     Ok(AddOutput { sum: input.a + input.b })
/// }
///
/// let pkg = rustra::build!("com.example.my", add_numbers).done();
/// ```
#[proc_macro]
pub fn build(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as BuildInput);

    let package_name = &input.package_name;
    let chain: TokenStream2 = input
        .commands
        .iter()
        .map(command_chain_entry)
        .collect();

    let expanded = quote! {
        rustra::Package::builder(#package_name) #chain
    };

    expanded.into()
}