intuicio_frontend_simpleton/library/
promise.rs

1use crate::{library::closure::Closure, Reference};
2use intuicio_core::{context::Context, registry::Registry, IntuicioStruct};
3use intuicio_derive::{intuicio_method, intuicio_methods, IntuicioStruct};
4
5#[derive(IntuicioStruct, Default)]
6#[intuicio(name = "Promise", module_name = "promise", override_send = false)]
7pub struct Promise {
8    #[intuicio(ignore)]
9    pub resolved: Reference,
10    #[intuicio(ignore)]
11    pub rejected: Reference,
12    #[intuicio(ignore)]
13    pub next: Reference,
14}
15
16#[intuicio_methods(module_name = "promise")]
17impl Promise {
18    #[allow(clippy::new_ret_no_self)]
19    #[intuicio_method(use_registry)]
20    pub fn new(registry: &Registry, resolved: Reference, rejected: Reference) -> Reference {
21        Reference::new(
22            Promise {
23                resolved,
24                rejected,
25                next: Reference::null(),
26            },
27            registry,
28        )
29    }
30
31    fn then_impl(promise: &mut Promise, then: Reference) {
32        if let Some(mut next) = promise.next.write::<Promise>() {
33            return Self::then_impl(&mut next, then);
34        }
35        promise.next = then;
36    }
37
38    #[intuicio_method()]
39    pub fn then(mut promise: Reference, then: Reference) -> Reference {
40        let mut promise = promise.write::<Promise>().unwrap();
41        Self::then_impl(&mut promise, then);
42        Reference::null()
43    }
44
45    #[intuicio_method(use_context, use_registry)]
46    pub fn resolve(
47        context: &mut Context,
48        registry: &Registry,
49        mut promise: Reference,
50        value: Reference,
51    ) -> Reference {
52        let mut promise = match promise.write::<Promise>() {
53            Some(promise) => promise,
54            None => return Reference::null(),
55        };
56        if !promise.resolved.is_null() {
57            promise.resolved.read::<Closure>().unwrap().invoke(
58                context,
59                registry,
60                &[promise.next.clone(), value],
61            );
62        }
63        promise.resolved = Reference::null();
64        promise.rejected = Reference::null();
65        promise.next = Reference::null();
66        Reference::null()
67    }
68
69    #[intuicio_method(use_context, use_registry)]
70    pub fn reject(
71        context: &mut Context,
72        registry: &Registry,
73        mut promise: Reference,
74        value: Reference,
75    ) -> Reference {
76        let mut promise = match promise.write::<Promise>() {
77            Some(promise) => promise,
78            None => return Reference::null(),
79        };
80        if !promise.rejected.is_null() {
81            promise.rejected.read::<Closure>().unwrap().invoke(
82                context,
83                registry,
84                &[promise.next.clone(), value],
85            );
86        }
87        promise.resolved = Reference::null();
88        promise.rejected = Reference::null();
89        promise.next = Reference::null();
90        Reference::null()
91    }
92}
93
94pub fn install(registry: &mut Registry) {
95    registry.add_type(Promise::define_struct(registry));
96    registry.add_function(Promise::new__define_function(registry));
97    registry.add_function(Promise::then__define_function(registry));
98    registry.add_function(Promise::resolve__define_function(registry));
99    registry.add_function(Promise::reject__define_function(registry));
100}