nw_sys/options.rs
1//!
2//! Helper trait for managing options struct which extends [Object](js_sys::Object)
3//! ```
4//! // create MyOptions struct
5//!
6//! #[wasm_bindgen]
7//! extern "C" {
8//! #[wasm_bindgen(extends = js_sys::Object)]
9//! #[derive(Debug, Clone, PartialEq, Eq)]
10//! pub type MyOptions;
11//! }
12//!
13//! impl workflow_wasm::options::OptionsTrait for MyOptions{}
14//!
15//! //impl methods as you need
16//! impl MyOptions{
17//! /// Set title
18//! pub fn title(mut self, title:&str)->Self{
19//! self.set("title", JsValue::from(title))
20//! }
21//!
22//! /// Set active
23//! pub fn active(mut self, active:bool)->Self{
24//! self.set("active", JsValue::from(active))
25//! }
26//! }
27//!
28//! // use MyOptions
29//!
30//! let options = MyOptions::new()
31//! .title("title text")
32//! .active(true);
33//!
34//! ```
35//!
36
37use js_sys::Object;
38use wasm_bindgen::prelude::*;
39
40pub trait OptionsTrait {
41 /// "Construct a new `Options`.
42 ///
43 fn new() -> Self
44 where
45 Self: wasm_bindgen::JsCast,
46 {
47 #[allow(unused_mut)]
48 let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(Object::new());
49 ret = ret.initialize();
50 ret
51 }
52
53 fn initialize(self) -> Self
54 where
55 Self: wasm_bindgen::JsCast,
56 {
57 self
58 }
59
60 fn set(self, mut key: &str, value: JsValue) -> Self
61 where
62 Self: wasm_bindgen::JsCast,
63 {
64 let mut target = self.as_ref().clone();
65
66 if key.contains('.') {
67 let mut name_parts: Vec<&str> = key.split('.').collect();
68 key = name_parts.pop().unwrap();
69
70 for name in name_parts {
71 //log_info!("name: {}, target: {:?}", name, target);
72 let r = ::js_sys::Reflect::get(&target, &JsValue::from(name));
73
74 match r {
75 Ok(r) => {
76 if !r.is_undefined() {
77 target = r
78 } else {
79 let object = Object::new();
80 let new_target = JsValue::from(object);
81 //log_info!("new_target: {:?}", new_target);
82 let _ =
83 ::js_sys::Reflect::set(&target, &JsValue::from(name), &new_target);
84
85 target = new_target;
86 }
87 }
88 Err(err) => {
89 panic!(
90 "OptionsExt::set(): unable to find property `{name}`, err: {:?}",
91 err
92 );
93 }
94 }
95 }
96
97 //log_info!("final: key: {}, target: {:?}", key, target);
98 }
99
100 let r = ::js_sys::Reflect::set(&target, &JsValue::from(key), &value);
101 debug_assert!(
102 r.is_ok(),
103 "setting properties should never fail on our dictionary objects"
104 );
105 let _ = r;
106
107 self
108 }
109}