napi/bindgen_runtime/js_values/stream/
write.rs

1use std::{marker::PhantomData, ptr};
2
3use crate::{
4  bindgen_prelude::{
5    FromNapiValue, Function, JsObjectValue, PromiseRaw, ToNapiValue, TypeName, ValidateNapiValue,
6  },
7  check_status, sys, Env, Error, JsValue, Result, Status, Value, ValueType,
8};
9
10pub struct WriteableStream<'env> {
11  pub(crate) value: sys::napi_value,
12  pub(crate) env: sys::napi_env,
13  pub(crate) _scope: &'env PhantomData<()>,
14}
15
16impl<'env> JsValue<'env> for WriteableStream<'env> {
17  fn value(&self) -> Value {
18    Value {
19      env: self.env,
20      value: self.value,
21      value_type: ValueType::Object,
22    }
23  }
24}
25
26impl<'env> JsObjectValue<'env> for WriteableStream<'env> {}
27
28impl TypeName for WriteableStream<'_> {
29  fn type_name() -> &'static str {
30    "WriteableStream"
31  }
32
33  fn value_type() -> ValueType {
34    ValueType::Object
35  }
36}
37
38impl ValidateNapiValue for WriteableStream<'_> {
39  unsafe fn validate(
40    env: napi_sys::napi_env,
41    napi_val: napi_sys::napi_value,
42  ) -> Result<napi_sys::napi_value> {
43    let constructor = Env::from(env)
44      .get_global()?
45      .get_named_property_unchecked::<Function>("WritableStream")?;
46    let mut is_instance = false;
47    check_status!(
48      unsafe { sys::napi_instanceof(env, napi_val, constructor.value, &mut is_instance) },
49      "Check WritableStream instance failed"
50    )?;
51    if !is_instance {
52      return Err(Error::new(
53        Status::InvalidArg,
54        "Value is not a WritableStream",
55      ));
56    }
57    Ok(ptr::null_mut())
58  }
59}
60
61impl FromNapiValue for WriteableStream<'_> {
62  unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> Result<Self> {
63    Ok(Self {
64      value: napi_val,
65      env,
66      _scope: &PhantomData,
67    })
68  }
69}
70
71impl WriteableStream<'_> {
72  pub fn ready(&self) -> Result<PromiseRaw<'_, ()>> {
73    let mut promise = ptr::null_mut();
74    check_status!(
75      unsafe {
76        sys::napi_get_named_property(self.env, self.value, c"ready".as_ptr().cast(), &mut promise)
77      },
78      "Get ready property failed"
79    )?;
80    Ok(PromiseRaw::new(self.env, promise))
81  }
82
83  /// The `abort()` method of the `WritableStream` interface aborts the stream,
84  /// signaling that the producer can no longer successfully write to the stream and it is to be immediately moved to an error state,
85  /// with any queued writes discarded.
86  pub fn abort(&mut self, reason: String) -> Result<PromiseRaw<'_, ()>> {
87    let mut abort_fn = ptr::null_mut();
88    check_status!(
89      unsafe {
90        sys::napi_get_named_property(
91          self.env,
92          self.value,
93          c"abort".as_ptr().cast(),
94          &mut abort_fn,
95        )
96      },
97      "Get abort property failed"
98    )?;
99    let reason_value = unsafe { ToNapiValue::to_napi_value(self.env, reason)? };
100    let mut promise = ptr::null_mut();
101    check_status!(
102      unsafe {
103        sys::napi_call_function(
104          self.env,
105          self.value,
106          abort_fn,
107          1,
108          [reason_value].as_ptr(),
109          &mut promise,
110        )
111      },
112      "Call abort function failed"
113    )?;
114    Ok(PromiseRaw::new(self.env, promise))
115  }
116
117  /// The `close()` method of the `WritableStream` interface closes the associated stream.
118  ///
119  /// All chunks written before this method is called are sent before the returned promise is fulfilled.
120  pub fn close(&mut self) -> Result<PromiseRaw<'_, ()>> {
121    let mut close_fn = ptr::null_mut();
122    check_status!(
123      unsafe {
124        sys::napi_get_named_property(
125          self.env,
126          self.value,
127          c"close".as_ptr().cast(),
128          &mut close_fn,
129        )
130      },
131      "Get close property failed"
132    )?;
133    let mut promise = ptr::null_mut();
134    check_status!(
135      unsafe {
136        sys::napi_call_function(
137          self.env,
138          self.value,
139          close_fn,
140          0,
141          ptr::null_mut(),
142          &mut promise,
143        )
144      },
145      "Call close function failed"
146    )?;
147    Ok(PromiseRaw::new(self.env, promise))
148  }
149}