refact: make FialedParserResult to implement std::Error:Error.
This commit is contained in:
parent
91c6c42a02
commit
e2c4388a0c
|
@ -219,7 +219,7 @@ where
|
|||
PSeparator: Parser<'a, TToken, TSeparator, TContext>,
|
||||
{
|
||||
separate_by1(parser, separator).next(|r| match r {
|
||||
Err((input, _)) => Ok((input, vec![])),
|
||||
Err(r) => Ok((r.input(), vec![])),
|
||||
r => r,
|
||||
})
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ where
|
|||
PSeparator: Parser<'a, TToken, TSeparator, TContext>,
|
||||
{
|
||||
separate_or_end_by1(parser, separator).next(|r| match r {
|
||||
Err((i, _)) => Ok((i, vec![])),
|
||||
Err(r) => Ok((r.input(), vec![])),
|
||||
r => r,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -136,9 +136,9 @@ where
|
|||
input = i;
|
||||
result.push(r);
|
||||
} else {
|
||||
return Err((
|
||||
return Err(FailedParserResult::new_with_str(
|
||||
input,
|
||||
FailedParserResult::new("End with other elements.".to_owned()),
|
||||
"End with other elements.",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -174,9 +174,9 @@ where
|
|||
result.push(r);
|
||||
input = i;
|
||||
} else {
|
||||
return Err((
|
||||
return Err(FailedParserResult::new_with_str(
|
||||
input,
|
||||
FailedParserResult::new("End with other elements.".to_owned()),
|
||||
"End with other elements.",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,33 +10,51 @@ use crate::parser::primitive_parsers::{
|
|||
TakeParser,
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::marker::PhantomData;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FailedParserResult {
|
||||
pub struct FailedParserResult<'a, TToken: Debug> {
|
||||
input: &'a [TToken],
|
||||
message: String,
|
||||
}
|
||||
|
||||
impl FailedParserResult {
|
||||
pub fn new(message: String) -> Self {
|
||||
Self { message }
|
||||
impl<'a, TToken: Debug> FailedParserResult<'a, TToken> {
|
||||
pub fn new(input: &'a [TToken], message: String) -> Self {
|
||||
Self { input, message }
|
||||
}
|
||||
|
||||
pub fn new_with_str(input: &'a [TToken], message: &'static str) -> Self {
|
||||
Self {
|
||||
input,
|
||||
message: message.to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn message(&self) -> &str {
|
||||
self.message.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for FailedParserResult {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Parse failed: {}.", self.message)
|
||||
pub fn input(&self) -> &'a [TToken] {
|
||||
self.input
|
||||
}
|
||||
}
|
||||
|
||||
pub type ParserResult<'a, TToken, T> =
|
||||
Result<(&'a [TToken], T), (&'a [TToken], FailedParserResult)>;
|
||||
impl<'a, TToken: Debug> Error for FailedParserResult<'a, TToken> {}
|
||||
|
||||
impl<'a, TToken: Debug> Display for FailedParserResult<'a, TToken> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"Parse failed: {}, the input is '{:?}'.",
|
||||
self.message, self.input
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub type ParserResult<'a, TToken, T> = Result<(&'a [TToken], T), FailedParserResult<'a, TToken>>;
|
||||
|
||||
pub struct ParserContext<TToken, TContext>
|
||||
where
|
||||
|
|
|
@ -121,11 +121,9 @@ where
|
|||
let (input, _) = self.parser.parse(context, input)?;
|
||||
|
||||
if origin_input.is_empty() {
|
||||
return Err((
|
||||
return Err(FailedParserResult::new_with_str(
|
||||
input,
|
||||
FailedParserResult::new(
|
||||
"Empty input, the 'literal' parser cann't get length of elememt.".to_owned(),
|
||||
),
|
||||
"Empty input, the 'literal' parser cann't get length of elememt.",
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -156,11 +154,9 @@ where
|
|||
let (input, _) = self.parser.parse(context, input)?;
|
||||
|
||||
if origin_input.is_empty() {
|
||||
return Err((
|
||||
return Err(FailedParserResult::new_with_str(
|
||||
input,
|
||||
FailedParserResult::new(
|
||||
"Empty input, the 'literal' parser cann't get length of elememt.".to_owned(),
|
||||
),
|
||||
"Empty input, the 'literal' parser cann't get length of elememt.",
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -212,11 +208,11 @@ where
|
|||
input: &'a [TToken],
|
||||
) -> ParserResult<'a, TToken, TResult> {
|
||||
match self.parser.parse(context, input) {
|
||||
Ok((input, _)) => Err((
|
||||
Ok(_) => Err(FailedParserResult::new_with_str(
|
||||
input,
|
||||
FailedParserResult::new("Reverse failed succeeded.".to_owned()),
|
||||
"Reverse successful parser.",
|
||||
)),
|
||||
Err((input, _)) => Ok((input, self.result.clone())),
|
||||
Err(_) => Ok((input, self.result.clone())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +265,7 @@ mod test {
|
|||
let (input, result) = satisfy(|c: &char| c.is_numeric()).parse(context, input)?;
|
||||
|
||||
match result.to_digit(10) {
|
||||
None => Err((input, FailedParserResult::new("What?".to_string()))),
|
||||
None => Err(FailedParserResult::new_with_str(input, "What?")),
|
||||
Some(r) => Ok((input, Number(r as i32))),
|
||||
}
|
||||
}
|
||||
|
@ -300,7 +296,7 @@ mod test {
|
|||
satisfy(|c: &char| c.is_numeric())
|
||||
.next(|r| match r {
|
||||
Ok((input, result)) => match result.to_digit(10) {
|
||||
None => Err((input, FailedParserResult::new("What?".to_string()))),
|
||||
None => Err(FailedParserResult::new_with_str(input, "What?")),
|
||||
Some(r) => Ok((input, Number(r as i32))),
|
||||
},
|
||||
Err(r) => Err(r),
|
||||
|
|
|
@ -35,9 +35,9 @@ where
|
|||
_: Rc<RefCell<ParserContext<TToken, TContext>>>,
|
||||
input: &'a [TToken],
|
||||
) -> ParserResult<'a, TToken, T> {
|
||||
Err((
|
||||
Err(FailedParserResult::new_with_str(
|
||||
input,
|
||||
FailedParserResult::new("Default failed parser.".to_owned()),
|
||||
"Default failed parser.",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ where
|
|||
_: Rc<RefCell<ParserContext<TToken, TContext>>>,
|
||||
input: &'a [TToken],
|
||||
) -> ParserResult<'a, TToken, T> {
|
||||
Err((input, FailedParserResult::new(self.message.clone())))
|
||||
Err(FailedParserResult::new(input, self.message.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,16 +75,13 @@ where
|
|||
input: &'a [TToken],
|
||||
) -> ParserResult<'a, TToken, TToken> {
|
||||
if input.is_empty() {
|
||||
return Err((input, FailedParserResult::new("Input is empty.".to_owned())));
|
||||
return Err(FailedParserResult::new_with_str(input, "Input is empty"));
|
||||
}
|
||||
|
||||
if (self.predicate)(&input[0]) {
|
||||
Ok((&input[1..], input[0].clone()))
|
||||
} else {
|
||||
Err((
|
||||
input,
|
||||
FailedParserResult::new("Predicate failed.".to_owned()),
|
||||
))
|
||||
Err(FailedParserResult::new_with_str(input, "Predicate failed."))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +98,7 @@ where
|
|||
input: &'a [TToken],
|
||||
) -> ParserResult<'a, TToken, TToken> {
|
||||
if input.is_empty() {
|
||||
Err((input, FailedParserResult::new("Input is empty.".to_owned())))
|
||||
Err(FailedParserResult::new_with_str(input, "Input is empty"))
|
||||
} else {
|
||||
Ok((&input[1..], input[0].clone()))
|
||||
}
|
||||
|
@ -122,12 +119,12 @@ where
|
|||
input: &'a [TToken],
|
||||
) -> ParserResult<'a, TToken, Vec<TToken>> {
|
||||
if input.len() < self.count {
|
||||
Err((
|
||||
Err(FailedParserResult::new(
|
||||
input,
|
||||
FailedParserResult::new(format!(
|
||||
format!(
|
||||
"The input doesn't contain enough {} elemements.",
|
||||
self.count
|
||||
)),
|
||||
),
|
||||
))
|
||||
} else {
|
||||
Ok((
|
||||
|
@ -152,12 +149,12 @@ where
|
|||
input: &'a [TToken],
|
||||
) -> ParserResult<'a, TToken, ()> {
|
||||
if input.len() < self.count {
|
||||
Err((
|
||||
Err(FailedParserResult::new(
|
||||
input,
|
||||
FailedParserResult::new(format!(
|
||||
format!(
|
||||
"The input doesn't contain enough {} elemements.",
|
||||
self.count
|
||||
)),
|
||||
),
|
||||
))
|
||||
} else {
|
||||
Ok((&input[self.count..], ()))
|
||||
|
|
|
@ -78,7 +78,7 @@ fn file_lexical_parser_test() -> anyhow::Result<()> {
|
|||
let context = ParserContext::new_with_str(source_file.content.as_str(), ());
|
||||
let borrowed_context = context.borrow();
|
||||
let (_, zero_tokens) = zero_lexical_parser(context.clone(), borrowed_context.input_slice())
|
||||
.or_else(|e| Err(anyhow!("{}", e.1)))?;
|
||||
.or_else(|e| Err(anyhow!("{}", e)))?;
|
||||
|
||||
assert_eq!(nom_tokens.len(), zero_tokens.len());
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user