0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2025-03-10 05:56:52 -04:00
rusty-v8/src/promise.rs
Moritz Gunz efe0e76a75
#[derive(Debug)] all the things (#468)
This commit implements Debug trait for most public structs.
2020-11-18 15:17:25 +01:00

220 lines
5.6 KiB
Rust

use std::marker::PhantomData;
use crate::support::MaybeBool;
use crate::Context;
use crate::Function;
use crate::HandleScope;
use crate::Local;
use crate::Promise;
use crate::PromiseResolver;
use crate::Value;
extern "C" {
fn v8__Promise__Resolver__New(
context: *const Context,
) -> *const PromiseResolver;
fn v8__Promise__Resolver__GetPromise(
this: *const PromiseResolver,
) -> *const Promise;
fn v8__Promise__Resolver__Resolve(
this: *const PromiseResolver,
context: *const Context,
value: *const Value,
) -> MaybeBool;
fn v8__Promise__Resolver__Reject(
this: *const PromiseResolver,
context: *const Context,
value: *const Value,
) -> MaybeBool;
fn v8__Promise__State(this: *const Promise) -> PromiseState;
fn v8__Promise__HasHandler(this: *const Promise) -> bool;
fn v8__Promise__Result(this: *const Promise) -> *const Value;
fn v8__Promise__Catch(
this: *const Promise,
context: *const Context,
handler: *const Function,
) -> *const Promise;
fn v8__Promise__Then(
this: *const Promise,
context: *const Context,
handler: *const Function,
) -> *const Promise;
fn v8__Promise__Then2(
this: *const Promise,
context: *const Context,
on_fulfilled: *const Function,
on_rejected: *const Function,
) -> *const Promise;
fn v8__PromiseRejectMessage__GetPromise(
this: *const PromiseRejectMessage,
) -> *const Promise;
fn v8__PromiseRejectMessage__GetValue(
this: *const PromiseRejectMessage,
) -> *const Value;
fn v8__PromiseRejectMessage__GetEvent(
this: *const PromiseRejectMessage,
) -> PromiseRejectEvent;
}
#[derive(Debug, PartialEq)]
#[repr(C)]
pub enum PromiseState {
Pending,
Fulfilled,
Rejected,
}
impl Promise {
/// Returns the value of the [[PromiseState]] field.
pub fn state(&self) -> PromiseState {
unsafe { v8__Promise__State(&*self) }
}
/// Returns true if the promise has at least one derived promise, and
/// therefore resolve/reject handlers (including default handler).
pub fn has_handler(&self) -> bool {
unsafe { v8__Promise__HasHandler(&*self) }
}
/// Returns the content of the [[PromiseResult]] field. The Promise must not
/// be pending.
pub fn result<'s>(&self, scope: &mut HandleScope<'s>) -> Local<'s, Value> {
unsafe { scope.cast_local(|_| v8__Promise__Result(&*self)) }.unwrap()
}
/// Register a rejection handler with a promise.
///
/// See `Self::then2`.
pub fn catch<'s>(
&self,
scope: &mut HandleScope<'s>,
handler: Local<Function>,
) -> Option<Local<'s, Promise>> {
unsafe {
scope.cast_local(|sd| {
v8__Promise__Catch(&*self, sd.get_current_context(), &*handler)
})
}
}
/// Register a resolution handler with a promise.
///
/// See `Self::then2`.
pub fn then<'s>(
&self,
scope: &mut HandleScope<'s>,
handler: Local<Function>,
) -> Option<Local<'s, Promise>> {
unsafe {
scope.cast_local(|sd| {
v8__Promise__Then(&*self, sd.get_current_context(), &*handler)
})
}
}
/// Register a resolution/rejection handler with a promise.
/// The handler is given the respective resolution/rejection value as
/// an argument. If the promise is already resolved/rejected, the handler is
/// invoked at the end of turn.
pub fn then2<'s>(
&self,
scope: &mut HandleScope<'s>,
on_fulfilled: Local<Function>,
on_rejected: Local<Function>,
) -> Option<Local<'s, Promise>> {
unsafe {
scope.cast_local(|sd| {
v8__Promise__Then2(
&*self,
sd.get_current_context(),
&*on_fulfilled,
&*on_rejected,
)
})
}
}
}
impl PromiseResolver {
/// Create a new resolver, along with an associated promise in pending state.
pub fn new<'s>(
scope: &mut HandleScope<'s>,
) -> Option<Local<'s, PromiseResolver>> {
unsafe {
scope
.cast_local(|sd| v8__Promise__Resolver__New(sd.get_current_context()))
}
}
/// Extract the associated promise.
pub fn get_promise<'s>(
&self,
scope: &mut HandleScope<'s>,
) -> Local<'s, Promise> {
unsafe { scope.cast_local(|_| v8__Promise__Resolver__GetPromise(&*self)) }
.unwrap()
}
/// Resolve the associated promise with a given value.
/// Ignored if the promise is no longer pending.
pub fn resolve(
&self,
scope: &mut HandleScope,
value: Local<'_, Value>,
) -> Option<bool> {
unsafe {
v8__Promise__Resolver__Resolve(
&*self,
&*scope.get_current_context(),
&*value,
)
.into()
}
}
/// Reject the associated promise with a given value.
/// Ignored if the promise is no longer pending.
pub fn reject(
&self,
scope: &mut HandleScope,
value: Local<'_, Value>,
) -> Option<bool> {
unsafe {
v8__Promise__Resolver__Reject(
&*self,
&*scope.get_current_context(),
&*value,
)
.into()
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[repr(C)]
pub enum PromiseRejectEvent {
PromiseRejectWithNoHandler,
PromiseHandlerAddedAfterReject,
PromiseRejectAfterResolved,
PromiseResolveAfterResolved,
}
#[derive(Clone, Copy, Debug)]
#[repr(C)]
pub struct PromiseRejectMessage<'msg>([usize; 3], PhantomData<&'msg ()>);
impl<'msg> PromiseRejectMessage<'msg> {
pub fn get_promise(&self) -> Local<'msg, Promise> {
unsafe { Local::from_raw(v8__PromiseRejectMessage__GetPromise(self)) }
.unwrap()
}
pub fn get_event(&self) -> PromiseRejectEvent {
unsafe { v8__PromiseRejectMessage__GetEvent(self) }
}
pub fn get_value(&self) -> Option<Local<'msg, Value>> {
unsafe { Local::from_raw(v8__PromiseRejectMessage__GetValue(self)) }
}
}