1pub(crate) mod rust;
2
3#[cfg(feature = "objc")]
4pub(crate) mod objc;
5
6#[cfg(feature = "java")]
7pub(crate) mod java;
8
9
10use std::fmt::{Debug, Display};
11use proc_macro2::Ident;
12use quote::ToTokens;
13use syn::{Attribute, Generics, Lifetime, Type};
14use crate::composer::VarComposable;
15use crate::error;
16use crate::ext::{Mangle, MangleDefault, ToType};
17use crate::lang::objc::composers::AttrWrapper;
18use crate::presentable::{NameTreeContext, ScopeContextPresentable, TypeContext, Expression, ExpressionComposable};
19use crate::presentation::{DictionaryName, FFIVariable, InterfacePresentation, Name, RustFermentate};
20use crate::tree::CrateTree;
21
22
23pub trait CrateTreeConsumer {
24 fn generate(&self, crate_tree: &CrateTree) -> Result<(), error::Error>;
25}
26
27pub trait FromDictionary {
28 fn dictionary_name(dictionary: DictionaryName) -> Self;
29}
30
31pub trait NameComposable<LANG, SPEC>
32 where LANG: LangFermentable,
33 SPEC: Specification<LANG> {
34 fn ident(ident: Ident) -> Self;
35 fn index(ident: usize) -> Self;
36 fn unnamed_arg(index: usize) -> Self;
37}
38
39pub trait LangFermentable: Clone + Debug {
40 }
42pub trait Specification<LANG>: Clone + Debug
43 where LANG: LangFermentable,
44 {
46 type Attr: Clone + LangAttrSpecification<LANG> + Debug;
47 type Gen: LangGenSpecification<LANG>;
48 type Lt: LangLifetimeSpecification<LANG>;
49 type TYC: NameTreeContext;
50 type Interface: ToTokens;
51 type Expr: ExpressionComposable<LANG, Self>;
52 type Var: VarComposable<LANG, Self> + ToType;
53 type Name: Clone + Default + Display + ToTokens + Mangle<MangleDefault> + FromDictionary + NameComposable<LANG, Self>;
54}
55
56pub trait PresentableSpecification<LANG>:
57 Specification<LANG, Expr=Expression<LANG, Self>>
58 where LANG: LangFermentable,
59 Expression<LANG, Self>: ScopeContextPresentable,
60 <Self::Expr as ScopeContextPresentable>::Presentation: ToTokens {}
61
62impl<LANG, SPEC> PresentableSpecification<LANG> for SPEC
63 where LANG: LangFermentable,
64 SPEC: Specification<LANG, Expr=Expression<LANG, SPEC>>,
65 Expression<LANG, SPEC>: ScopeContextPresentable {}
66
67
68pub trait RustSpecification:
69 PresentableSpecification<RustFermentate,
70 Attr=Vec<Attribute>,
71 Gen=Option<Generics>,
72 Lt=Vec<Lifetime>,
73 Interface=InterfacePresentation,
74 TYC=TypeContext,
75 Expr=Expression<RustFermentate, Self>,
76 Var=FFIVariable<RustFermentate, Self, Type>,
77 Name=Name<RustFermentate, Self>
78 > {}
79
80impl<SPEC> Specification<RustFermentate> for SPEC where SPEC: RustSpecification {
81 type Attr = Vec<Attribute>;
82 type Gen = Option<Generics>;
83 type Lt = Vec<Lifetime>;
84 type TYC = TypeContext;
85 type Interface = InterfacePresentation;
86 type Expr = Expression<RustFermentate, SPEC>;
87 type Var = FFIVariable<RustFermentate, SPEC, Type>;
88 type Name = Name<RustFermentate, SPEC>;
89}
90
91
92pub trait LangAttrSpecification<T: Clone>: Clone + Default {
93 fn from_attrs(attrs: Vec<Attribute>) -> Self;
94}
95pub trait LangGenSpecification<T: Clone>: Clone + Default + Debug {
96 fn from_generics(generics: Option<Generics>) -> Self;
97}
98pub trait LangLifetimeSpecification<T: Clone>: Clone + Default + Debug {
99 #[allow(unused)]
100 fn from_lifetimes(lifetimes: Vec<Lifetime>) -> Self;
101}
102
103impl<T> LangAttrSpecification<T> for Vec<Attribute> where T: Clone {
104 fn from_attrs(attrs: Vec<Attribute>) -> Self {
105 attrs
106 }
107}
108impl<T> LangGenSpecification<T> for Option<Generics> where T: Clone {
109 fn from_generics(generics: Option<Generics>) -> Self {
110 generics
111 }
112}
113impl<T> LangLifetimeSpecification<T> for Vec<Lifetime> where T: Clone {
114 fn from_lifetimes(lifetimes: Vec<Lifetime>) -> Self {
115 lifetimes
116 }
117}
118impl<T> LangAttrSpecification<T> for AttrWrapper where T: Clone {
119 fn from_attrs(attrs: Vec<Attribute>) -> Self {
120 AttrWrapper::from(attrs)
121 }
122}
123
124#[derive(Debug, Clone)]
125#[non_exhaustive]
126pub enum Lang {
127 #[cfg(feature = "objc")]
128 ObjC(objc::Config),
129 #[cfg(feature = "java")]
130 Java(java::Config)
131}
132
133impl CrateTreeConsumer for Lang {
134 fn generate(&self, crate_tree: &CrateTree) -> Result<(), error::Error> {
135 match self {
136 #[cfg(feature = "objc")]
137 Lang::ObjC(config) =>
138 config.generate(crate_tree),
139 #[cfg(feature = "java")]
140 Lang::Java(config) =>
141 config.generate(crate_tree),
142 #[cfg(all(not(feature = "objc"), not(feature = "java")))]
143 _ => Ok(())
144 }
145 }
146}