use proc_macro::TokenStream;
use syn::parse::{Parse, ParseStream};
use syn::{parse_macro_input, Token};
struct RosLibRustMessagePaths {
paths: Vec<std::path::PathBuf>,
}
impl Parse for RosLibRustMessagePaths {
fn parse(input: ParseStream) -> syn::Result<Self> {
let mut paths = vec![];
while let Ok(path) = input.parse::<syn::LitStr>() {
paths.push(path.value().into());
if input.parse::<Token![,]>().is_ok() {
continue;
} else {
break;
}
}
Ok(Self { paths })
}
}
#[proc_macro]
pub fn find_and_generate_ros_messages(input_stream: TokenStream) -> TokenStream {
let RosLibRustMessagePaths { paths } =
parse_macro_input!(input_stream as RosLibRustMessagePaths);
match roslibrust_codegen::find_and_generate_ros_messages(paths) {
Ok(t) => t.into(),
Err(e) => {
let error_msg = e.to_string();
quote::quote!(compile_error!(#error_msg);).into()
}
}
}
#[proc_macro]
pub fn find_and_generate_ros_messages_relative_to_manifest_dir(
input_stream: TokenStream,
) -> TokenStream {
let RosLibRustMessagePaths { mut paths } =
parse_macro_input!(input_stream as RosLibRustMessagePaths);
std::env::set_current_dir(env!("CARGO_MANIFEST_DIR")).expect("Failed to set working dir");
for path in &mut paths {
*path = path.canonicalize().unwrap_or_else(|err| {
panic!("Failed to canonicalize path {path:?}: {}", err.to_string())
});
}
match roslibrust_codegen::find_and_generate_ros_messages(paths) {
Ok(t) => t.into(),
Err(e) => {
let error_msg = e.to_string();
quote::quote!(compile_error!(#error_msg);).into()
}
}
}
#[proc_macro]
pub fn find_and_generate_ros_messages_without_ros_package_path(
input_stream: TokenStream,
) -> TokenStream {
let RosLibRustMessagePaths { paths } =
parse_macro_input!(input_stream as RosLibRustMessagePaths);
match roslibrust_codegen::find_and_generate_ros_messages_without_ros_package_path(paths) {
Ok(t) => t.into(),
Err(e) => {
let error_msg = e.to_string();
quote::quote!( compile_error!(#error_msg); ).into()
}
}
}