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}