use proc_macro::TokenStream;
use safety_parser::{
configuration::env::config_exists, proc_macro2::TokenStream as TokenStream2, quote::quote,
safety::SafetyAttrArgs as AttrArgs, split_attrs::split_attrs_and_rest, syn,
};
fn tag(attr: TokenStream, item: TokenStream) -> TokenStream {
let mut ts = TokenStream2::new();
let tool_attr = {
let attr = TokenStream2::from(attr.clone());
quote! { #[rapx::requires(#attr)] }
};
ts.extend(tool_attr);
let input = split_attrs_and_rest(item.into());
if !input.gen_doc {
ts.extend(input.attrs);
ts.extend(input.rest);
return ts.into();
}
ts.extend(input.attrs);
let attr_args: AttrArgs = syn::parse(attr).unwrap();
if config_exists() {
for tag in &attr_args.args {
ts.extend(tag.gen_doc());
}
}
ts.extend(input.rest);
ts.into()
}
#[proc_macro_attribute]
#[deprecated = "Use `#[requires]` instead."]
pub fn safety(attr: TokenStream, item: TokenStream) -> TokenStream {
tag(attr, item)
}
#[proc_macro_attribute]
pub fn requires(attr: TokenStream, item: TokenStream) -> TokenStream {
tag(attr, item)
}
#[proc_macro_attribute]
pub fn checked(attr: TokenStream, item: TokenStream) -> TokenStream {
let mut ts = TokenStream::new();
let tool_attr: TokenStream = {
let attr = TokenStream2::from(attr.clone());
quote! { #[rapx::checked(#attr)] }.into()
};
ts.extend(tool_attr);
ts.extend(item);
ts
}