use lazy_static::lazy_static;
use proc_macro2::Literal;
use regex::{Captures, Regex};
use std::borrow::Cow;
const TRIPPLE_EQ: &str = "\"__============__\"";
const NL_PATCH: &str = "\"__nlnlnlnl__\"";
const NAMES: [(&str, &str); 13] = [
("brack", r"\s*\[\s+\]"),
("brace", r"\{\s+\}"),
("colon", r"\s+[:]\s"),
("enl", r"\n+\}"),
("fnl", r"\{\n+"),
("te", TRIPPLE_EQ), ("lt", r"\s<\s"),
("gt", r"\s>(\s|$)"),
("semi", r"\s+;"),
("call", r"\s\(\s+\)\s"),
("dot", r"\s\.\s"),
("nlpatch", NL_PATCH), ("nl", r"\n+"), ];
lazy_static! {
static ref RE: Regex = {
let v = NAMES
.iter()
.map(|(n, re)| format!("(?P<{}>{})", n, re))
.collect::<Vec<_>>()
.join("|");
Regex::new(&v).unwrap()
};
}
trait Has {
fn has(&self, s: &'static str) -> bool;
fn key(&self) -> &'static str;
}
impl Has for Captures<'_> {
#[inline]
fn has(&self, s: &'static str) -> bool {
self.name(s).is_some()
}
fn key(&self) -> &'static str {
for n in &NAMES {
if self.has(n.0) {
return n.0;
}
}
"?"
}
}
pub fn patch(s: &str) -> Cow<'_, str> {
RE.replace_all(s, |c: &Captures| {
let key = c.key();
let m = match key {
"brace" => "{}",
"brack" => "[]",
"colon" => ": ",
"fnl" => "{ ",
"enl" => " }",
"nl" => " ",
"te" => "===",
"lt" => "<",
"gt" => ">",
"semi" => ";",
"dot" => ".",
"call" => " () ",
"nlpatch" => "\n",
_ => return Cow::Owned(c.get(0).unwrap().as_str().to_owned()), };
Cow::Borrowed(m)
})
}
#[inline]
pub fn eq() -> Literal {
Literal::string(&TRIPPLE_EQ[1..TRIPPLE_EQ.len() - 1])
}
#[inline]
pub fn nl() -> Literal {
Literal::string(&NL_PATCH[1..NL_PATCH.len() - 1])
}