diff --git a/src/gamelog.rs b/src/gamelog.rs index a707a54..a98421d 100644 --- a/src/gamelog.rs +++ b/src/gamelog.rs @@ -1,20 +1,56 @@ use semver; use serde::Deserialize; -use std::{fmt, fs::File, u64}; +use std::{fmt, fs::File, io, path::PathBuf, u64}; pub const GAMELOG_MIN_VER: semver::Version = semver::Version::new(0, 2, 0); +#[derive(Debug)] +pub enum LogFileError { + FailedToOpen(io::Error), + RonSpannedError(ron::error::SpannedError), + CompatibilityCheck, +} + +impl fmt::Display for LogFileError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::FailedToOpen(err) => write!(f, "{}", err), + Self::CompatibilityCheck => write!(f, "Variant was not Down::Kickoff."), + Self::RonSpannedError(err) => write!(f, "{}", err), + } + } +} + #[derive(Debug, Deserialize)] pub struct LogFile(Vec); impl TryFrom for LogFile { - type Error = ron::de::SpannedError; + type Error = ron::error::SpannedError; fn try_from(file: File) -> Result { ron::de::from_reader(file) } } +impl TryFrom for LogFile { + type Error = LogFileError; + + fn try_from(path: PathBuf) -> Result { + match Self::try_from( + match std::fs::OpenOptions::new() // Defaults to setting all options false. + .read(true) // Only need ensure that reading is possible. + .open(path.as_path()) + { + Ok(f) => f, + Err(err) => return Err(LogFileError::FailedToOpen(err)), + }, + ) { + Ok(f) => Ok(f), + Err(err) => Err(LogFileError::RonSpannedError(err)), + } + } +} + impl LogFile { pub fn get_min_ver(&mut self) -> semver::Version { let mut lowest = semver::Version::new(u64::MAX, u64::MAX, u64::MAX); @@ -27,6 +63,25 @@ impl LogFile { lowest } + + /// Returns if the LogFile min version is compatible. + fn is_compatible(&mut self) -> bool { + self.get_min_ver().cmp_precedence(&GAMELOG_MIN_VER).is_lt() + } + + /// Attempts to make a gamefile compatible. + pub fn make_compatible(&mut self) -> Result<&mut Self, LogFileError> { + todo!() + } + + /// Ensures that the returned gamefile is compatible, else returns Error. + pub fn ensure_compatible(&mut self) -> Result<&mut Self, LogFileError> { + if self.is_compatible() { + Ok(self) + } else { + Err(LogFileError::CompatibilityCheck) + } + } } #[derive(Debug, Deserialize)] diff --git a/src/main.rs b/src/main.rs index 6aeb6a2..48a8e6e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ mod calculator; mod gamelog; use clap::Parser; +use core::panic; use gamelog::{GAMELOG_MIN_VER, LogFile}; use std::path::PathBuf; @@ -22,24 +23,8 @@ struct Args { fn main() { let config = Args::parse(); - let mut log: LogFile = LogFile::try_from( - match std::fs::OpenOptions::new() // Defaults to setting all options false. - .read(true) // Only need ensure that reading is possible. - .open(&config.logfile_path.as_path()) - { - Ok(f) => f, - Err(err) => panic!("Failed to open log file: {:?}", err), - }, - ) - .expect("Failed to open game log file"); - - let log_ver = dbg!(log.get_min_ver()); - - if log_ver.cmp_precedence(&GAMELOG_MIN_VER).is_lt() { - panic!( - "Error: Log file GameRecord version deviates as low as {:?}, while minimum {:?} is required", - log_ver.to_string(), - GAMELOG_MIN_VER.to_string() - ) - } + let mut log: LogFile = match LogFile::try_from(config.logfile_path) { + Ok(f) => f, + Err(err) => panic!("Error: Failed to open logfile: {:?}", err), + }; }