use crate::types::Cursor;
use phf::phf_set;
static MARKUP_POST: phf::Set<u8> = phf_set! {
b'-',
b'.',
b',',
b';',
b':',
b'!',
b'?',
b')',
b'}',
b'[',
b'"',
b'\'',
b'\n',
b' ',
b'\t',
b'|',
b']',
b'/',
b'*',
b'_',
b'+',
};
static MARKUP_PRE: phf::Set<u8> = phf_set! {
b'-',
b'(',
b'{',
b'\'',
b'"',
b' ',
b'\t',
b'\n',
b'|',
b'[',
b'/',
b'*',
b'_',
b'+',
b':',
};
#[inline]
pub(crate) fn bytes_to_str(byte_arr: &[u8]) -> &str {
unsafe { std::str::from_utf8_unchecked(byte_arr) }
}
#[derive(Debug, Clone)]
pub struct Match<T> {
pub start: usize,
pub end: usize,
pub obj: T,
}
impl<'a, T> Match<T> {
#[inline]
pub fn to_str(&self, source: &'a str) -> &'a str {
&source[self.start..self.end]
}
pub fn len(&self) -> usize {
self.end - self.start
}
}
pub(crate) fn variant_eq<T>(a: &T, b: &T) -> bool {
std::mem::discriminant(a) == std::mem::discriminant(b)
}
pub(crate) fn verify_markup(cursor: Cursor, post: bool) -> bool {
let before_maybe = cursor.peek_rev(1);
let after_maybe = cursor.peek(1);
if post {
!before_maybe.unwrap().is_ascii_whitespace()
&& if let Ok(val) = after_maybe {
MARKUP_POST.contains(&val)
} else {
true
}
} else if let Ok(after) = after_maybe {
!after.is_ascii_whitespace()
&& if let Ok(val) = before_maybe {
MARKUP_PRE.contains(&val)
} else {
true
}
} else {
false
}
}
pub(crate) fn id_escape(potential_id: &str) -> String {
let mut ret = String::with_capacity(potential_id.len());
for chr in potential_id.chars() {
if chr == ' ' {
ret.push('-');
} else if chr == '_' || chr == '-' {
ret.push(chr);
} else if chr.is_alphanumeric() {
for val in chr.to_lowercase() {
ret.push(val);
}
}
}
ret
}
#[macro_export]
macro_rules! expr_in_pool {
($parsed: ident, $name: ident) => {
$parsed.pool.iter().find_map(|x| {
if let Expr::$name(i) = &x.obj {
Some(i)
} else {
None
}
})
};
}
#[macro_export]
macro_rules! node_in_pool {
($parsed: ident, $name: ident) => {
$parsed.pool.iter().find_map(|x| {
if let Expr::$name(i) = &x.obj {
Some(x)
} else {
None
}
})
};
}