use std::convert::TryFrom;
extern crate proc_macro;
use dot_parser::ast::Graph;
use litrs::StringLit;
use quote::quote;
#[proc_macro]
pub fn from_dot_file(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = proc_macro2::TokenStream::from(input);
let tokens: Vec<_> = input.into_iter().collect();
if tokens.len() != 1 {
let output: proc_macro2::TokenStream = {
quote! {
compile_error!("Expect a single path argument")
}
};
return proc_macro::TokenStream::from(output);
}
let token = tokens.into_iter().next().unwrap();
let str_lit = match StringLit::try_from(token) {
Err(e) => return e.to_compile_error(),
Ok(lit) => lit,
};
let graph = match Graph::from_file(str_lit.value()) {
Err(f) => {
let msg = format!("{}", f);
return quote! { compile_error!(#msg)}.into();
}
Ok(graph) => graph,
};
let output: proc_macro2::TokenStream = quote! { #graph };
proc_macro::TokenStream::from(output)
}
#[proc_macro]
pub fn from_dot_string(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = proc_macro2::TokenStream::from(input);
let tokens: Vec<_> = input.into_iter().collect();
if tokens.len() != 1 {
let output: proc_macro2::TokenStream = {
quote! {
compile_error!("Expect a single argument, which must be a literal containing a DOT graph description.")
}
};
return proc_macro::TokenStream::from(output);
}
let token = tokens.into_iter().next().unwrap();
let str_lit = match StringLit::try_from(token) {
Err(e) => return e.to_compile_error(),
Ok(lit) => lit,
};
let graph = match Graph::try_from(str_lit.value()) {
Err(f) => {
let msg = format!("{}", f);
return quote! { compile_error!(#msg)}.into();
}
Ok(graph) => graph.filter_map(&|(s1, s2): (&str, &str)| Some((s1.to_string(), s2.to_string()))),
};
let output: proc_macro2::TokenStream = quote! { #graph };
proc_macro::TokenStream::from(output)
}