mistletoe_macros/
lib.rs

1use mistletoe_api::v1alpha1::MistPackage;
2
3use indexmap::IndexMap;
4use proc_macro::TokenStream;
5use quote::quote;
6use serde::Deserialize;
7use serde_yaml;
8use unindent::unindent;
9
10#[derive(Deserialize, Debug)]
11struct MistHeaders {
12    name: String,
13    #[serde(default)]
14    labels: Option<IndexMap<String, String>>,
15}
16
17#[proc_macro]
18pub fn mistletoe_package(input: TokenStream) -> TokenStream {
19    let header_string_unfmt = input.into_iter().next().unwrap().to_string();
20    let header_string = unindent(&header_string_unfmt[1..header_string_unfmt.len()-1]);
21    let headers: MistHeaders = serde_yaml::from_str(&header_string).unwrap();
22
23    let mistpackage = MistPackage {
24        name: headers.name,
25        labels: headers.labels,
26    };
27
28    let mistpackage_string = serde_yaml::to_string(&mistpackage).unwrap();
29
30    quote! {
31        const INFO: &'static str = #mistpackage_string;
32        
33        static INFO_PTR: mistletoe_bind::include::once_cell::sync::Lazy<std::sync::atomic::AtomicPtr<[usize; 2]>>
34            = mistletoe_bind::include::once_cell::sync::Lazy::new(||
35        {
36            let wide_ptr = Box::new([INFO.as_ptr() as usize, INFO.len()]);
37            std::sync::atomic::AtomicPtr::new(Box::into_raw(wide_ptr))
38        });
39        
40        #[wasm_bindgen::prelude::wasm_bindgen]
41        pub fn __mistletoe_info() -> *mut [usize; 2] {
42            unsafe { *INFO_PTR.as_ptr() }
43        }
44        
45        #[wasm_bindgen::prelude::wasm_bindgen]
46        pub fn __mistletoe_alloc(len: usize) -> *mut u8 {
47            unsafe {
48                let layout = std::alloc::Layout::from_size_align(len, std::mem::align_of::<u8>()).unwrap();
49                std::alloc::alloc(layout)
50            }
51        }
52        
53        #[wasm_bindgen::prelude::wasm_bindgen]
54        pub fn __mistletoe_dealloc(ptr: *mut u8, len: usize) {
55            unsafe {
56                let layout = std::alloc::Layout::from_size_align(len, std::mem::align_of::<u8>()).unwrap();
57                std::alloc::dealloc(ptr, layout);
58            }
59        }
60
61        fn __mistletoe_generate_result(input_str: &str) -> mistletoe_api::v1alpha1::MistResult {
62            let input: mistletoe_api::v1alpha1::MistInput = mistletoe_bind::include::serde_yaml::from_str(input_str)?;
63            generate(input.try_into_data()?)
64        }
65        
66        #[wasm_bindgen::prelude::wasm_bindgen]
67        pub fn __mistletoe_generate(ptr: *const u8, len: usize) -> *mut [usize; 2] {
68            let input_str = unsafe { std::str::from_utf8(std::slice::from_raw_parts(ptr, len)).unwrap() };
69            let result = __mistletoe_generate_result(input_str);
70            let mut output_str = std::mem::ManuallyDrop::new(mistletoe_api::v1alpha1::serialize_result(result).unwrap());
71            let retptr = Box::into_raw(Box::new([output_str.as_mut_ptr() as usize, output_str.len()]));
72            retptr
73        }
74    }.into()
75}