dfir_datalog/
lib.rs
1use dfir_datalog_core::diagnostic::Diagnostic;
2use dfir_datalog_core::{dfir_graph_to_program, gen_dfir_graph};
3use proc_macro2::Span;
4use quote::{ToTokens, quote};
5
6#[proc_macro]
13pub fn datalog(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
14 let item = proc_macro2::TokenStream::from(item);
15 let literal: proc_macro2::Literal = syn::parse_quote! {
16 #item
17 };
18
19 const DFIR_CRATE: &str = "dfir_rs";
20
21 let dfir_crate = proc_macro_crate::crate_name(DFIR_CRATE)
22 .unwrap_or_else(|_| panic!("`{}` should be present in `Cargo.toml`", DFIR_CRATE));
23 let root = match dfir_crate {
24 proc_macro_crate::FoundCrate::Itself => {
25 let ident = syn::Ident::new(DFIR_CRATE, Span::call_site());
26 quote! { #ident }
27 }
28 proc_macro_crate::FoundCrate::Name(name) => {
29 let ident = syn::Ident::new(&name, Span::call_site());
30 quote! { #ident }
31 }
32 };
33
34 match gen_dfir_graph(literal) {
35 Ok(graph) => {
36 let program = dfir_graph_to_program(graph, root);
37 program.to_token_stream().into()
38 }
39 Err(diagnostics) => {
40 let diagnostic_tokens = Diagnostic::try_emit_all(diagnostics.iter())
41 .err()
42 .unwrap_or_default();
43 proc_macro::TokenStream::from(quote! {
44 {
45 #diagnostic_tokens
46 dfir_rs::scheduled::graph::Dfir::new()
47 }
48 })
49 }
50 }
51}