use std::path::{Path, PathBuf}; use java::{JAVA_EXT_CLASS, JAVA_EXT_SOURCE}; use serde::{Deserialize, Serialize}; use crate::{Error, Result}; /// [`Class`] represents a source file. It is a handler. #[derive(Debug, Clone, Deserialize, Serialize, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Class { /// Path relative to PACKAGE/java, without file extension. pub path: PathBuf, pub checksum: String, } impl Class { /// Creates a new [`Class`]. /// /// # Error /// /// * [`Error::MismatchedPackage`] if the provided `file_path` is absolute, and cannot be /// subtracted to just its relative path within its parent package. /// * [`Error::Io`] if the source file cannot be loaded and digested. pub fn new>(package_src_root: P, file_path: P) -> Result { let mut file_path = file_path.as_ref().to_path_buf(); if file_path.is_absolute() { file_path = pathsub::sub_paths(file_path.as_path(), package_src_root.as_ref()) .ok_or(Error::MismatchedPackage)?; } Ok(Self { path: dbg!(file_path.with_extension("")), checksum: sha256::try_digest(package_src_root.as_ref().join(file_path))?, }) } /// Returns a boolean representing if the class is up to date. /// /// # Criteria /// /// * The class path is local. /// * The class has been compiled to `target/` /// * The class' source file has not been updated. /// /// # Errors /// /// * [`Error::Io`] pub fn is_updated>(&self, class_path: P) -> Result { // If the path is local and that file has not been updated. Ok(class_path .as_ref() .join(self.path.as_path()) .with_extension(JAVA_EXT_CLASS) .exists() && self.checksum == sha256::try_digest(self.path.clone())?) } /// Updates the class' checksum. /// /// Only call this if you know that the class has been compiled successfully. /// /// # Errors /// /// * [`Error::Io`] if the source file cannot be loaded and digested. pub fn update>(&mut self, package_src_root: P) -> Result<()> { self.checksum = sha256::try_digest(dbg!( package_src_root .as_ref() .join(self.path.as_path()) .with_extension(JAVA_EXT_SOURCE), ))?; Ok(()) } }