ferment_sys/presentable/
sequence.rs1use 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