1use std::rc::Rc;
2
3use crate::model::*;
4
5#[non_exhaustive]
7#[derive(Debug, Clone, PartialEq)]
8pub enum CallbackArgument {
9 Basic(BasicType),
10 String(StringType),
11 Iterator(AbstractIteratorHandle),
12 Class(ClassDeclarationHandle),
13 Struct(UniversalOr<CallbackArgStructField>),
14}
15
16impl From<BasicType> for CallbackArgument {
17 fn from(x: BasicType) -> Self {
18 Self::Basic(x)
19 }
20}
21
22impl From<Primitive> for CallbackArgument {
23 fn from(x: Primitive) -> Self {
24 Self::Basic(x.into())
25 }
26}
27
28impl From<Handle<Enum<Unvalidated>>> for CallbackArgument {
29 fn from(x: Handle<Enum<Unvalidated>>) -> Self {
30 Self::Basic(BasicType::Enum(x))
31 }
32}
33
34impl From<DurationType> for CallbackArgument {
35 fn from(x: DurationType) -> Self {
36 CallbackArgument::Basic(BasicType::Duration(x))
37 }
38}
39
40impl From<AbstractIteratorHandle> for CallbackArgument {
41 fn from(x: AbstractIteratorHandle) -> Self {
42 Self::Iterator(x)
43 }
44}
45
46impl From<UniversalStructHandle> for CallbackArgument {
47 fn from(x: UniversalStructHandle) -> Self {
48 Self::Struct(UniversalOr::Universal(x))
49 }
50}
51
52impl From<CallbackArgStructHandle> for CallbackArgument {
53 fn from(x: CallbackArgStructHandle) -> Self {
54 Self::Struct(x.into())
55 }
56}
57
58impl From<StringType> for CallbackArgument {
59 fn from(x: StringType) -> Self {
60 Self::String(x)
61 }
62}
63
64impl From<ClassDeclarationHandle> for CallbackArgument {
65 fn from(x: ClassDeclarationHandle) -> Self {
66 Self::Class(x)
67 }
68}
69
70#[derive(Debug, Clone)]
72pub struct EnumValue {
73 pub(crate) handle: EnumHandle,
74 pub(crate) variant: EnumVariant<Unvalidated>,
75}
76
77impl EnumValue {
78 pub(crate) fn new(handle: EnumHandle, variant: &'static str) -> BindResult<Self> {
79 let variant = handle.validate_contains_variant_name(variant)?.clone();
80 Ok(Self { handle, variant })
81 }
82}
83
84#[derive(Debug, Clone)]
87pub struct ZeroParameterStructInitializer {
88 pub(crate) handle: UniversalStructHandle,
89 pub(crate) initializer: Handle<Initializer<Unvalidated>>,
90}
91
92impl ZeroParameterStructInitializer {
93 fn try_create(handle: UniversalStructHandle, name: &'static str) -> BindResult<Self> {
94 let initializer = match handle.initializers.iter().find(|x| x.name == name) {
95 None => {
96 return Err(BindingErrorVariant::InitializerDoesNotExist {
97 name,
98 struct_name: handle.declaration.name().clone(),
99 }
100 .into())
101 }
102 Some(x) => x.clone(),
103 };
104
105 if initializer.values.len() != handle.fields.len() {
107 return Err(BindingErrorVariant::InitializerNotParameterless {
108 name,
109 struct_name: handle.declaration.name().clone(),
110 }
111 .into());
112 }
113
114 Ok(Self {
115 handle,
116 initializer,
117 })
118 }
119}
120
121impl UniversalStructHandle {
122 pub fn zero_parameter_initializer(
123 &self,
124 name: &'static str,
125 ) -> BindResult<ZeroParameterStructInitializer> {
126 ZeroParameterStructInitializer::try_create(self.clone(), name)
127 }
128}
129
130#[non_exhaustive]
132#[derive(Debug, Clone)]
133pub enum BasicValue {
134 Primitive(PrimitiveValue),
135 Duration(DurationValue),
136 Enum(EnumValue),
137}
138
139impl BasicValue {
140 pub(crate) fn get_basic_type(&self) -> BasicType {
141 match self {
142 BasicValue::Primitive(x) => {
143 let pv: PrimitiveValue = *x;
144 let x: Primitive = pv.into();
145 BasicType::Primitive(x)
146 }
147 BasicValue::Duration(x) => {
148 let dv: DurationValue = *x;
149 let dt: DurationType = dv.into();
150 BasicType::Duration(dt)
151 }
152 BasicValue::Enum(x) => BasicType::Enum(x.handle.clone()),
153 }
154 }
155}
156
157#[non_exhaustive]
159#[derive(Debug, Clone, PartialEq, Eq)]
160pub enum CallbackReturnValue {
161 Basic(BasicType),
162 Struct(UniversalStructHandle),
163}
164
165#[non_exhaustive]
167#[derive(Debug, Clone)]
168pub enum DefaultCallbackReturnValue {
169 Void,
170 Basic(BasicValue),
171 InitializedStruct(ZeroParameterStructInitializer),
172}
173
174impl DefaultCallbackReturnValue {
175 pub(crate) fn get_callback_return_value(&self) -> Option<CallbackReturnValue> {
176 match self {
177 DefaultCallbackReturnValue::Void => None,
178 DefaultCallbackReturnValue::Basic(x) => {
179 Some(CallbackReturnValue::Basic(x.get_basic_type()))
180 }
181 DefaultCallbackReturnValue::InitializedStruct(x) => {
182 Some(CallbackReturnValue::Struct(x.handle.clone()))
183 }
184 }
185 }
186}
187
188impl From<ZeroParameterStructInitializer> for DefaultCallbackReturnValue {
189 fn from(x: ZeroParameterStructInitializer) -> Self {
190 DefaultCallbackReturnValue::InitializedStruct(x)
191 }
192}
193
194impl From<PrimitiveValue> for DefaultCallbackReturnValue {
195 fn from(x: PrimitiveValue) -> Self {
196 DefaultCallbackReturnValue::Basic(BasicValue::Primitive(x))
197 }
198}
199
200impl From<DurationValue> for DefaultCallbackReturnValue {
201 fn from(x: DurationValue) -> Self {
202 DefaultCallbackReturnValue::Basic(BasicValue::Duration(x))
203 }
204}
205
206impl From<EnumValue> for DefaultCallbackReturnValue {
207 fn from(x: EnumValue) -> Self {
208 DefaultCallbackReturnValue::Basic(BasicValue::Enum(x))
209 }
210}
211
212impl From<Primitive> for CallbackReturnValue {
213 fn from(x: Primitive) -> Self {
214 Self::Basic(x.into())
215 }
216}
217
218impl From<BasicType> for CallbackReturnValue {
219 fn from(x: BasicType) -> Self {
220 CallbackReturnValue::Basic(x)
221 }
222}
223
224impl From<UniversalStructHandle> for CallbackReturnValue {
225 fn from(x: UniversalStructHandle) -> Self {
226 CallbackReturnValue::Struct(x)
227 }
228}
229
230impl From<DurationType> for CallbackReturnValue {
231 fn from(x: DurationType) -> Self {
232 BasicType::Duration(x).into()
233 }
234}
235
236impl From<Handle<Enum<Unvalidated>>> for CallbackReturnValue {
237 fn from(x: Handle<Enum<Unvalidated>>) -> Self {
238 Self::Basic(BasicType::Enum(x))
239 }
240}
241
242pub type CallbackReturnType<T> = ReturnType<CallbackReturnValue, T>;
243
244#[non_exhaustive]
248#[derive(Debug, Copy, Clone, PartialEq, Eq)]
249pub enum FunctionalTransform {
250 Yes,
253 No,
255}
256
257impl FunctionalTransform {
258 pub fn enabled(&self) -> bool {
259 match self {
260 FunctionalTransform::Yes => true,
261 FunctionalTransform::No => false,
262 }
263 }
264}
265
266#[derive(Debug)]
267pub(crate) struct CallbackFunction<D>
268where
269 D: DocReference,
270{
271 pub(crate) name: Name,
272 pub(crate) functional_transform: FunctionalTransform,
273 pub(crate) return_type: OptionalReturnType<CallbackReturnValue, D>,
274 pub(crate) default_implementation: Option<DefaultCallbackReturnValue>,
275 pub(crate) arguments: Vec<Arg<CallbackArgument, D>>,
276 pub(crate) doc: Doc<D>,
277}
278
279impl CallbackFunction<Unvalidated> {
280 pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<CallbackFunction<Validated>> {
281 let arguments: BindResult<Vec<Arg<CallbackArgument, Validated>>> =
282 self.arguments.iter().map(|x| x.validate(lib)).collect();
283
284 let argument_names: Vec<Name> = self.arguments.iter().map(|x| x.name.clone()).collect();
285
286 Ok(CallbackFunction {
287 name: self.name.clone(),
288 functional_transform: self.functional_transform,
289 return_type: self.return_type.validate(&self.name, lib)?,
290 default_implementation: self.default_implementation.clone(),
291 arguments: arguments?,
292 doc: self
293 .doc
294 .validate_with_args(&self.name, lib, Some(&argument_names))?,
295 })
296 }
297}
298
299#[derive(Debug, Copy, Clone, PartialEq, Eq)]
300pub(crate) enum InterfaceCategory {
301 Synchronous,
305 Asynchronous,
309 Future,
311}
312
313#[derive(Debug, Clone)]
314pub(crate) enum InterfaceType<D>
315where
316 D: DocReference,
317{
318 Synchronous(Handle<Interface<D>>),
319 Asynchronous(Handle<Interface<D>>),
320 Future(FutureInterface<D>),
321}
322
323impl InterfaceType<Unvalidated> {
324 pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<InterfaceType<Validated>> {
325 match self {
326 InterfaceType::Synchronous(x) => Ok(InterfaceType::Synchronous(x.validate(lib)?)),
327 InterfaceType::Asynchronous(x) => Ok(InterfaceType::Asynchronous(x.validate(lib)?)),
328 InterfaceType::Future(x) => Ok(InterfaceType::Future(x.validate(lib)?)),
329 }
330 }
331}
332
333impl<D> InterfaceType<D>
334where
335 D: DocReference,
336{
337 pub(crate) fn name(&self) -> &Name {
338 match self {
339 InterfaceType::Synchronous(x) => &x.name,
340 InterfaceType::Asynchronous(x) => &x.name,
341 InterfaceType::Future(x) => &x.interface.name,
342 }
343 }
344
345 pub(crate) fn mode(&self) -> InterfaceCategory {
346 match self {
347 InterfaceType::Synchronous(_) => InterfaceCategory::Synchronous,
348 InterfaceType::Asynchronous(_) => InterfaceCategory::Asynchronous,
349 InterfaceType::Future(_) => InterfaceCategory::Future,
350 }
351 }
352
353 pub(crate) fn doc(&self) -> &Doc<D> {
354 match self {
355 InterfaceType::Synchronous(x) => &x.doc,
356 InterfaceType::Asynchronous(x) => &x.doc,
357 InterfaceType::Future(x) => &x.interface.doc,
358 }
359 }
360
361 pub(crate) fn untyped(&self) -> &Handle<Interface<D>> {
362 match self {
363 InterfaceType::Synchronous(x) => x,
364 InterfaceType::Asynchronous(x) => x,
365 InterfaceType::Future(x) => &x.interface,
366 }
367 }
368}
369
370#[derive(Debug)]
371pub struct Interface<D>
372where
373 D: DocReference,
374{
375 pub(crate) name: Name,
376 pub(crate) mode: InterfaceCategory,
377 pub(crate) callbacks: Vec<CallbackFunction<D>>,
378 pub(crate) doc: Doc<D>,
379 pub(crate) settings: Rc<LibrarySettings>,
380}
381
382impl Interface<Unvalidated> {
383 pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<Handle<Interface<Validated>>> {
384 let callbacks: BindResult<Vec<CallbackFunction<Validated>>> =
385 self.callbacks.iter().map(|x| x.validate(lib)).collect();
386
387 Ok(Handle::new(Interface {
388 name: self.name.clone(),
389 mode: self.mode,
390 callbacks: callbacks?,
391 doc: self.doc.validate(&self.name, lib)?,
392 settings: self.settings.clone(),
393 }))
394 }
395}
396
397impl<D> Interface<D>
398where
399 D: DocReference,
400{
401 pub(crate) fn get_functional_callback(&self) -> Option<&CallbackFunction<D>> {
405 match self.callbacks.len() {
406 1 => self.callbacks.first(),
407 _ => None,
408 }
409 }
410
411 pub(crate) fn is_functional(&self) -> bool {
412 self.get_functional_callback().is_some()
413 }
414
415 pub(crate) fn find_callback<S: AsRef<str>>(&self, name: S) -> Option<&CallbackFunction<D>> {
416 self.callbacks
417 .iter()
418 .find(|callback| callback.name.as_ref() == name.as_ref())
419 }
420}
421
422pub type InterfaceHandle = Handle<Interface<Unvalidated>>;
423
424#[derive(Debug, Clone)]
428pub struct AsynchronousInterface {
429 pub(crate) inner: InterfaceHandle,
430}
431
432#[derive(Debug, Clone)]
436pub struct SynchronousInterface {
437 pub(crate) inner: InterfaceHandle,
438}
439
440#[derive(Debug, Clone)]
441pub struct FutureInterface<D>
442where
443 D: DocReference,
444{
445 pub(crate) value_type: CallbackArgument,
446 pub(crate) value_type_doc: DocString<D>,
447 pub(crate) error_type: ErrorType<D>,
448 pub(crate) interface: Handle<Interface<D>>,
449}
450
451impl FutureInterface<Unvalidated> {
452 pub(crate) fn new(
453 value_type: CallbackArgument,
454 error_type: ErrorType<Unvalidated>,
455 interface: Handle<Interface<Unvalidated>>,
456 value_type_doc: DocString<Unvalidated>,
457 ) -> Self {
458 Self {
459 value_type,
460 error_type,
461 value_type_doc,
462 interface,
463 }
464 }
465
466 pub(crate) fn validate(&self, lib: &LibraryFields) -> BindResult<FutureInterface<Validated>> {
467 Ok(FutureInterface {
468 value_type: self.value_type.clone(),
469 error_type: self.error_type.validate(lib)?,
470 value_type_doc: self.value_type_doc.validate(&self.interface.name, lib)?,
471 interface: self.interface.validate(lib)?,
472 })
473 }
474}
475
476pub type FutureInterfaceHandle = FutureInterface<Unvalidated>;