ferment-sys 0.2.14

Syntax tree morphing of FFI-compatible stuff
Documentation
use std::fmt::Debug;
use quote::ToTokens;
use crate::composable::FieldComposer;
use crate::composer::{SourceComposable, ConversionFromComposer, ConversionToComposer, ConversionDropComposer};
use crate::context::ScopeContext;
use crate::ext::ToType;
use crate::lang::Specification;
use crate::presentable::{Expression, ScopeContextPresentable};
use crate::presentation::{FFIFullDictionaryPath, FFIFullPath, Name};

#[derive(Clone, Debug)]
pub enum Conversion<SPEC>
    where SPEC: Specification {
    From(FieldComposer<SPEC>, Option<SPEC::Expr>),
    To(FieldComposer<SPEC>, Option<SPEC::Expr>),
    Destroy(FieldComposer<SPEC>, Option<SPEC::Expr>),
}

impl<SPEC> Conversion<SPEC>
    where SPEC: Specification {
    pub fn expr_from(composer: &FieldComposer<SPEC>, expr: Option<SPEC::Expr>) -> Self {
        Self::From(composer.clone(), expr)
    }
    pub fn expr_to(composer: &FieldComposer<SPEC>, expr: Option<SPEC::Expr>) -> Self {
        Self::To(composer.clone(), expr)
    }
    pub fn expr_destroy(composer: &FieldComposer<SPEC>, expr: Option<SPEC::Expr>) -> Self {
        Self::Destroy(composer.clone(), expr)
    }
}

impl<SPEC> SourceComposable for Conversion<SPEC>
    where SPEC: Specification<Expr=Expression<SPEC>, Name=Name<SPEC>>,
          SPEC::Expr: ScopeContextPresentable,
          Name<SPEC>: ToTokens,
          FFIFullPath<SPEC>: ToType,
          FFIFullDictionaryPath<SPEC>: ToType
{
    type Source = ScopeContext;
    type Output = SPEC::Expr;

    fn compose(&self, source: &Self::Source) -> Self::Output {
        match self {
            Conversion::From(composer, expr) =>
                ConversionFromComposer::<SPEC>::key_ref_expr_in_composer_scope(&composer.name, composer.ty(), expr.clone())
                    .compose(source),
            Conversion::To(composer, expr) =>
                ConversionToComposer::<SPEC>::key_ref_expr_in_composer_scope(&composer.name, composer.ty(), expr.clone())
                    .compose(source),
            Conversion::Destroy(composer, expr) =>
                ConversionDropComposer::<SPEC>::key_ref_expr_in_composer_scope(&composer.name, composer.ty(), expr.clone())
                    .compose(source)
                    .unwrap_or_default(),
        }
    }
}