Skip to main content

wry_bindgen/
value.rs

1//! JsValue - An opaque reference to a JavaScript value
2//!
3//! This type represents a reference to a JavaScript value on the JS heap.
4//! API compatible with wasm-bindgen's JsValue.
5
6use crate::__rt::{JsRef, JsRefEncode};
7use alloc::{boxed::Box, string::String, vec::Vec};
8use core::fmt;
9use core::ptr::NonNull;
10use wry_bindgen_core::Clamped;
11
12/// An opaque reference to a JavaScript heap object.
13///
14/// This type is the wry-bindgen equivalent of wasm-bindgen's `JsValue`.
15/// It represents any JavaScript value and is used as the base type for
16/// all imported JS types.
17///
18/// JsValue is intentionally opaque - you cannot inspect or create values
19/// directly. All values come from JavaScript via the IPC protocol.
20///
21/// Unlike wasm-bindgen which runs in a single-threaded Wasm environment,
22/// this implementation uses the IPC protocol to communicate with JS.
23pub struct JsValue {
24    // A JsRef is only meaningful inside the thread-local runtime that created
25    // it; using one elsewhere is a runtime error.
26    idx: JsRef,
27}
28
29impl JsValue {
30    /// The `null` JS value constant.
31    pub const NULL: JsValue = JsValue::from_ref(JsRef::NULL);
32
33    /// The `undefined` JS value constant.
34    pub const UNDEFINED: JsValue = JsValue::from_ref(JsRef::UNDEFINED);
35
36    /// The `true` JS value constant.
37    pub const TRUE: JsValue = JsValue::from_ref(JsRef::TRUE);
38
39    /// The `false` JS value constant.
40    pub const FALSE: JsValue = JsValue::from_ref(JsRef::FALSE);
41
42    /// Create a new JsValue from a JS heap reference.
43    ///
44    /// This is called internally when decoding or reserving a value from JS.
45    #[inline]
46    pub(crate) const fn from_ref(js_ref: JsRef) -> Self {
47        Self { idx: js_ref }
48    }
49
50    /// Get the JS heap reference for this value.
51    ///
52    /// This is used internally for encoding values to send to JS.
53    #[inline]
54    pub(crate) fn js_ref(&self) -> JsRef {
55        self.idx
56    }
57
58    /// Serializes a Rust value into a `JsValue` by serializing to JSON and
59    /// invoking `JSON.parse` on the JS side.
60    ///
61    /// **This function is deprecated**, mirroring upstream wasm-bindgen. Use
62    /// [`serde-wasm-bindgen`](https://docs.rs/serde-wasm-bindgen) instead.
63    ///
64    /// Usage requires activating the `serde-serialize` feature.
65    ///
66    /// # Errors
67    ///
68    /// Returns any error encountered when serializing `T` into JSON.
69    #[cfg(feature = "serde-serialize")]
70    #[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` instead"]
71    pub fn from_serde<T>(t: &T) -> serde_json::Result<JsValue>
72    where
73        T: serde::ser::Serialize + ?Sized,
74    {
75        let json = serde_json::to_string(t)?;
76        Ok(crate::__wry_call_js_function!(
77            "(s) => JSON.parse(s)",
78            fn(&str) -> JsValue,
79            (json.as_str())
80        ))
81    }
82
83    /// Invokes `JSON.stringify` on this value and parses the resulting JSON into
84    /// an arbitrary Rust value.
85    ///
86    /// **This function is deprecated**, mirroring upstream wasm-bindgen. Use
87    /// [`serde-wasm-bindgen`](https://docs.rs/serde-wasm-bindgen) instead.
88    ///
89    /// Usage requires activating the `serde-serialize` feature.
90    ///
91    /// # Errors
92    ///
93    /// Returns any error encountered when parsing the JSON into a `T`.
94    #[cfg(feature = "serde-serialize")]
95    #[deprecated = "causes dependency cycles, use `serde-wasm-bindgen` instead"]
96    pub fn into_serde<T>(&self) -> serde_json::Result<T>
97    where
98        T: for<'a> serde::de::Deserialize<'a>,
99    {
100        // `JSON.stringify(undefined) === undefined`; reinterpret that as JSON
101        // `null` so it round-trips, matching upstream's behavior.
102        let json: String = crate::__wry_call_js_function!(
103            "(v) => JSON.stringify(v) ?? \"null\"",
104            fn(JsValue) -> String,
105            (self.clone())
106        );
107        serde_json::from_str(&json)
108    }
109
110    /// Returns the value as f64 without type checking.
111    /// Used by serde-wasm-bindgen for numeric conversions.
112    #[inline]
113    pub fn unchecked_into_f64(&self) -> f64 {
114        // Unary `+` coercion, matching wasm-bindgen (so e.g. the string "5" becomes 5).
115        crate::js_helpers::js_as_number(self)
116    }
117
118    /// Check if this value is an instance of a specific JS type.
119    #[inline]
120    pub fn has_type<T: crate::JsCast>(&self) -> bool {
121        T::is_type_of(self)
122    }
123
124    /// Get the internal ABI representation (heap index), consuming self.
125    /// This is used by the convert module for low-level interop.
126    /// Returns u32 for wasm-bindgen compatibility.
127    #[inline]
128    pub fn into_abi(self) -> u32 {
129        let id = self.idx.into_abi();
130        core::mem::forget(self);
131        id
132    }
133
134    /// Creates a new JS value representing `undefined`.
135    #[inline]
136    pub const fn undefined() -> JsValue {
137        JsValue::UNDEFINED
138    }
139
140    /// Creates a new JS value representing `null`.
141    #[inline]
142    pub const fn null() -> JsValue {
143        JsValue::NULL
144    }
145
146    /// Creates a new JS value which is a boolean.
147    #[inline]
148    pub const fn from_bool(b: bool) -> JsValue {
149        if b { JsValue::TRUE } else { JsValue::FALSE }
150    }
151
152    /// Creates a JS string from a Rust string.
153    #[allow(clippy::should_implement_trait)]
154    pub fn from_str(s: &str) -> JsValue {
155        s.into()
156    }
157
158    /// Creates a JS number from an f64.
159    pub fn from_f64(n: f64) -> JsValue {
160        n.into()
161    }
162
163    /// Creates a JS value which is a bigint from a string representing a number.
164    pub fn bigint_from_str(s: &str) -> JsValue {
165        crate::js_helpers::js_bigint_from_str(s)
166    }
167
168    /// Creates a new JS symbol with the optional description specified.
169    pub fn symbol(description: Option<&str>) -> JsValue {
170        crate::js_helpers::js_symbol_new(description)
171    }
172}
173
174impl Clone for JsValue {
175    #[inline]
176    fn clone(&self) -> JsValue {
177        // Mirror wasm-bindgen's externref table, where cloning any `JsValue`
178        // (even `null`/`undefined`/`true`/`false`) takes a fresh, counted heap
179        // slot that is reclaimed on drop. Routing special constants through the
180        // JS heap keeps `externref_heap_live_count` accurate; the value-based
181        // predicates (`is_null`, `as_bool`, ...) still recognize the clone via
182        // their JS fallback, so promoting a constant to an owned ref is sound.
183        crate::js_helpers::js_clone_heap_ref(self)
184    }
185}
186
187impl JsRefEncode for JsValue {
188    #[inline]
189    fn js_ref(&self) -> JsRef {
190        self.js_ref()
191    }
192}
193
194impl Drop for JsValue {
195    #[inline]
196    fn drop(&mut self) {
197        // Borrowed refs and special constants don't own JS heap slots.
198        if !self.idx.is_owned_heap_ref() {
199            return;
200        }
201
202        // Drop the value on the JS heap
203        self.idx.drop_js_object();
204    }
205}
206
207impl<'a> PartialEq<&'a str> for JsValue {
208    fn eq(&self, other: &&'a str) -> bool {
209        match self.as_string() {
210            Some(s) => &s == other,
211            None => false,
212        }
213    }
214}
215
216impl PartialEq<JsValue> for &str {
217    fn eq(&self, other: &JsValue) -> bool {
218        match other.as_string() {
219            Some(s) => self == &s,
220            None => false,
221        }
222    }
223}
224
225impl PartialEq<str> for JsValue {
226    fn eq(&self, other: &str) -> bool {
227        match self.as_string() {
228            Some(s) => s == other,
229            None => false,
230        }
231    }
232}
233
234impl PartialEq<String> for JsValue {
235    fn eq(&self, other: &String) -> bool {
236        match self.as_string() {
237            Some(s) => &s == other,
238            None => false,
239        }
240    }
241}
242
243impl PartialEq<JsValue> for String {
244    fn eq(&self, other: &JsValue) -> bool {
245        match other.as_string() {
246            Some(s) => self == &s,
247            None => false,
248        }
249    }
250}
251
252impl<'a> PartialEq<&'a String> for JsValue {
253    fn eq(&self, other: &&'a String) -> bool {
254        match self.as_string() {
255            Some(s) => &s == *other,
256            None => false,
257        }
258    }
259}
260
261impl PartialEq<JsValue> for &String {
262    fn eq(&self, other: &JsValue) -> bool {
263        match other.as_string() {
264            Some(s) => *self == &s,
265            None => false,
266        }
267    }
268}
269
270impl PartialEq<bool> for JsValue {
271    fn eq(&self, other: &bool) -> bool {
272        match self.as_bool() {
273            Some(b) => b == *other,
274            None => false,
275        }
276    }
277}
278
279impl PartialEq<JsValue> for bool {
280    fn eq(&self, other: &JsValue) -> bool {
281        match other.as_bool() {
282            Some(b) => *self == b,
283            None => false,
284        }
285    }
286}
287
288impl PartialEq<f32> for JsValue {
289    fn eq(&self, other: &f32) -> bool {
290        match self.as_f64() {
291            Some(n) => n == (*other as f64),
292            None => false,
293        }
294    }
295}
296
297impl PartialEq<JsValue> for f32 {
298    fn eq(&self, other: &JsValue) -> bool {
299        match other.as_f64() {
300            Some(n) => (*self as f64) == n,
301            None => false,
302        }
303    }
304}
305
306impl PartialEq<f64> for JsValue {
307    fn eq(&self, other: &f64) -> bool {
308        match self.as_f64() {
309            Some(n) => n == *other,
310            None => false,
311        }
312    }
313}
314
315impl PartialEq<JsValue> for f64 {
316    fn eq(&self, other: &JsValue) -> bool {
317        match other.as_f64() {
318            Some(n) => *self == n,
319            None => false,
320        }
321    }
322}
323
324// Macro for integer PartialEq implementations
325macro_rules! impl_partial_eq_int {
326    ($($t:ty),*) => {
327        $(
328            impl PartialEq<$t> for JsValue {
329                fn eq(&self, other: &$t) -> bool {
330                    match self.as_f64() {
331                        Some(n) => n == (*other as f64),
332                        None => false,
333                    }
334                }
335            }
336
337            impl PartialEq<JsValue> for $t {
338                fn eq(&self, other: &JsValue) -> bool {
339                    match other.as_f64() {
340                        Some(n) => (*self as f64) == n,
341                        None => false,
342                    }
343                }
344            }
345        )*
346    };
347}
348
349impl_partial_eq_int!(i8, i16, i32, isize, u8, u16, u32, usize);
350
351// 64/128-bit integers are JS `BigInt`s, so they compare via bigint `===` rather
352// than `as_f64` (which is `None` for a bigint). Matches wasm-bindgen.
353macro_rules! impl_partial_eq_bigint {
354    ($($t:ty),*) => {
355        $(
356            impl PartialEq<$t> for JsValue {
357                fn eq(&self, other: &$t) -> bool {
358                    *self == JsValue::from(*other)
359                }
360            }
361
362            impl PartialEq<JsValue> for $t {
363                fn eq(&self, other: &JsValue) -> bool {
364                    JsValue::from(*self) == *other
365                }
366            }
367        )*
368    };
369}
370
371impl_partial_eq_bigint!(i64, u64, i128, u128);
372
373impl fmt::Debug for JsValue {
374    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
375        write!(f, "JsValue({})", self.as_debug_string())
376    }
377}
378
379impl PartialEq for JsValue {
380    /// Compares two `JsValue`s with JS `===`, matching wasm-bindgen.
381    fn eq(&self, other: &Self) -> bool {
382        crate::js_helpers::js_strict_eq(self, other)
383    }
384}
385
386impl Eq for JsValue {}
387
388impl core::hash::Hash for JsValue {
389    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
390        core::hash::Hash::hash(&self.idx, state);
391    }
392}
393
394impl Default for JsValue {
395    fn default() -> Self {
396        Self::UNDEFINED
397    }
398}
399
400// Additional methods needed by js-sys for BigInt operations
401impl JsValue {
402    /// Checked division.
403    pub fn checked_div(&self, rhs: &Self) -> Self {
404        crate::js_helpers::js_checked_div(self, rhs)
405    }
406
407    /// Power operation.
408    pub fn pow(&self, rhs: &Self) -> Self {
409        crate::js_helpers::js_pow(self, rhs)
410    }
411
412    /// Bitwise AND.
413    pub fn bit_and(&self, rhs: &JsValue) -> JsValue {
414        crate::js_helpers::js_bit_and(self, rhs)
415    }
416
417    /// Bitwise OR.
418    pub fn bit_or(&self, rhs: &JsValue) -> JsValue {
419        crate::js_helpers::js_bit_or(self, rhs)
420    }
421
422    /// Bitwise XOR.
423    pub fn bit_xor(&self, rhs: &JsValue) -> JsValue {
424        crate::js_helpers::js_bit_xor(self, rhs)
425    }
426
427    /// Bitwise NOT.
428    pub fn bit_not(&self) -> JsValue {
429        crate::js_helpers::js_bit_not(self)
430    }
431
432    /// Left shift.
433    pub fn shl(&self, rhs: &JsValue) -> JsValue {
434        crate::js_helpers::js_shl(self, rhs)
435    }
436
437    /// Signed right shift.
438    pub fn shr(&self, rhs: &JsValue) -> JsValue {
439        crate::js_helpers::js_shr(self, rhs)
440    }
441
442    /// Unsigned right shift.
443    pub fn unsigned_shr(&self, rhs: &Self) -> u32 {
444        crate::js_helpers::js_unsigned_shr(self, rhs)
445    }
446
447    /// Add.
448    pub fn add(&self, rhs: &JsValue) -> JsValue {
449        crate::js_helpers::js_add(self, rhs)
450    }
451
452    /// Subtract.
453    pub fn sub(&self, rhs: &JsValue) -> JsValue {
454        crate::js_helpers::js_sub(self, rhs)
455    }
456
457    /// Multiply.
458    pub fn mul(&self, rhs: &JsValue) -> JsValue {
459        crate::js_helpers::js_mul(self, rhs)
460    }
461
462    /// Divide.
463    pub fn div(&self, rhs: &JsValue) -> JsValue {
464        crate::js_helpers::js_div(self, rhs)
465    }
466
467    /// Remainder.
468    pub fn rem(&self, rhs: &JsValue) -> JsValue {
469        crate::js_helpers::js_rem(self, rhs)
470    }
471
472    /// Negate.
473    pub fn neg(&self) -> JsValue {
474        crate::js_helpers::js_neg(self)
475    }
476
477    /// Less than comparison.
478    pub fn lt(&self, other: &Self) -> bool {
479        crate::js_helpers::js_lt(self, other)
480    }
481
482    /// Less than or equal comparison.
483    pub fn le(&self, other: &Self) -> bool {
484        crate::js_helpers::js_le(self, other)
485    }
486
487    /// Greater than comparison.
488    pub fn gt(&self, other: &Self) -> bool {
489        crate::js_helpers::js_gt(self, other)
490    }
491
492    /// Greater than or equal comparison.
493    pub fn ge(&self, other: &Self) -> bool {
494        crate::js_helpers::js_ge(self, other)
495    }
496
497    /// Loose equality (==).
498    pub fn loose_eq(&self, other: &Self) -> bool {
499        crate::js_helpers::js_loose_eq(self, other)
500    }
501
502    /// Check if this value is a falsy value in JavaScript.
503    pub fn is_falsy(&self) -> bool {
504        crate::js_helpers::js_is_falsy(self)
505    }
506
507    /// Check if this value is a truthy value in JavaScript.
508    pub fn is_truthy(&self) -> bool {
509        crate::js_helpers::js_is_truthy(self)
510    }
511
512    /// Check if this value is an object.
513    pub fn is_object(&self) -> bool {
514        crate::js_helpers::js_is_object(self)
515    }
516
517    /// Check if this value is a function.
518    pub fn is_function(&self) -> bool {
519        crate::js_helpers::js_is_function(self)
520    }
521
522    /// Check if this value is a string.
523    pub fn is_string(&self) -> bool {
524        crate::js_helpers::js_is_string(self)
525    }
526
527    /// Check if this value is a symbol.
528    pub fn is_symbol(&self) -> bool {
529        crate::js_helpers::js_is_symbol(self)
530    }
531
532    /// Check if this value is a bigint.
533    pub fn is_bigint(&self) -> bool {
534        crate::js_helpers::js_is_bigint(self)
535    }
536
537    /// Check if this value is an Array.
538    pub fn is_array(&self) -> bool {
539        crate::js_helpers::js_is_array(self)
540    }
541
542    /// Check if this value is undefined.
543    pub fn is_undefined(&self) -> bool {
544        if self.idx == JsRef::UNDEFINED {
545            return true;
546        }
547        crate::js_helpers::js_is_undefined(self)
548    }
549
550    /// Check if this value is null.
551    pub fn is_null(&self) -> bool {
552        if self.idx == JsRef::NULL {
553            return true;
554        }
555        crate::js_helpers::js_is_null(self)
556    }
557
558    /// Check if this value is null or undefined.
559    pub fn is_null_or_undefined(&self) -> bool {
560        if self.idx == JsRef::NULL || self.idx == JsRef::UNDEFINED {
561            return true;
562        }
563        crate::js_helpers::js_is_null_or_undefined(self)
564    }
565
566    /// Get the typeof this value as a string.
567    pub fn js_typeof(&self) -> JsValue {
568        crate::js_helpers::js_typeof(self)
569    }
570
571    /// Check if this value has a property with the given name.
572    pub fn js_in(&self, obj: &JsValue) -> bool {
573        crate::js_helpers::js_in(self, obj)
574    }
575
576    /// Get the value as a bool.
577    pub fn as_bool(&self) -> Option<bool> {
578        if self.idx == JsRef::TRUE {
579            Some(true)
580        } else if self.idx == JsRef::FALSE {
581            Some(false)
582        } else if self.idx == JsRef::UNDEFINED || self.idx == JsRef::NULL {
583            None
584        } else if crate::js_helpers::js_is_true(self) {
585            Some(true)
586        } else if crate::js_helpers::js_is_false(self) {
587            Some(false)
588        } else {
589            None
590        }
591    }
592
593    /// Get the value as an f64.
594    pub fn as_f64(&self) -> Option<f64> {
595        crate::js_helpers::js_as_f64(self)
596    }
597
598    /// Get the value as a string.
599    pub fn as_string(&self) -> Option<String> {
600        crate::js_helpers::js_as_string(self)
601    }
602
603    /// Get a debug string representation of the value.
604    pub fn as_debug_string(&self) -> String {
605        crate::js_helpers::js_debug_string(self)
606    }
607}
608
609// Operator trait implementations for JsValue references
610use core::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Rem, Shl, Shr, Sub};
611
612impl Neg for &JsValue {
613    type Output = JsValue;
614    fn neg(self) -> Self::Output {
615        JsValue::neg(self)
616    }
617}
618
619impl Not for &JsValue {
620    type Output = bool;
621
622    fn not(self) -> Self::Output {
623        JsValue::is_falsy(self)
624    }
625}
626
627impl BitAnd for &JsValue {
628    type Output = JsValue;
629    fn bitand(self, rhs: Self) -> Self::Output {
630        JsValue::bit_and(self, rhs)
631    }
632}
633
634impl BitOr for &JsValue {
635    type Output = JsValue;
636    fn bitor(self, rhs: Self) -> Self::Output {
637        JsValue::bit_or(self, rhs)
638    }
639}
640
641impl BitXor for &JsValue {
642    type Output = JsValue;
643    fn bitxor(self, rhs: Self) -> Self::Output {
644        JsValue::bit_xor(self, rhs)
645    }
646}
647
648impl Shl for &JsValue {
649    type Output = JsValue;
650    fn shl(self, rhs: Self) -> Self::Output {
651        JsValue::shl(self, rhs)
652    }
653}
654
655impl Shr for &JsValue {
656    type Output = JsValue;
657    fn shr(self, rhs: Self) -> Self::Output {
658        JsValue::shr(self, rhs)
659    }
660}
661
662impl Add for &JsValue {
663    type Output = JsValue;
664    fn add(self, rhs: Self) -> Self::Output {
665        JsValue::add(self, rhs)
666    }
667}
668
669impl Sub for &JsValue {
670    type Output = JsValue;
671    fn sub(self, rhs: Self) -> Self::Output {
672        JsValue::sub(self, rhs)
673    }
674}
675
676impl Mul for &JsValue {
677    type Output = JsValue;
678    fn mul(self, rhs: Self) -> Self::Output {
679        JsValue::mul(self, rhs)
680    }
681}
682
683impl Div for &JsValue {
684    type Output = JsValue;
685    fn div(self, rhs: Self) -> Self::Output {
686        JsValue::div(self, rhs)
687    }
688}
689
690impl Rem for &JsValue {
691    type Output = JsValue;
692    fn rem(self, rhs: Self) -> Self::Output {
693        JsValue::rem(self, rhs)
694    }
695}
696
697impl Neg for JsValue {
698    type Output = JsValue;
699    fn neg(self) -> JsValue {
700        JsValue::neg(&self)
701    }
702}
703
704impl Not for JsValue {
705    type Output = bool;
706    fn not(self) -> Self::Output {
707        JsValue::is_falsy(&self)
708    }
709}
710
711// Macro for binary operators with all ownership combinations
712macro_rules! impl_binary_op {
713    ($trait:ident, $method:ident, $js_method:ident) => {
714        // JsValue op JsValue
715        impl $trait for JsValue {
716            type Output = JsValue;
717            fn $method(self, rhs: JsValue) -> JsValue {
718                JsValue::$js_method(&self, &rhs)
719            }
720        }
721
722        // JsValue op &JsValue
723        impl $trait<&JsValue> for JsValue {
724            type Output = JsValue;
725            fn $method(self, rhs: &JsValue) -> JsValue {
726                JsValue::$js_method(&self, rhs)
727            }
728        }
729
730        // &JsValue op JsValue
731        impl<'a> $trait<JsValue> for &'a JsValue {
732            type Output = JsValue;
733            fn $method(self, rhs: JsValue) -> JsValue {
734                JsValue::$js_method(self, &rhs)
735            }
736        }
737    };
738}
739
740impl_binary_op!(Add, add, add);
741impl_binary_op!(Sub, sub, sub);
742impl_binary_op!(Mul, mul, mul);
743impl_binary_op!(Div, div, div);
744impl_binary_op!(Rem, rem, rem);
745impl_binary_op!(BitAnd, bitand, bit_and);
746impl_binary_op!(BitOr, bitor, bit_or);
747impl_binary_op!(BitXor, bitxor, bit_xor);
748impl_binary_op!(Shl, shl, shl);
749impl_binary_op!(Shr, shr, shr);
750
751impl From<bool> for JsValue {
752    fn from(s: bool) -> JsValue {
753        JsValue::from_bool(s)
754    }
755}
756
757impl<T> From<*mut T> for JsValue {
758    fn from(s: *mut T) -> JsValue {
759        JsValue::from(s as usize)
760    }
761}
762
763impl<T> From<*const T> for JsValue {
764    fn from(s: *const T) -> JsValue {
765        JsValue::from(s as usize)
766    }
767}
768
769impl<T> From<NonNull<T>> for JsValue {
770    fn from(s: NonNull<T>) -> JsValue {
771        JsValue::from(s.as_ptr() as usize)
772    }
773}
774
775impl<T> From<Vec<T>> for JsValue
776where
777    Vec<T>: crate::__rt::BinaryEncode + crate::__rt::EncodeTypeDef,
778{
779    fn from(vector: Vec<T>) -> Self {
780        crate::__rt::wbg_cast(vector)
781    }
782}
783
784impl<T> From<Box<[T]>> for JsValue
785where
786    Box<[T]>: crate::__rt::BinaryEncode + crate::__rt::EncodeTypeDef,
787{
788    fn from(vector: Box<[T]>) -> Self {
789        crate::__rt::wbg_cast(vector)
790    }
791}
792
793impl<T> From<Clamped<Vec<T>>> for JsValue
794where
795    Clamped<Vec<T>>: crate::__rt::BinaryEncode + crate::__rt::EncodeTypeDef,
796{
797    fn from(vector: Clamped<Vec<T>>) -> Self {
798        crate::__rt::wbg_cast(vector)
799    }
800}
801
802impl<T> From<Clamped<Box<[T]>>> for JsValue
803where
804    Clamped<Vec<T>>: crate::__rt::BinaryEncode + crate::__rt::EncodeTypeDef,
805{
806    fn from(vector: Clamped<Box<[T]>>) -> Self {
807        crate::__rt::wbg_cast(Clamped(vector.0.into_vec()))
808    }
809}