Skip to content

Commit ef8dbea

Browse files
authored
feat(engine): add JsArrayBuffer::to_vec for copying bytes (#4976)
This Pull Request fixes/closes #4974. It changes the following: - Add `JsArrayBuffer::to_vec(&self) -> Option<Vec<u8>>` helper to copy buffer contents into a fresh `Vec<u8>` while returning `None` when the buffer has been detached - Add a doc comment and example for `JsArrayBuffer::to_vec`, including both normal and detached cases - Add small unit tests (`array_buffer_to_vec_roundtrip_and_detach` and `array_buffer_to_vec_empty`) to cover round-trip, detach, and empty-buffer behavior Testing: - `cargo test -p boa_engine` (including the new unit tests and doctest)
1 parent 683d483 commit ef8dbea

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

core/engine/src/object/builtins/jsarraybuffer.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,35 @@ impl JsArrayBuffer {
257257
GcRef::try_map(self.inner.borrow(), |o| o.data().bytes())
258258
}
259259

260+
/// Copies the contents of this [`JsArrayBuffer`] into a new [`Vec<u8>`].
261+
///
262+
/// Returns `None` if the buffer has been detached.
263+
///
264+
/// See also [`crate::object::builtins::JsUint8Array::to_vec`] and
265+
/// [`crate::object::builtins::JsSharedArrayBuffer::to_vec`].
266+
///
267+
/// # Example
268+
///
269+
/// ```
270+
/// # use boa_engine::object::builtins::{AlignedVec, JsArrayBuffer};
271+
/// # use boa_engine::{Context, JsResult, JsValue};
272+
/// # fn main() -> JsResult<()> {
273+
/// let context = &mut Context::default();
274+
/// let data = AlignedVec::from_iter(0, [1u8, 2, 3, 4]);
275+
/// let buffer = JsArrayBuffer::from_byte_block(data, context)?;
276+
/// assert_eq!(buffer.to_vec(), Some(vec![1u8, 2, 3, 4]));
277+
///
278+
/// buffer.detach(&JsValue::undefined())?;
279+
/// assert_eq!(buffer.to_vec(), None);
280+
/// # Ok(())
281+
/// # }
282+
/// ```
283+
#[inline]
284+
#[must_use]
285+
pub fn to_vec(&self) -> Option<Vec<u8>> {
286+
self.data().map(|data| data.to_vec())
287+
}
288+
260289
/// Get a mutable reference to the [`JsArrayBuffer`]'s data.
261290
///
262291
/// Returns `None` if detached.
@@ -325,3 +354,32 @@ impl TryFromJs for JsArrayBuffer {
325354
}
326355
}
327356
}
357+
358+
#[cfg(test)]
359+
mod tests {
360+
use super::*;
361+
use crate::{Context, JsValue};
362+
363+
#[test]
364+
fn array_buffer_to_vec_roundtrip_and_detach() {
365+
let context = &mut Context::default();
366+
367+
let data = AlignedVec::from_iter(0, [1u8, 2, 3, 4, 5]);
368+
let buffer = JsArrayBuffer::from_byte_block(data, context).unwrap();
369+
370+
assert_eq!(buffer.to_vec(), Some(vec![1u8, 2, 3, 4, 5]));
371+
372+
buffer.detach(&JsValue::undefined()).unwrap();
373+
assert_eq!(buffer.to_vec(), None);
374+
}
375+
376+
#[test]
377+
fn array_buffer_to_vec_empty() {
378+
let context = &mut Context::default();
379+
380+
let data = AlignedVec::from_iter(0, []);
381+
let buffer = JsArrayBuffer::from_byte_block(data, context).unwrap();
382+
383+
assert_eq!(buffer.to_vec(), Some(Vec::new()));
384+
}
385+
}

0 commit comments

Comments
 (0)