refact: make FialedParserResult to implement std::Error:Error.
This commit is contained in:
		@@ -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()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn input(&self) -> &'a [TToken] {
 | 
			
		||||
        self.input
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Display for 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: {}.", self.message)
 | 
			
		||||
        write!(
 | 
			
		||||
            f,
 | 
			
		||||
            "Parse failed: {}, the input is '{:?}'.",
 | 
			
		||||
            self.message, self.input
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub type ParserResult<'a, TToken, T> =
 | 
			
		||||
    Result<(&'a [TToken], T), (&'a [TToken], FailedParserResult)>;
 | 
			
		||||
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());
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user