ag_grid_core/
convert.rs

1//! Access to the `ToJsValue` trait for converting types into
2//! `wasm_bindgen::JsValue`s.
3
4use std::collections::HashMap;
5
6use js_sys::Array;
7use wasm_bindgen::{prelude::Closure, JsValue};
8
9use crate::imports::ObjectExt;
10
11/// This trait is used to provide an implementation for converting a given type
12/// into a `wasm_bindgen::JsValue`.
13pub trait ToJsValue {
14    /// Convert the current type to a `wasm_bindgen::JsValue`;
15    fn to_js_value(&self) -> JsValue;
16}
17
18impl ToJsValue for String {
19    fn to_js_value(&self) -> JsValue {
20        JsValue::from_str(self)
21    }
22}
23
24impl ToJsValue for &'static str {
25    fn to_js_value(&self) -> JsValue {
26        JsValue::from_str(self)
27    }
28}
29
30impl ToJsValue for bool {
31    fn to_js_value(&self) -> JsValue {
32        JsValue::from_bool(*self)
33    }
34}
35
36// It would be a nice exercise to write a macro for these...
37
38impl ToJsValue for usize {
39    fn to_js_value(&self) -> JsValue {
40        JsValue::from_f64(*self as f64)
41    }
42}
43
44impl ToJsValue for isize {
45    fn to_js_value(&self) -> JsValue {
46        JsValue::from_f64(*self as f64)
47    }
48}
49
50impl ToJsValue for u64 {
51    fn to_js_value(&self) -> JsValue {
52        JsValue::from_f64(*self as f64)
53    }
54}
55
56impl ToJsValue for i64 {
57    fn to_js_value(&self) -> JsValue {
58        JsValue::from_f64(*self as f64)
59    }
60}
61
62impl ToJsValue for u32 {
63    fn to_js_value(&self) -> JsValue {
64        JsValue::from_f64(*self as f64)
65    }
66}
67
68impl ToJsValue for i32 {
69    fn to_js_value(&self) -> JsValue {
70        JsValue::from_f64(*self as f64)
71    }
72}
73
74impl ToJsValue for u16 {
75    fn to_js_value(&self) -> JsValue {
76        JsValue::from_f64(*self as f64)
77    }
78}
79
80impl ToJsValue for i16 {
81    fn to_js_value(&self) -> JsValue {
82        JsValue::from_f64(*self as f64)
83    }
84}
85
86impl ToJsValue for u8 {
87    fn to_js_value(&self) -> JsValue {
88        JsValue::from_f64(*self as f64)
89    }
90}
91
92impl ToJsValue for i8 {
93    fn to_js_value(&self) -> JsValue {
94        JsValue::from_f64(*self as f64)
95    }
96}
97
98impl ToJsValue for f32 {
99    fn to_js_value(&self) -> JsValue {
100        JsValue::from_f64(*self as f64)
101    }
102}
103
104impl ToJsValue for f64 {
105    fn to_js_value(&self) -> JsValue {
106        JsValue::from_f64(*self as f64)
107    }
108}
109
110impl<T> ToJsValue for Option<T>
111where
112    T: ToJsValue,
113{
114    fn to_js_value(&self) -> JsValue {
115        match self {
116            Some(val) => val.to_js_value(),
117            None => JsValue::null(),
118        }
119    }
120}
121
122impl<T> ToJsValue for Vec<T>
123where
124    T: ToJsValue,
125{
126    fn to_js_value(&self) -> JsValue {
127        self.iter()
128            .map(|v| v.to_js_value())
129            .collect::<Array>()
130            .into()
131    }
132}
133
134impl<V> ToJsValue for HashMap<String, V>
135where
136    V: ToJsValue,
137{
138    fn to_js_value(&self) -> JsValue {
139        let obj = ObjectExt::new();
140        for (k, v) in self {
141            obj.set(k, v.to_js_value())
142        }
143        obj.into()
144    }
145}
146
147impl<T> ToJsValue for Closure<T>
148where
149    T: ?Sized,
150{
151    fn to_js_value(&self) -> JsValue {
152        // I'm not sure if this messes up the memory management of `Closure`. Normally,
153        // to release it to the JS side completely, `Closure::into_js_value()` is
154        // called, which drops the (owned) `Closure` in Rust and returns just the
155        // `JsValue`. Here we are getting a `JsValue`, but we are only working
156        // on a reference to the `Closure`.
157        self.as_ref().to_owned()
158    }
159}
160
161impl ToJsValue for JsValue {
162    fn to_js_value(&self) -> JsValue {
163        self.to_owned()
164    }
165}
166
167impl ToJsValue for () {
168    fn to_js_value(&self) -> JsValue {
169        JsValue::undefined()
170    }
171}