sciter/
macros.rs

1//! Macros
2
3/// Rust string to UTF-8 conversion. See also `utf::u2s`.
4///
5/// # Example:
6///
7/// ```ignore
8/// let cstr = s2u!("hello"); // ffi::CString
9/// libc::printf("%hs", cstr.as_ptr());
10/// ```
11///
12#[macro_export]
13macro_rules! s2u {
14	($s:expr) => ( $crate::utf::s2un($s.as_ref()).0 )
15}
16
17/// Rust string to UTF-8 conversion. See also `utf::u2s`.
18///
19/// # Example:
20///
21/// ```ignore
22/// let (cstr, len) = s2un!("hello"); // ffi::CString
23/// libc::printf("%.*hs", len, cstr.as_ptr());
24/// ```
25///
26#[macro_export]
27macro_rules! s2un {
28	($s:expr) => ( $crate::utf::s2un($s.as_ref()) )
29}
30
31
32/// Rust string to UTF-16 conversion. See also `utf::w2s`.
33///
34/// # Example:
35///
36/// ```ignore
37/// let cwstr = s2w!("hello"); // Vec<u16>
38/// libc::printf("%ws", cwstr.as_ptr());
39/// ```
40///
41#[macro_export]
42macro_rules! s2w {
43	($s:expr) => ( $crate::utf::s2vec($s.as_ref()) )
44}
45
46/// Rust string to UTF-16 conversion. See also `utf::w2s`.
47///
48/// # Example:
49///
50/// ```ignore
51/// let (cwstr, len) = s2wn!("hello"); // Vec<u16>
52/// libc::printf("%.*ws", len, cwstr.as_ptr());
53/// ```
54///
55#[macro_export]
56macro_rules! s2wn {
57	($s:expr) => ( $crate::utf::s2vecn($s.as_ref()) )
58}
59
60
61/// UTF-16 to `String` conversion.
62#[macro_export]
63macro_rules! w2s {
64	($s:expr) => ( $crate::utf::w2s($s) )
65}
66
67
68/// UTF-8 to `String` conversion.
69#[macro_export]
70macro_rules! u2s {
71	($s:expr) => ( $crate::utf::u2s($s) )
72}
73
74
75/// Pack arguments to call the Sciter script function.
76#[doc(hidden)]
77#[macro_export]
78macro_rules! pack_args {
79	() => { $crate::value::Value::pack_args(&[]) };
80
81	( $($s:expr),* ) => {
82		{
83			let args = [
84			$(
85				$crate::value::Value::from($s)
86			 ),*
87			];
88			$crate::value::Value::pack_args(&args)
89		}
90	};
91}
92
93/// Pack arguments into a `[Value]` array to call Sciter script functions.
94///
95/// Used in [`Element.call_function()`](dom/struct.Element.html#method.call_function),
96/// [`Element.call_method()`](dom/struct.Element.html#method.call_method),
97/// [`Host.call_function()`](host/struct.Host.html#method.call_function),
98/// [`Value.call()`](value/struct.Value.html#method.call).
99///
100/// ## Example:
101///
102/// ```rust,ignore
103/// # #![doc(test(no_crate_inject))]
104/// # #[macro_use] extern crate sciter;
105/// let value = sciter::Value::new();
106/// let result = value.call(None, &make_args!(1, "2", 3.0), Some(file!())).unwrap();
107/// ```
108#[macro_export]
109macro_rules! make_args {
110	() => { { let args : [$crate::value::Value; 0] = []; args } };
111
112	( $($s:expr),* ) => {
113		{
114			let args = [
115			$(
116				$crate::value::Value::from($s)
117			 ),*
118			];
119			args
120		}
121	};
122}
123
124#[doc(hidden)]
125#[macro_export]
126/// Declare handle type (native pointer).
127macro_rules! MAKE_HANDLE {
128	($(#[$attrs:meta])* $name:ident, $inner:ident) => {
129		#[repr(C)] #[doc(hidden)]
130		pub struct $inner { _unused: usize }
131    $(#[$attrs])*
132    pub type $name = *mut $inner;
133	};
134}
135
136/// Dispatch script calls to native code. Used in [`dom::EventHandler`](dom/event/trait.EventHandler.html) implementations.
137///
138/// This macro generates a new function which dispatches incoming script calls to the corresponding native functions
139/// with arguments unpacking and type checking.
140///
141/// Note: unstable, will be improved.
142#[macro_export]
143macro_rules! dispatch_script_call {
144
145	(
146		$(
147			fn $name:ident ( $( $argt:ident ),* );
148		 )*
149	) => {
150
151		fn dispatch_script_call(&mut self, _root: $crate::HELEMENT, name: &str, argv: &[$crate::Value]) -> Option<$crate::Value>
152		{
153			match name {
154				$(
155					stringify!($name) => {
156
157						// args count
158						let mut _i = 0;
159						$(
160							let _: $argt;
161							_i += 1;
162						)*
163						let argc = _i;
164
165						if argv.len() != argc {
166							return Some($crate::Value::error(&format!("{} error: {} of {} arguments provided.", stringify!($name), argv.len(), argc)));
167						}
168
169						// call function
170						let mut _i = 0;
171						let rv = self.$name(
172							$(
173								{
174									match $crate::FromValue::from_value(&argv[_i]) {
175										Some(arg) => { _i += 1; arg },
176										None => {
177											// invalid type
178											return Some($crate::Value::error(&format!("{} error: invalid type of {} argument ({} expected, {:?} provided).",
179												stringify!($name), _i, stringify!($argt), argv[_i])));
180										},
181									}
182								}
183							 ),*
184						);
185
186						// return result value
187						return Some($crate::Value::from(rv));
188					},
189				 )*
190
191				_ => ()
192			};
193
194			// script call not handled
195			return None;
196		}
197	};
198}
199
200
201/// Create a `sciter::Value` (of map type) from a list of key-value pairs.
202///
203/// # Example
204///
205/// ```rust
206/// # #[macro_use] extern crate sciter;
207/// # fn main() {
208/// let v: sciter::Value = vmap! {
209///   "one" => 1,
210///   "two" => 2.0,
211///   "three" => "",
212/// };
213/// assert!(v.is_map());
214/// assert_eq!(v.len(), 3);
215/// # }
216/// ```
217#[macro_export]
218macro_rules! vmap {
219  ( $($key:expr => $value:expr,)+ ) => { vmap!($($key => $value),+)  };
220  ( $($key:expr => $value:expr),* ) => {
221    {
222      let mut _v = $crate::Value::map();
223      $(
224        _v.set_item($key, $value);
225      )*
226      _v
227    }
228  };
229}
230
231/// Creates a `sciter::Value` (of array type) containing the arguments.
232///
233/// # Example
234///
235/// ```rust
236/// # #[macro_use] extern crate sciter;
237/// # fn main() {
238/// let v: sciter::Value = varray![1, 2.0, "three"];
239/// assert!(v.is_array());
240/// assert_eq!(v.len(), 3);
241/// # }
242/// ```
243#[macro_export]
244macro_rules! varray {
245  ( $($value:expr,)+ ) => { varray!($($value),+) };
246  ( $($value:expr),* ) => {
247    {
248      // args count
249      let mut _i = 0;
250      $(
251        let _ = &$value;
252        _i += 1;
253      )*
254      let argc = _i;
255      let mut _v = $crate::Value::array(argc);
256      let mut _i = 0;
257      $(
258        _v.set(_i, $value);
259        _i += 1;
260      )*
261      _v
262    }
263  };
264}