workflow_wasm/options.rs
1//!
2//! Helper trait for managing options struct which extends [Object](js_sys::Object)
3//! ```ignore
4//! # use wasm_bindgen::JsValue;
5//! # use crate::workflow_wasm::options::OptionsTrait;
6//! // create MyOptions struct
7//!
8//! #[wasm_bindgen]
9//! extern "C" {
10//! #[derive(Debug, Clone, PartialEq, Eq)]
11//! #[wasm_bindgen(extends = js_sys::Object)]
12//! pub type MyOptions;
13//! }
14//!
15//!
16//! impl OptionsTrait for MyOptions{}
17//!
18//! //impl methods as you need
19//! impl MyOptions{
20//! /// Set title
21//! pub fn title(self, title:&str)->Self{
22//! self.set("title", JsValue::from(title))
23//! }
24//!
25//! /// Set active
26//! pub fn active(self, active:bool)->Self{
27//! self.set("active", JsValue::from(active))
28//! }
29//! }
30//!
31//! // use MyOptions
32//!
33//! let options = MyOptions::new()
34//! .title("title text")
35//! .active(true);
36//!
37//! ```
38//!
39
40use js_sys::Object;
41use wasm_bindgen::prelude::*;
42
43pub trait OptionsTrait {
44 /// "Construct a new `Options`.
45 ///
46 fn new() -> Self
47 where
48 Self: wasm_bindgen::JsCast,
49 {
50 #[allow(unused_mut)]
51 let mut ret: Self = ::wasm_bindgen::JsCast::unchecked_into(Object::new());
52 ret = ret.initialize();
53 ret
54 }
55
56 fn initialize(self) -> Self
57 where
58 Self: wasm_bindgen::JsCast,
59 {
60 self
61 }
62
63 fn set(self, mut key: &str, value: JsValue) -> Self
64 where
65 Self: wasm_bindgen::JsCast,
66 {
67 let mut target = self.as_ref().clone();
68
69 if key.contains('.') {
70 let mut name_parts: Vec<&str> = key.split('.').collect();
71 key = name_parts.pop().unwrap();
72
73 for name in name_parts {
74 //log_info!("name: {}, target: {:?}", name, target);
75 let r = ::js_sys::Reflect::get(&target, &JsValue::from(name));
76
77 match r {
78 Ok(r) => {
79 if !r.is_undefined() {
80 target = r
81 } else {
82 let object = Object::new();
83 let new_target = JsValue::from(object);
84 //log_info!("new_target: {:?}", new_target);
85 let _ =
86 ::js_sys::Reflect::set(&target, &JsValue::from(name), &new_target);
87
88 target = new_target;
89 }
90 }
91 Err(err) => {
92 panic!("OptionsExt::set(): unable to find property `{name}`, err: {err:?}");
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}
110
111/*
112#[cfg(test)]
113mod test{
114 use super::*;
115 use crate as workflow_wasm;
116 #[test]
117 fn test(){
118 #[wasm_bindgen]
119 extern "C" {
120 #[wasm_bindgen(extends = js_sys::Object)]
121 #[derive(Debug, Clone, PartialEq, Eq)]
122 pub type MyOptions;
123 }
124
125 impl workflow_wasm::options::OptionsTrait for MyOptions{}
126
127 //impl methods as you need
128 impl MyOptions{
129 /// Set title
130 pub fn title(self, title:&str)->Self{
131 self.set("title", JsValue::from(title))
132 }
133
134 /// Set active
135 pub fn active(self, active:bool)->Self{
136 self.set("active", JsValue::from(active))
137 }
138 }
139
140 // use MyOptions
141
142 let options = MyOptions::new()
143 .title("title text")
144 .active(true);
145 }
146}
147
148*/