use std::hash::Hash; use std::path::{Path, PathBuf}; use semver::Version; use serde::{Deserialize, Serialize}; use crate::class::Class; use crate::nest::{F_NEST_LOCK, Nest, NestLock}; pub const DIR_JAVA: &str = "java/"; /// Hashing is only based off the Prey. #[derive(Debug, Clone)] pub struct PackageHandler { prey: Nest, prey_lock: NestLock, /// Path relative to WORKSPACE/src package_root: PathBuf, target_dir: PathBuf, } impl PackageHandler { pub fn new>(src_dir: P, package_root: P, target_dir: P) -> crate::Result { let package_root = src_dir.as_ref().join(package_root.as_ref()); let prey_lock = if let Ok(prey_lock) = NestLock::try_from(package_root.join(F_NEST_LOCK)) { prey_lock } else { NestLock::new(package_root.clone(), package_root.join(DIR_JAVA))? }; Ok(Self { prey: Nest::try_from(package_root.join(F_NEST_LOCK))?, prey_lock, package_root, target_dir: target_dir.as_ref().to_path_buf(), }) } pub fn entry_point(&self) -> Option { self.prey.entry_point() } pub fn name(&self) -> String { self.prey.name() } pub fn version(&self) -> semver::Version { self.prey.version() } pub fn prey_lock(&mut self) -> &mut NestLock { &mut self.prey_lock } pub fn get_outdated>(&self, class_path: P) -> Vec { self.prey_lock .clone() .classes() .iter() .filter(|class| { class .is_updated(class_path.as_ref()) .is_ok_and(|b| b == false) }) .cloned() .collect() } pub fn write_lock(&self) -> crate::Result<()> { self.prey_lock.write(self.package_root.as_path()) } } // impl Hash for PackageHandler { // fn hash(&self, state: &mut H) { // self.prey.hash(state); // } // } /// Data struct #[derive(Debug, Clone, Deserialize, Serialize, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Package { pub name: String, pub version: Version, #[serde(skip_serializing_if = ">::is_none")] pub authors: Option>, #[serde(skip_serializing_if = ">::is_none")] pub repository: Option, #[serde(skip_serializing_if = ">::is_none")] pub license: Option, #[serde(skip_serializing_if = ">::is_none")] pub license_file: Option, pub entry_point: Option, } impl Package { pub fn new(name: S) -> Self { let mut package = Self::default(); package.name = name.to_string(); package } } impl Default for Package { fn default() -> Self { Package { name: String::from("Main"), version: Version::new(0, 1, 0), authors: None, repository: None, license: None, license_file: None, entry_point: None, } } }