extern crate proc_macro;
extern crate quote;
extern crate syn;
use regex::Regex;
use proc_macro::TokenStream;
use syn::{parse_macro_input, ItemFn};
#[proc_macro_attribute]
pub fn kotlike(_attr: TokenStream, item: TokenStream) -> TokenStream {
let item_clone = item.clone();
let _func = parse_macro_input!(item as ItemFn); let raw = item_clone.to_string();
let seperator = Regex::new(r";[\s]+").expect("Invalid regex");
let new_item = seperator
.split(&raw)
.map(|line| {
let line = line.to_string();
let split = line.split("?.");
let split_size = split.clone().into_iter().count();
if split_size <= 1 {
line
} else {
split.enumerate().fold(String::new(), |mut acc, (j, item)| {
let s = item.to_string();
let tmp = if j == split_size - 1 {
let postfix = if s.ends_with(";") { ";" } else { "" };
let s_trim = s.trim_end_matches(|c: char| c == ';');
let repeat = ")".repeat(split_size - 1);
format!(".map_or(None,|mut v|Some(v.{s_trim}){repeat}{postfix}")
} else {
format!(".map_or(None,|mut v|v.{s}")
};
if acc.is_empty() {
acc.push_str(&s);
} else {
acc.push_str(&tmp);
}
acc
})
}
})
.collect::<Vec<String>>()
.join(";\n");
new_item.parse().unwrap()
}