use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{
parse::{Parse, ParseStream},
Ident, ItemFn,
};
struct DepsArgs {
bytes_mode: bool,
}
impl Parse for DepsArgs {
fn parse(input: ParseStream) -> syn::Result<Self> {
if input.is_empty() {
return Ok(DepsArgs { bytes_mode: false });
}
let ident: Ident = input.parse()?;
match ident.to_string().as_str() {
"bytes" => Ok(DepsArgs { bytes_mode: true }),
other => Err(syn::Error::new(
ident.span(),
format!("#[dependencies]: unknown option `{other}`; expected `bytes`"),
)),
}
}
}
pub fn expand_dependencies(attr: TokenStream, item: TokenStream) -> TokenStream {
let args = match syn::parse::<DepsArgs>(attr) {
Ok(a) => a,
Err(e) => return e.to_compile_error().into(),
};
let func = match syn::parse::<ItemFn>(item) {
Ok(f) => f,
Err(e) => return e.to_compile_error().into(),
};
let binding = &func.sig.ident;
let cap = quote! { ::toolkit_zero::dependency_graph::capture };
let expanded: TokenStream2 = if args.bytes_mode {
quote! {
let #binding: &'static [u8] =
include_str!(concat!(env!("OUT_DIR"), "/fingerprint.json")).as_bytes();
}
} else {
quote! {
let #binding = #cap::parse(
include_str!(concat!(env!("OUT_DIR"), "/fingerprint.json"))
)?;
}
};
expanded.into()
}