use std::any::type_name;
use std::fmt::Debug;
use super::*;
pub trait Parse : Sized + Debug {
fn span(&self) -> &Span;
fn start(&self) -> Place {
self.span().start()
}
fn end(&self) -> Place {
self.span().end()
}
fn label() -> String {
type_name::<Self>().to_string()
}
fn description() -> String {
let label = Self::label();
format!("Expected '{label}' here.")
}
fn error(span: Span, level: Level) -> Error {
let description = Self::description();
Error::new(Some(span), level, &description)
}
fn is_error() -> bool { false }
fn parse(state: &mut State) -> Result<Self>;
fn can_parse(state: &mut State) -> bool {
let ref mut cloned_state = state.clone();
Self::parse(cloned_state).is_ok()
}
fn find(state: &mut State) -> Option::<Self> {
loop {
let end_index = state.page().len();
if state.index() == end_index {
return None;
}
else if Self::can_parse(state) {
let ok = Self::parse(state).unwrap();
return Some(ok);
}
else { state.index += 1; }
}
}
fn is_found_in(state: &mut State) -> bool {
Self::find(state).is_some()
}
fn find_all(state: &mut State) -> Vec::<Self> {
let mut parsed_values = Vec::default();
let ref mut cloned_state = state.clone();
loop {
let start_index = state.index();
let found_maybe = Self::find(cloned_state);
match found_maybe {
Some(some) => parsed_values.push(some),
None => break
}
let end_index = state.index();
let progress = match end_index - start_index == 0 {
true => 1,
false => end_index - start_index
};
state.index += progress
}
parsed_values
}
}