use crate::core::parse_error::ParseError;
use crate::core::CommittedStatus;
#[derive(Debug, Clone)]
pub enum ParseResult<'a, I, A> {
Success {
value: A,
length: usize,
},
Failure {
error: ParseError<'a, I>,
committed_status: CommittedStatus,
},
}
impl<'a, I, A> ParseResult<'a, I, A> {
pub fn successful(value: A, length: usize) -> Self {
ParseResult::Success { value, length }
}
pub fn failed(error: ParseError<'a, I>, committed_status: CommittedStatus) -> Self {
ParseResult::Failure {
error,
committed_status,
}
}
pub fn failed_with_uncommitted(error: ParseError<'a, I>) -> Self {
Self::failed(error, CommittedStatus::Uncommitted)
}
pub fn failed_with_commit(error: ParseError<'a, I>) -> Self {
Self::failed(error, CommittedStatus::Committed)
}
pub fn to_result(self) -> Result<A, ParseError<'a, I>> {
match self {
ParseResult::Failure { error, .. } => Err(error),
ParseResult::Success { value, .. } => Ok(value),
}
}
pub fn is_success(&self) -> bool {
match self {
ParseResult::Failure { .. } => false,
ParseResult::Success { .. } => true,
}
}
pub fn success(self) -> Option<A> {
match self {
ParseResult::Failure { .. } => None,
ParseResult::Success { value, .. } => Some(value),
}
}
pub fn is_failure(&self) -> bool {
match self {
ParseResult::Failure { .. } => true,
ParseResult::Success { .. } => false,
}
}
pub fn failure(self) -> Option<ParseError<'a, I>> {
match self {
ParseResult::Failure { error, .. } => Some(error),
ParseResult::Success { .. } => None,
}
}
pub fn committed_status(&self) -> Option<CommittedStatus> {
match self {
ParseResult::Failure {
committed_status: is_committed,
..
} => Some(is_committed.clone()),
_ => None,
}
}
pub fn with_uncommitted(self) -> Self {
match self {
ParseResult::Failure {
error,
committed_status: CommittedStatus::Committed,
} => ParseResult::Failure {
error,
committed_status: CommittedStatus::Uncommitted,
},
_ => self,
}
}
pub fn with_committed_fallback(self, is_committed: bool) -> Self {
match self {
ParseResult::Failure {
error,
committed_status: c,
} => ParseResult::Failure {
error,
committed_status: (c.or(&is_committed.into())),
},
_ => self,
}
}
pub fn flat_map<B, F>(self, f: F) -> ParseResult<'a, I, B>
where
F: Fn(A, usize) -> ParseResult<'a, I, B>, {
match self {
ParseResult::Success { value, length } => f(value, length),
ParseResult::Failure {
error: e,
committed_status: c,
} => ParseResult::Failure {
error: e,
committed_status: c,
},
}
}
pub fn map<B, F>(self, f: F) -> ParseResult<'a, I, B>
where
F: Fn(A, usize) -> (B, usize), {
self.flat_map(|value, length| {
let (v, l) = f(value, length);
ParseResult::successful(v, l)
})
}
pub fn map_err<F>(self, f: F) -> Self
where
F: Fn(ParseError<'a, I>) -> ParseError<'a, I>, {
match self {
ParseResult::Failure {
error: e,
committed_status: c,
} => ParseResult::Failure {
error: f(e),
committed_status: c,
},
_ => self,
}
}
pub fn with_add_length(self, n: usize) -> Self {
match self {
ParseResult::Success { value, length: m } => ParseResult::Success { value, length: n + m },
_ => self,
}
}
}