use std::fmt;
use std::path::Path;
use crate::ast::TPTPProblem;
use crate::error::ParseError;
use crate::parser::parse_tptp;
#[derive(Debug)]
pub enum ParseFileError {
Io(std::io::Error),
Parse(ParseError),
}
impl fmt::Display for ParseFileError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ParseFileError::Io(e) => write!(f, "I/O error: {e}"),
ParseFileError::Parse(e) => write!(f, "{e}"),
}
}
}
impl std::error::Error for ParseFileError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
ParseFileError::Io(e) => Some(e),
ParseFileError::Parse(e) => Some(e),
}
}
}
impl From<std::io::Error> for ParseFileError {
fn from(e: std::io::Error) -> Self {
ParseFileError::Io(e)
}
}
impl From<ParseError> for ParseFileError {
fn from(e: ParseError) -> Self {
ParseFileError::Parse(e)
}
}
pub struct OwnedTPTPProblem {
_source: String,
problem: TPTPProblem<'static>,
}
impl OwnedTPTPProblem {
pub fn problem(&self) -> &TPTPProblem<'_> {
&self.problem
}
pub fn source(&self) -> &str {
&self._source
}
}
impl std::ops::Deref for OwnedTPTPProblem {
type Target = TPTPProblem<'static>;
fn deref(&self) -> &Self::Target {
&self.problem
}
}
impl fmt::Debug for OwnedTPTPProblem {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OwnedTPTPProblem")
.field("formulas", &self.problem.formulas.len())
.field("includes", &self.problem.includes.len())
.finish()
}
}
pub fn parse_tptp_owned(source: String) -> Result<OwnedTPTPProblem, ParseError> {
let source_ref: &str = source.as_str();
let source_static: &'static str = unsafe { std::mem::transmute(source_ref) };
let problem = parse_tptp(source_static)?;
Ok(OwnedTPTPProblem {
_source: source,
problem,
})
}
pub fn parse_tptp_file(path: &Path) -> Result<OwnedTPTPProblem, ParseFileError> {
let source = std::fs::read_to_string(path)?;
parse_tptp_owned(source).map_err(ParseFileError::Parse)
}