#[allow(clippy::wildcard_imports)]
use crate::prelude::*;
use crate::always_impl;
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub struct Newline;
impl<'a> Tool<'a> for Newline {
type Data = ();
type Error = View<'a>;
fn parse(&self, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error>{
Seq{
first : RepeatAny::new_bounds('\r', TrueTool, 1),
second :'\n'
}
.parse(st)
.map(|d| ((), d.1, d.2))
.map_err(Either::into_second)
}
}
#[derive(Debug, Copy, Clone)]
pub struct WhiteSP;
impl<'a> AlwaysTool<'a> for WhiteSP{
fn parse_always(&self, st : View<'a>) -> (Self::Data, usize, View<'a>){
let (_, a, b) = RepeatAny::new_unbounded(Predicate::new(char::is_whitespace), TrueTool).parse_always(st);
((), a, b)
}
}
always_impl!(WhiteSP);
#[derive(Debug, Copy, Clone)]
pub struct Ident;
impl<'a> Tool<'a> for Ident{
type Data = &'a str;
type Error = View<'a>;
fn parse(&self, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error>{
let su = Seq{
first : Predicate::new(char::is_alphabetic),
second : RepeatAny::new_unbounded(Predicate::new(char::is_alphanumeric), TrueTool)
};
st.match_tool_string(&su)
.map(|(s, step)| (s, s.len(), step))
.map_err(Either::into_first)
}
}
struct NumberCount{
num : usize,
radix : u32,
}
impl<Z> InsertB<u32, Z> for NumberCount {
fn insert(&mut self, data : u32) {
self.num = self.num * (self.radix as usize) + (data as usize);
}
fn insert_sep(&mut self, _ : Z) {}
}
pub struct AsciiNumber(u32);
impl AsciiNumber{
#[must_use]
pub fn new(radix : u32) -> Self {
assert!((2..=36).contains(&radix), "Invalid radix");
Self(radix)
}
}
impl<'a> Tool<'a> for AsciiNumber {
type Data = usize;
type Error = View<'a>;
fn parse(&self, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error>{
let mut count = NumberCount{num : 0, radix : self.0};
let st = Repeat::new_unbounded(PredicateData::new(
|c : char| c.to_digit(self.0)),
SetError::<_, View<'a>>::new(TrueTool), 1).parse_logic(st, &mut count)?.finalize();
Ok((count.num, st.1, st.2))
}
}
pub struct PfxAsciiNumber;
impl<'a> Tool<'a> for PfxAsciiNumber {
type Data = usize;
type Error = View<'a>;
fn parse(&self, st : View<'a>) -> Result<(Self::Data, usize, View<'a>), Self::Error>{
st.match_if_else_data_len(&"0x", &AsciiNumber::new(16), |st| {
st.match_if_else_data_len(&"0o", &AsciiNumber::new(8), |st| {
st.match_if_else_data_len(&"0b", &AsciiNumber::new(2), |st| st.match_tool_data_len(&AsciiNumber::new(10)))
})})
}
}