1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
use std::str::FromStr;

use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, ItemFn, punctuated::Punctuated, FnArg, token::Comma};

#[proc_macro_attribute]
pub fn scs_api(args: TokenStream, input: TokenStream) -> TokenStream {
    let api_type = if args.is_empty() {
        "void".to_string()
    } else {
        args.to_string()
    };

    if api_type != "void" && api_type != "result" {
        panic!("Expected API type `void` or `result`, but got `{}`", api_type);
    }

    let mut input = parse_macro_input!(input as ItemFn);

    input.sig.abi = syn::parse_str("extern \"C\"").unwrap();

    if api_type == "result" {
        input.sig.output = syn::parse_str("-> scs_sdk_rs::scs_result_t").unwrap();
    }
    
    TokenStream::from(quote!(#input))
}

#[proc_macro_attribute]
pub fn scs_telemetry_init(_args: TokenStream, input: TokenStream) -> TokenStream {
    let input = scs_api(TokenStream::from_str("result").unwrap(), input);
    let mut input = parse_macro_input!(input as ItemFn);

    let mut punc = Punctuated::new();
    punc.push_value(syn::parse_str::<FnArg>("version: scs_sdk_rs::scs_u32_t").unwrap());
    punc.push_punct(syn::parse_str::<Comma>(",").unwrap());
    punc.push_value(syn::parse_str("params: *const scs_sdk_rs::scs_telemetry_init_params_t").unwrap());

    input.sig.inputs = punc;
    input.sig.ident = syn::parse_str("scs_telemetry_init").unwrap();

    TokenStream::from(quote!(#input))
}