Skip to main content

ferrijs_std/abort/
abort_controller.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3use rquickjs::{
4    atom::PredefinedAtom,
5    prelude::{Opt, This},
6    Class, Ctx, JsLifetime, Result, Value,
7};
8
9use super::AbortSignal;
10
11#[rquickjs::class]
12#[derive(rquickjs::class::Trace)]
13pub struct AbortController<'js> {
14    signal: Class<'js, AbortSignal<'js>>,
15}
16
17unsafe impl<'js> JsLifetime<'js> for AbortController<'js> {
18    type Changed<'to> = AbortController<'to>;
19}
20
21#[rquickjs::methods]
22impl<'js> AbortController<'js> {
23    #[qjs(constructor)]
24    pub fn new(ctx: Ctx<'js>) -> Result<Self> {
25        let signal = AbortSignal::new();
26
27        let abort_controller = Self {
28            signal: Class::instance(ctx, signal)?,
29        };
30        Ok(abort_controller)
31    }
32
33    #[qjs(get)]
34    pub fn signal(&self) -> Class<'js, AbortSignal<'js>> {
35        self.signal.clone()
36    }
37
38    #[qjs(prop, rename = PredefinedAtom::SymbolToStringTag, configurable)]
39    pub fn to_string_tag() -> &'static str {
40        stringify!(AbortController)
41    }
42
43    pub fn abort(
44        ctx: Ctx<'js>,
45        this: This<Class<'js, Self>>,
46        reason: Opt<Value<'js>>,
47    ) -> Result<()> {
48        let instance = this.0.borrow();
49        let signal = instance.signal.clone();
50        let mut signal_borrow = signal.borrow_mut();
51        if signal_borrow.aborted {
52            //only once
53            return Ok(());
54        }
55        signal_borrow.set_reason(reason);
56        drop(signal_borrow);
57        AbortSignal::send_aborted(This(signal), ctx)?;
58
59        Ok(())
60    }
61}