rquickjs_core/value/convert/
coerce.rs1use crate::{convert::Coerced, qjs, Ctx, FromJs, Result, StdString, String, Value};
2use core::{
3 mem::MaybeUninit,
4 ops::{Deref, DerefMut},
5};
6
7impl<T> AsRef<T> for Coerced<T> {
8 fn as_ref(&self) -> &T {
9 &self.0
10 }
11}
12
13impl<T> AsMut<T> for Coerced<T> {
14 fn as_mut(&mut self) -> &mut T {
15 &mut self.0
16 }
17}
18
19impl<T> Deref for Coerced<T> {
20 type Target = T;
21
22 fn deref(&self) -> &Self::Target {
23 &self.0
24 }
25}
26
27impl<T> DerefMut for Coerced<T> {
28 fn deref_mut(&mut self) -> &mut Self::Target {
29 &mut self.0
30 }
31}
32
33impl<'js> FromJs<'js> for Coerced<String<'js>> {
35 fn from_js(ctx: &Ctx<'js>, value: Value<'js>) -> Result<Self> {
36 Ok(Coerced(unsafe {
37 let result = qjs::JS_ToString(ctx.as_ptr(), value.as_js_value());
38 ctx.handle_exception(result)?;
39 String::from_js_value(ctx.clone(), result)
43 }))
44 }
45}
46
47impl<'js> FromJs<'js> for Coerced<StdString> {
49 fn from_js(ctx: &Ctx<'js>, value: Value<'js>) -> Result<Self> {
50 <Coerced<String>>::from_js(ctx, value)
51 .and_then(|string| string.to_string())
52 .map(Coerced)
53 }
54}
55
56macro_rules! coerce_impls {
57 ($($(#[$meta:meta])* $type:ident $func:ident,)*) => {
58 $(
59 $(#[$meta])*
60 impl<'js> FromJs<'js> for Coerced<$type> {
61 fn from_js(ctx: &Ctx<'js>, value: Value<'js>) -> Result<Self> {
62 let mut result = MaybeUninit::uninit();
63 Ok(Coerced(unsafe {
64 if 0 > qjs::$func(ctx.as_ptr(), result.as_mut_ptr(), value.as_js_value()) {
65 return Err(ctx.raise_exception());
66 }
67 result.assume_init()
68 }))
69 }
70 }
71 )*
72 };
73}
74
75coerce_impls! {
76 i32 JS_ToInt32,
78 i64 JS_ToInt64Ext,
80 u64 JS_ToIndex,
82 f64 JS_ToFloat64,
84}
85
86impl<'js> FromJs<'js> for Coerced<bool> {
88 fn from_js(ctx: &Ctx<'js>, value: Value<'js>) -> Result<Self> {
89 Ok(Coerced(unsafe {
90 let res = qjs::JS_ToBool(ctx.as_ptr(), value.as_js_value());
91 if 0 > res {
92 return Err(ctx.raise_exception());
93 }
94 res == 1
95 }))
96 }
97}