use rquickjs::{
atom::PredefinedAtom,
prelude::{Opt, This},
Class, Ctx, JsLifetime, Result, Value,
};
use super::AbortSignal;
#[rquickjs::class]
#[derive(rquickjs::class::Trace)]
pub struct AbortController<'js> {
signal: Class<'js, AbortSignal<'js>>,
}
unsafe impl<'js> JsLifetime<'js> for AbortController<'js> {
type Changed<'to> = AbortController<'to>;
}
#[rquickjs::methods]
impl<'js> AbortController<'js> {
#[qjs(constructor)]
pub fn new(ctx: Ctx<'js>) -> Result<Self> {
let signal = AbortSignal::new();
let abort_controller = Self {
signal: Class::instance(ctx, signal)?,
};
Ok(abort_controller)
}
#[qjs(get)]
pub fn signal(&self) -> Class<'js, AbortSignal<'js>> {
self.signal.clone()
}
#[qjs(prop, rename = PredefinedAtom::SymbolToStringTag, configurable)]
pub fn to_string_tag() -> &'static str {
stringify!(AbortController)
}
pub fn abort(
ctx: Ctx<'js>,
this: This<Class<'js, Self>>,
reason: Opt<Value<'js>>,
) -> Result<()> {
let instance = this.0.borrow();
let signal = instance.signal.clone();
let mut signal_borrow = signal.borrow_mut();
if signal_borrow.aborted {
return Ok(());
}
signal_borrow.set_reason(reason);
drop(signal_borrow);
AbortSignal::send_aborted(This(signal), ctx)?;
Ok(())
}
}