#![doc(html_root_url = "https://docs.rs/impl_sim/0.3.0")]
use proc_macro::TokenStream;
use proc_macro2::TokenStream as PM2TS;
use proc_macro2::TokenTree;
use quote::{quote, ToTokens}; use syn;
#[proc_macro]
pub fn impl_sim_fn(item: TokenStream) -> TokenStream {
let ts: PM2TS = item.into();
let tk = match ts.into_iter().next().unwrap() {
TokenTree::Ident(t) => Some(t), _ => None };
let f = &tk.unwrap();
let s = &f.to_string();
match s.as_str() {
"draw_geom" => {
quote! {
fn #f(&self, geom: dGeomID,
pos: Option<*const dReal>, rot: Option<*const dReal>, ws: i32) {
ostatln!(concat!("called ", #s));
self.super_get().#f(geom, pos, rot, ws);
}
}
},
"near_callback" => {
quote! {
fn #f(&mut self, dat: *mut c_void, o1: dGeomID, o2: dGeomID) {
ostatln!(concat!("called ", #s));
self.super_mut().#f(dat, o1, o2);
}
}
},
"step_callback" => {
quote! {
fn #f(&mut self, pause: i32) {
ostatln!(concat!("called ", #s));
self.super_mut().#f(pause);
}
}
},
"command_callback" => {
quote! {
fn #f(&mut self, cmd: i32) {
ostatln!(concat!("called ", #s));
self.super_mut().#f(cmd);
}
}
},
_ => {
quote! {
fn #f(&mut self) {
ostatln!(concat!("called ", #s));
self.super_mut().#f();
}
}
}
}.into()
}
#[proc_macro_attribute]
pub fn impl_sim_derive(attr: TokenStream, item: TokenStream) -> TokenStream {
let mut ast = syn::parse_macro_input!(item as syn::ItemImpl);
let ts: PM2TS = attr.into();
for tt in ts {
match tt {
TokenTree::Ident(f) => { ast.items.push(syn::parse_quote! {
impl_sim_fn!(#f);
});
},
_ => {} }
}
ast.into_token_stream().into()
}