ferment_sys/presentable/
sequence.rs

1use std::fmt::Debug;
2use proc_macro2::Ident;
3use quote::ToTokens;
4use syn::Type;
5use ferment_macro::Display;
6use crate::ast::CommaPunctuated;
7use crate::composer::{AspectCommaPunctuatedArgKinds, AttrComposable, TypeAspect, VariantComposable, FieldsConversionComposable, SourceComposable, ComposerLinkRef, AspectTerminatedArgKinds, AspectPresentableArgKinds, CommaPunctuatedArgKinds};
8use crate::lang::Specification;
9use crate::presentable::Aspect;
10
11
12#[derive(Clone, Debug, Display)]
13pub enum SeqKind<SPEC>
14    where SPEC: Specification {
15    FromStub(AspectCommaPunctuatedArgKinds<SPEC>),
16    FromNamedFields(AspectCommaPunctuatedArgKinds<SPEC>),
17    ToNamedFields(AspectCommaPunctuatedArgKinds<SPEC>),
18    FromUnnamedFields(AspectCommaPunctuatedArgKinds<SPEC>),
19    TraitImplFnCall(((Type, Type, Ident), CommaPunctuatedArgKinds<SPEC>)),
20    ToUnnamedFields(AspectCommaPunctuatedArgKinds<SPEC>),
21    ToStub(AspectCommaPunctuatedArgKinds<SPEC>),
22    NamedVariantFields(AspectCommaPunctuatedArgKinds<SPEC>),
23    UnnamedVariantFields(AspectCommaPunctuatedArgKinds<SPEC>),
24    EnumUnitFields(AspectCommaPunctuatedArgKinds<SPEC>),
25
26    Variants(Aspect<SPEC::TYC>, SPEC::Attr, CommaPunctuated<SeqKind<SPEC>>),
27    Unit(Aspect<SPEC::TYC>),
28    NoFieldsConversion(Aspect<SPEC::TYC>),
29    TypeAliasFromConversion(AspectCommaPunctuatedArgKinds<SPEC>),
30    NamedStruct(AspectCommaPunctuatedArgKinds<SPEC>),
31    UnnamedStruct(AspectCommaPunctuatedArgKinds<SPEC>),
32    StubStruct(AspectCommaPunctuatedArgKinds<SPEC>),
33    Enum(Box<SeqKind<SPEC>>),
34
35    StructFrom(Box<SeqKind<SPEC>>, Box<SeqKind<SPEC>>),
36    StructTo(Box<SeqKind<SPEC>>, Box<SeqKind<SPEC>>),
37
38    EnumVariantFrom(Box<SeqKind<SPEC>>, Box<SeqKind<SPEC>>),
39    EnumVariantTo(Box<SeqKind<SPEC>>, Box<SeqKind<SPEC>>),
40    EnumVariantDrop(Box<SeqKind<SPEC>>, Box<SeqKind<SPEC>>),
41
42    DerefFFI,
43    Obj,
44    Empty,
45
46    DropStub(AspectTerminatedArgKinds<SPEC>),
47    StructDropBody(AspectTerminatedArgKinds<SPEC>),
48    DropCode(AspectTerminatedArgKinds<SPEC>),
49}
50
51impl<SPEC> SeqKind<SPEC>
52    where SPEC: Specification {
53    pub fn struct_to(field_path: &SeqKind<SPEC>, conversions: SeqKind<SPEC>) -> Self {
54        Self::StructTo(field_path.clone().into(), conversions.into())
55    }
56    pub fn struct_from(field_path: &SeqKind<SPEC>, conversions: SeqKind<SPEC>) -> Self {
57        Self::StructFrom(field_path.clone().into(), conversions.into())
58    }
59    pub fn variant_from(left: &SeqKind<SPEC>, right: SeqKind<SPEC>) -> Self {
60        Self::EnumVariantFrom(left.clone().into(), right.clone().into())
61    }
62    pub fn variant_to(left: &SeqKind<SPEC>, right: SeqKind<SPEC>) -> Self {
63        Self::EnumVariantTo(left.clone().into(), right.clone().into())
64    }
65    pub fn variant_drop(left: &SeqKind<SPEC>, right: SeqKind<SPEC>) -> Self {
66        Self::EnumVariantDrop(left.clone().into(), right.clone().into())
67    }
68    pub fn struct_drop_post_processor(_: &SeqKind<SPEC>, right: SeqKind<SPEC>) -> Self {
69        right
70    }
71
72    pub fn no_fields<SEP: ToTokens>(((aspect, ..), _): AspectPresentableArgKinds<SPEC, SEP>) -> Self {
73        Self::NoFieldsConversion(match &aspect {
74            Aspect::Target(context) => Aspect::RawTarget(context.clone()),
75            _ => aspect.clone(),
76        })
77    }
78    pub fn unit(((aspect, ..), _): &AspectCommaPunctuatedArgKinds<SPEC>) -> Self {
79        Self::Unit(aspect.clone())
80    }
81    pub fn variants<C>(composer_ref: &ComposerLinkRef<C>) -> Self
82        where C: AttrComposable<SPEC::Attr> + TypeAspect<SPEC::TYC> + VariantComposable<SPEC> {
83        Self::Variants(C::target_type_aspect(composer_ref), C::compose_attributes(composer_ref), C::compose_variants(composer_ref))
84    }
85    pub fn deref_ffi<C>(_ctx: &ComposerLinkRef<C>) -> Self {
86        Self::DerefFFI
87    }
88    pub fn empty<C>(_ctx: &ComposerLinkRef<C>) -> Self {
89        Self::Empty
90    }
91    pub fn obj<C>(_ctx: &ComposerLinkRef<C>) -> Self {
92        Self::Obj
93    }
94    pub fn unit_fields(context: &AspectCommaPunctuatedArgKinds<SPEC>) -> Self {
95        Self::EnumUnitFields(context.clone())
96    }
97    pub fn brace_variants(context: &AspectCommaPunctuatedArgKinds<SPEC>) -> Self {
98        Self::NamedVariantFields(context.clone())
99    }
100    pub fn paren_variants(context: &AspectCommaPunctuatedArgKinds<SPEC>) -> Self {
101        Self::UnnamedVariantFields(context.clone())
102    }
103    pub fn empty_root(_: SeqKind<SPEC>) -> Self {
104        Self::Empty
105    }
106    pub fn bypass(sequence: SeqKind<SPEC>) -> Self {
107        sequence
108    }
109    pub fn r#enum(context: SeqKind<SPEC>) -> Self {
110        Self::Enum(Box::new(context))
111    }
112    pub fn fields_from<C>(ctx: &ComposerLinkRef<C>) -> Self
113        where C: FieldsConversionComposable<SPEC> + 'static {
114        ctx.fields_from().compose(&())
115    }
116    pub fn fields_to<C>(ctx: &ComposerLinkRef<C>) -> Self
117        where C: FieldsConversionComposable<SPEC> + 'static {
118        ctx.fields_to().compose(&())
119    }
120}
121