use core::fmt;
use std::{collections::TryReserveError, num};
use ::num::bigint;
use lasso::LassoError;
#[cfg(feature = "mem_dbg")]
use mem_dbg::{MemDbg, MemSize};
use nonmax::ParseIntError;
use crate::items::{Blame, ENodeIdx, Fingerprint, QuantIdx, TermId, TermIdx};
pub type Result<T> = std::result::Result<T, Error>;
pub type FResult<T> = std::result::Result<T, FatalError>;
#[cfg_attr(feature = "mem_dbg", derive(MemSize, MemDbg))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Either<T, U> {
Left(T),
Right(U),
}
impl<T, U> Either<T, U> {
pub fn into_result(self) -> std::result::Result<T, U> {
match self {
Self::Left(t) => Ok(t),
Self::Right(u) => Err(u),
}
}
}
#[derive(Debug)]
pub enum Error {
UnknownLine(String),
UnexpectedNewline,
ExpectedNewline(String),
UnexpectedEnd,
InvalidVersion(semver::Error),
InvalidIdNumber(ParseIntError),
InvalidIdHash(String),
UnknownId(TermId),
InvalidVar(ParseIntError),
ParseBigUintError(bigint::ParseBigIntError),
ParseError(String),
VarNamesListInconsistent, VarNamesNoBar,
InvalidVarNum(ParseIntError),
UnknownQuantifierIdx(TermIdx),
NonNullLambdaName(String),
InvalidQVarInteger(ParseIntError),
NewMatchOnLambda(QuantIdx),
UnknownPatternIdx(TermIdx),
SubpatTooFewBlame(usize),
SubpatNoBlame(Vec<TermIdx>),
NonRewriteAxiomInvalidEnode(TermIdx),
RewriteAxiomMultipleTerms1(TermIdx),
RewriteAxiomMultipleTerms2(Vec<Blame>),
UnknownInstMethod(String),
UnmatchedEndOfInstance,
TupleMissingParens,
UnequalTupleForms(u8, u8),
InvalidFingerprint(num::ParseIntError),
UnknownFingerprint(Fingerprint),
UnknownEnode(TermIdx),
InvalidGeneration(ParseIntError),
EnodeRootMismatch(ENodeIdx, ENodeIdx),
UnknownEqLit,
StackFrameNotPushed,
PopConflictMismatch,
InvalidFrameInteger(num::ParseIntError),
NoConflict,
BoolLiteral,
BoolLiteralNotP,
InvalidBoolLiteral(num::ParseIntError),
UnknownJustification(String),
MissingColonJustification,
InvalidTheoryId(num::ParseIntError),
Allocation(TryReserveError),
Lasso(LassoError),
Debug,
}
impl From<semver::Error> for Error {
fn from(err: semver::Error) -> Self {
Self::InvalidVersion(err)
}
}
impl From<TryReserveError> for Error {
fn from(err: TryReserveError) -> Self {
Self::Allocation(err)
}
}
impl From<LassoError> for Error {
fn from(value: LassoError) -> Self {
Self::Lasso(value)
}
}
impl Error {
pub fn is_oom(&self) -> bool {
matches!(self, Self::Allocation(_) | Self::Lasso(_))
}
pub fn as_fatal(self) -> Option<FatalError> {
match self {
Self::Allocation(alloc) => Some(FatalError::Allocation(alloc)),
Self::Lasso(lasso) => Some(FatalError::Lasso(lasso)),
_ => None,
}
}
}
#[derive(Debug, Clone)]
pub enum FatalError {
Allocation(TryReserveError),
Lasso(LassoError),
Io(std::rc::Rc<std::io::Error>),
}
impl From<std::io::Error> for FatalError {
fn from(err: std::io::Error) -> Self {
Self::Io(std::rc::Rc::new(err))
}
}
impl fmt::Display for FatalError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Allocation(alloc) => write!(f, "Allocation error: {alloc}"),
Self::Lasso(lasso) => write!(f, "String interning error: {lasso}"),
Self::Io(err) => write!(f, "IO error: {err}"),
}
}
}