jsi_macros/
lib.rs

1use proc_macro_error::proc_macro_error;
2use syn::parse_macro_input;
3
4mod host_event;
5mod host_object;
6
7
8/// A macro that makes it easy to define functions and properies on host
9/// objects.
10/// 
11/// ```no_run
12/// struct ExampleHostObject;
13/// 
14/// #[host_object]
15/// impl ExampleHostObject {
16///     pub fn time(&self, _rt: &mut RuntimeHandle) -> anyhow::Result<i64> {
17///         Ok(3200)
18///     }
19/// }
20/// ```
21/// 
22/// It is used on `impl` blocks and on the functions within the `impl` block.
23/// 
24/// - Add `#[host_object(getter)]` to designate an `fn` as a getter. This will
25///   allow JavaScript code to read the member like a property instead of having
26///   to call it like a function. Getters should be `fn(&self, &mut
27///   RuntimeHandle) -> Result<T>` where `T: IntoValue`.
28/// 
29///   If the `fn` name in Rust starts with `get_`, this prefix will be removed.
30///   
31/// - Add `#[host_object(setter)]` to designate an `fn` as a setter. This will
32///   allow JavaScript code to write the like a property instead of having to
33///   call it like a function. Setters should be `fn(&self, &mut RuntimeHandle,
34///   value: JsiValue) -> Result<()>`.
35/// 
36///   If the `fn` name in Rust starts with `set_`, this prefix will be removed.
37///   
38/// - All other methods will appear as methods on the host object in JavaScript.
39///   The first two arguments should be `&self` and a `&mut Runtime`.
40/// 
41/// By default, all member names in a `host_object` block are converted from
42/// `snake_case` to `camelCase` to give them idiomatic names in JavaScript. To
43/// override this, you can set a name with `#[host_object(method as
44/// custom_method_name)]` or `#[host_object(getter as custom_prop_name)]`.
45/// 
46#[proc_macro_attribute]
47pub fn host_object(
48    _attr_input: proc_macro::TokenStream,
49    attr_target: proc_macro::TokenStream,
50) -> proc_macro::TokenStream {
51    let impl_block = parse_macro_input!(attr_target as host_object::HostObjectImpl);
52    let s = proc_macro::TokenStream::from(impl_block.0);
53    // println!("{}", s);
54    s
55}
56
57#[proc_macro_error]
58#[proc_macro_derive(HostEvent)]
59pub fn host_event_emitter(target: proc_macro::TokenStream) -> proc_macro::TokenStream {
60    let impl_block = parse_macro_input!(target as host_event::HostEventImpl);
61    proc_macro::TokenStream::from(impl_block.0)
62}