use std::sync::Arc;
#[derive(Clone, Debug)]
pub struct ParseContainer {
raw: Arc<String>,
begin: usize,
end: usize,
}
impl ParseContainer {
pub fn new(raw: Arc<String>) -> Self {
let end = raw.len();
Self { raw, begin: 0, end }
}
pub fn is_empty(&self) -> bool {
self.as_str().is_empty()
}
pub fn len(&self) -> usize {
self.as_str().len()
}
pub fn as_str(&self) -> &str {
&self.raw[self.begin..self.end]
}
pub fn split_at(&self, step: usize) -> (Self, Self) {
let rest = Self {
begin: self.begin + step,
..self.clone()
};
let parsed = Self {
end: self.begin + step,
..self.clone()
};
(rest, parsed)
}
}
impl PartialEq<ParseContainer> for ParseContainer {
fn eq(&self, rhs: &ParseContainer) -> bool {
self.as_str() == rhs.as_str()
}
}
impl PartialEq<&str> for ParseContainer {
fn eq(&self, rhs: &&str) -> bool {
self.as_str() == *rhs
}
}
impl PartialEq<ParseContainer> for &str {
fn eq(&self, rhs: &ParseContainer) -> bool {
*self == rhs.as_str()
}
}
impl std::borrow::Borrow<str> for ParseContainer {
fn borrow(&self) -> &str {
self.as_str()
}
}
impl std::fmt::Display for ParseContainer {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
self.as_str().fmt(formatter)
}
}
impl From<&str> for ParseContainer {
fn from(s: &str) -> Self {
Self::new(Arc::new(s.into()))
}
}
impl From<Vec<ParseContainer>> for ParseContainer {
fn from(x: Vec<ParseContainer>) -> Self {
if x.is_empty() {
return Self::new(Arc::new("".into()));
}
let x0 = x.get(0).unwrap();
let len = x.iter().fold(0, |stack, item| stack + item.len());
Self {
end: x0.begin + len,
..x0.clone()
}
}
}
macro_rules! wr {
($func:expr) => {
|input: ParseContainer| {
use std::sync::Arc;
let input_str = input.as_str();
let (_rest, parsed) =
$func(input_str).map_err(|e: nom::Err<nom::error::Error<&str>>| {
e.map_input(|x| ParseContainer::new(Arc::new(x.to_owned())))
})?;
let (rest, parsed) = input.split_at(parsed.len());
Ok((rest, parsed))
}
};
}
pub(crate) use wr;