alef 0.114.0

Opinionated polyglot binding generator for Rust libraries
Documentation
use crate::codegen::naming::{internal_rust_identifier, pascal_to_snake, to_class_name};
use crate::core::config::{AdapterConfig, ResolvedCrateConfig};

pub(crate) fn generate_body(
    adapter: &AdapterConfig,
    config: &ResolvedCrateConfig,
    typed_error: bool,
) -> anyhow::Result<(String, Option<String>)> {
    let body = crate::backends::dart::template_env::render(
        "rust_streaming_body.rs.jinja",
        crate::alef_context! {
            core_call => crate::adapters::rust_callable::receiver_call(&adapter.core_path, "inner", "&inner", &super::call_args(adapter).join(", "))?,
            item_type => adapter.item_type.as_deref().unwrap_or("()"),
            call_args => super::call_args(adapter).join(", "),
            bindings => super::core_let_bindings(adapter, &config.core_import_name()),
            transport => typed_error.then(|| transport_names(adapter)),
        },
    );
    Ok((body, None))
}

#[derive(serde::Serialize)]
pub(crate) struct StreamTransport {
    pub carrier: String,
    pub wire: String,
    pub module: String,
    pub converter: String,
    pub decoder: String,
    pub unit_item: bool,
}

pub(crate) fn transport_names(adapter: &AdapterConfig) -> StreamTransport {
    let owner = adapter.owner_type.as_deref().unwrap_or("Module");
    let stem = to_class_name(&format!("{owner}_{}", adapter.name));
    let module = internal_rust_identifier(&format!("alef_stream_{}", pascal_to_snake(&stem)));
    StreamTransport {
        carrier: internal_rust_identifier(&format!("AlefStream{stem}")),
        wire: internal_rust_identifier(&format!("AlefStream{stem}Wire")),
        converter: internal_rust_identifier(&format!("alef_encode_stream_{}", pascal_to_snake(&stem))),
        decoder: internal_rust_identifier(&format!("alef_decode_stream_{}", pascal_to_snake(&stem))),
        unit_item: syn::parse_str::<syn::Type>(adapter.item_type.as_deref().unwrap_or("()"))
            .is_ok_and(|ty| matches!(ty, syn::Type::Tuple(tuple) if tuple.elems.is_empty())),
        module,
    }
}