ferment-sys 0.2.14

Syntax tree morphing of FFI-compatible stuff
Documentation
use std::clone::Clone;
use syn::Field;
use crate::ast::CommaPunctuated;
use crate::composable::FieldComposer;
use crate::composer::{ArgComposers, AspectSharedComposerLink, AttrComposable, CommaArgComposers, CommaPunctuatedFields, ComposerLink, CtorSpec, FFIBindingsComposer, FFIBindingsComposerLink, FFIComposer, FFIComposerLink, ArgProducerByRef, FieldPathConversionResolveSpec, FieldPathResolver, FieldsContext, FieldsSequenceMixer, GenericsComposable, ItemComposerExprSpec, ItemComposerSpec, OwnedArgComposers, MethodComposer, NameKindComposable, OwnerAspectSequenceSpec, ArgKindPair, PresentableExprComposerRef, RootSequenceComposer, SequenceComposer, SequenceSharedComposerLink, SourceAccessible, SourceComposerByRef, TypeAspect, IterativeComposer, ItemAspectsSpec, LifetimesComposable};
use crate::composer::r#abstract::SequenceMixer;
use crate::lang::Specification;
use crate::presentable::{ArgKind, Aspect, BindingPresentableContext, InterfaceKind};

pub(crate) const fn args_composer_iterator_root<SPEC, CTX, Item, OUT>()
    -> SourceComposerByRef<OwnedArgComposers<SPEC, CTX>, ArgProducerByRef<SPEC, Item>, (CTX, OUT)>
    where CTX: Clone,
          OUT: FromIterator<Item>,
          SPEC: Specification {
    |(aspect, arg_composers), composer|
        (aspect.clone(), arg_conversions_iterator(arg_composers, composer))
}

pub(crate) fn arg_conversion_expressions_iterator<SPEC, Iter>(
    (arg_composers, expr_composer): (&CommaArgComposers<SPEC>, PresentableExprComposerRef<SPEC>),
    resolver: FieldPathResolver<SPEC>
) -> Iter
where Iter: FromIterator<ArgKind<SPEC>>,
      SPEC: Specification {
    arg_conversions_iterator(arg_composers, |c| ArgKind::attr_expr_composer(c, resolver, expr_composer))
}


pub fn field_composers_iterator<SPEC, MAP>(
    fields: &CommaPunctuatedFields,
    mapper: MAP
) -> CommaArgComposers<SPEC>
    where MAP: Fn(&Field, usize) -> FieldComposer<SPEC>,
          SPEC: Specification {
    CommaPunctuated::from_iter(fields.iter().enumerate().map(|(index, field)| mapper(field, index)))
}
pub fn arg_conversions_iterator<SPEC, MAP, Out, Iter, SEP>(
    composers: &ArgComposers<SPEC, SEP>,
    mapper: MAP
) -> Iter
    where MAP: Fn(&FieldComposer<SPEC>) -> Out,
          Iter: FromIterator<Out>,
          SPEC: Specification {
    Iter::from_iter(composers.iter().map(mapper))
}


pub(crate) const fn ffi_conversions_composer<SPEC, T, C>(
    from_ffi_root: RootSequenceComposer<SPEC>,
    from_context: SequenceSharedComposerLink<SPEC, T>,
    from_aspect: AspectSharedComposerLink<SPEC, T>,
    to_ffi_root: RootSequenceComposer<SPEC>,
    to_context: SequenceSharedComposerLink<SPEC, T>,
    drop_root: RootSequenceComposer<SPEC>,
    drop_context: SequenceSharedComposerLink<SPEC, T>,
) -> FFIComposerLink<SPEC, T>
    where T: FieldsContext<SPEC> + AttrComposable<SPEC::Attr> + LifetimesComposable<SPEC::Lt> + TypeAspect<SPEC::TYC> + GenericsComposable<SPEC::Gen> + NameKindComposable,
          C: ItemComposerSpec<SPEC> + ItemComposerExprSpec<SPEC> + FieldPathConversionResolveSpec<SPEC>,
          SPEC: Specification {
    FFIComposer::new(
        InterfaceKind::From(FieldsSequenceMixer::with_sequence(
            from_ffi_root,
            from_context,
            SequenceComposer::new(
                C::FROM_ROOT_CONVERSION_PRESENTER,
                from_aspect,
                IterativeComposer::new(
                |(aspect, field_composers), expr_composer|
                    (aspect.clone(), arg_conversion_expressions_iterator((field_composers, expr_composer), C::FROM)),
                C::FROM_CONVERSION)))),

        InterfaceKind::To(FieldsSequenceMixer::with_sequence(
            to_ffi_root,
            to_context,
            SequenceComposer::new(
                C::TO_ROOT_CONVERSION_PRESENTER,
                Aspect::ffi,
                IterativeComposer::new(
                |(aspect, field_composers), expr_composer|
                    (aspect.clone(), arg_conversion_expressions_iterator((field_composers, expr_composer), C::TO)),
                C::TO_CONVERSION)))),
        InterfaceKind::Drop(FieldsSequenceMixer::with_sequence(
            drop_root,
            drop_context,
            SequenceComposer::new(
                C::DROP_ROOT_CONVERSION_PRESENTER,
                Aspect::ffi,
                IterativeComposer::new(|(aspect, field_composers), expr_composer|
                    (aspect.clone(), arg_conversion_expressions_iterator((field_composers, expr_composer), C::DROP)),
                C::DROP_CONVERSION))))

    )
}
#[allow(unused)]
pub(crate) const fn ffi_conversions_composer2<SPEC, T, C>(
    from_ffi_root: RootSequenceComposer<SPEC>,
    from_context: SequenceSharedComposerLink<SPEC, T>,
    from_aspect: AspectSharedComposerLink<SPEC, T>,
    to_ffi_root: RootSequenceComposer<SPEC>,
    to_context: SequenceSharedComposerLink<SPEC, T>,
    drop_root: RootSequenceComposer<SPEC>,
    drop_context: SequenceSharedComposerLink<SPEC, T>,
) -> FFIComposerLink<SPEC, T>
    where T: FieldsContext<SPEC> + AttrComposable<SPEC::Attr> + LifetimesComposable<SPEC::Lt> + TypeAspect<SPEC::TYC> + GenericsComposable<SPEC::Gen> + NameKindComposable,
          C: ItemAspectsSpec<SPEC>,
          SPEC: Specification {
    FFIComposer::new(
        InterfaceKind::From(
            SequenceMixer::with_sequence(
                from_ffi_root,
                from_context,
                SequenceComposer::interface_method_spec::<C::FROM>(from_aspect))),
        InterfaceKind::To(
            SequenceMixer::with_sequence(
                to_ffi_root,
                to_context,
                SequenceComposer::interface_method_spec::<C::INTO>(Aspect::ffi))),
        InterfaceKind::Drop(
            SequenceMixer::with_sequence(
                drop_root,
                drop_context,
                SequenceComposer::interface_method_spec::<C::DTOR>(Aspect::ffi))),
    )
}

pub(crate) const fn ffi_bindings_composer<SPEC, T, C, Iter>()
    -> FFIBindingsComposerLink<SPEC, T, Iter>
    where SPEC: Specification,
          T: AttrComposable<SPEC::Attr>
          + LifetimesComposable<SPEC::Lt>
          + GenericsComposable<SPEC::Gen>
          + TypeAspect<SPEC::TYC>
          + FieldsContext<SPEC>
          + NameKindComposable
          + SourceAccessible
          + 'static,
          C: CtorSpec<SPEC, ComposerLink<T>, Iter>,
          Iter: FromIterator<Iter::Item> + IntoIterator<Item=ArgKindPair<SPEC>> {
    FFIBindingsComposer::new(
        C::COMPOSER,
        MethodComposer::new(Aspect::ffi, BindingPresentableContext::dtor),
        MethodComposer::new(Aspect::ffi, BindingPresentableContext::get),
        MethodComposer::new(Aspect::ffi, BindingPresentableContext::set),
        true
    )
}
#[allow(unused)]
pub(crate) const fn ffi_bindings_composer2<SPEC, T, C, Iter>()
    -> FFIBindingsComposerLink<SPEC, T, Iter>
    where SPEC: Specification,
          T: AttrComposable<SPEC::Attr>
          + LifetimesComposable<SPEC::Lt>
              + GenericsComposable<SPEC::Gen>
              + TypeAspect<SPEC::TYC>
              + FieldsContext<SPEC>
              + NameKindComposable
              + SourceAccessible
              + 'static,
          C: OwnerAspectSequenceSpec<SPEC, ComposerLink<T>, Iter, ArgKindPair<SPEC>, BindingPresentableContext<SPEC>>,
          Iter: FromIterator<Iter::Item> + IntoIterator<Item=ArgKindPair<SPEC>> {
    FFIBindingsComposer::new(
        C::COMPOSER,
        MethodComposer::new(Aspect::ffi, BindingPresentableContext::dtor),
        MethodComposer::new(Aspect::ffi, BindingPresentableContext::get),
        MethodComposer::new(Aspect::ffi, BindingPresentableContext::set),
        true
    )
}


// #[allow(unused)]
// pub const fn fields_sequence<SPEC, T, C, Iter>()
//     -> ArgsSequenceComposer<SPEC, ComposerLink<T>, AspectArgComposers<SPEC>, Iter::Item, OwnerAspectSequence<SPEC, Iter>, SeqKind<SPEC>>
//     where C: OwnerAspectSequenceSpec<SPEC, ComposerLink<T>, Iter, ArgKind<SPEC>, SeqKind<SPEC>>,
//     T: AttrComposable<SPEC::Attr>
//         + GenericsComposable<SPEC::Gen>
//         + TypeAspect<SPEC::TYC>
//         + NameKindComposable
//         + FieldsContext<SPEC>
//         + FieldsConversionComposable<SPEC>
//         + SourceAccessible
//         + 'static,
//     SPEC: Specification,
//     Iter: FromIterator<Iter::Item> + IntoIterator<Item=ArgKind<SPEC>> {
//     SequenceComposer::owner_aspect_sequence_spec::<C>()
// }