ferment-sys 0.2.14

Syntax tree morphing of FFI-compatible stuff
Documentation
use quote::ToTokens;
use syn::{FnArg, PatType, Receiver, ReturnType, Signature, Type};
use crate::composable::FieldComposer;
use crate::composer::{CommaPunctuatedArgKinds, SignatureAspect, SourceComposable, VarComposer};
use crate::context::ScopeContext;
use crate::ext::ToType;
use crate::lang::Specification;
use crate::presentable::{ArgKind, BindingPresentableContext, Expression, ScopeContextPresentable};
use crate::presentation::{FFIFullDictionaryPath, FFIFullPath, Name};

pub fn compose_trait_inner_fn<SPEC>(
    trait_ty: &Type,
    aspect: SignatureAspect<SPEC>,
    sig: &Signature,
    source: &ScopeContext
) -> BindingPresentableContext<SPEC>
where SPEC: Specification<Expr=Expression<SPEC>, Name=Name<SPEC>>,
      SPEC::Expr: ScopeContextPresentable,
      SPEC::Lt: IntoIterator + Extend<<SPEC::Lt as IntoIterator>::Item>,
      SPEC::Name: ToTokens,
      CommaPunctuatedArgKinds<SPEC>: Extend<ArgKind<SPEC>>,
      FFIFullPath<SPEC>: ToType,
      FFIFullDictionaryPath<SPEC>: ToType,
      VarComposer<SPEC>: SourceComposable<Source=ScopeContext, Output=SPEC::Var> {
    let Signature { output, inputs, .. } = sig;
    let return_type = match output {
        ReturnType::Default => ReturnType::Default,
        ReturnType::Type(_, ty) => ReturnType::Type(Default::default(), Box::new(VarComposer::<SPEC>::key_ref_in_composer_scope(ty).compose(source).to_type()))
    };
    let arguments = CommaPunctuatedArgKinds::from_iter(inputs
        .iter()
        .map(|arg| {
            ArgKind::<SPEC>::inherited_named(match arg {
                FnArg::Receiver(Receiver { attrs, .. }) =>
                    FieldComposer::self_var(VarComposer::<SPEC>::key_ref_in_composer_scope(trait_ty).compose(source), attrs),
                FnArg::Typed(PatType { ty, attrs, pat, .. }) =>
                    FieldComposer::named_typed(Name::pat(pat), ty, attrs)
            })
        }));
    BindingPresentableContext::TraitVTableInnerFn(aspect, sig.ident.clone(), arguments, return_type)
}