use std::collections::HashSet; use std::fs::{File, OpenOptions}; use std::io::{Read, Write}; use std::path::{Path, PathBuf}; use fs::expand_files; use serde::{Deserialize, Serialize}; use crate::class::Class; use crate::meta::Meta; use crate::package::Package; pub const F_PREY_TOML: &str = "Prey.toml"; pub const F_PREY_LOCK: &str = "Prey.lock"; /// Data struct #[derive(Debug, Clone, Deserialize, Serialize, Hash, PartialEq, Eq)] pub struct Prey { package: Package, meta: Meta, } impl Prey { pub fn new(name: S) -> Self { Self { package: Package { entry_point: PathBuf::from(""), }, meta: Meta::new(name), } } pub fn with_entry_point>(&mut self, entry_point: P) -> &mut Self { self.package.entry_point = entry_point.as_ref().to_path_buf(); self } pub fn entry_point(&self) -> PathBuf { self.package.entry_point.clone() } pub fn name(&self) -> String { self.meta.name.clone() } pub fn version(&self) -> semver::Version { self.meta.version.clone() } } impl TryFrom for Prey { type Error = crate::Error; fn try_from(value: PathBuf) -> Result { let f = OpenOptions::new().read(true).open(value)?; Self::try_from(f) } } impl TryFrom for Prey { type Error = crate::Error; fn try_from(mut value: File) -> Result { let mut buf = String::new(); value.read_to_string(&mut buf)?; Ok(toml::from_str(buf.as_str())?) } } /// Data struct #[derive(Debug, Clone, Default, Deserialize, Serialize, PartialEq, Eq)] pub struct PreyLock { classes: HashSet, } impl PreyLock { pub fn new>(package_root: P, package_src_root: P) -> crate::Result { Ok(Self::from_paths( expand_files(package_root)?, package_src_root, )) } pub fn from_paths>(paths: Vec, package_src_root: P) -> Self { let mut lock = Self::default(); lock.classes = paths .iter() .filter_map(|f| { let dep = Class::new(package_src_root.as_ref().to_path_buf(), f.to_owned()); if dep.is_ok() { Some(dep.unwrap()) } else { None } }) .collect(); lock } pub fn write>(&self, package_root: P) -> crate::Result<()> { let mut package_root = package_root.as_ref().to_path_buf(); if package_root.is_dir() { package_root = package_root.join(F_PREY_LOCK); } Ok(OpenOptions::new() .write(true) .create(true) .open(package_root)? .write_all(toml::to_string_pretty(&self)?.as_bytes())?) } pub fn with_class(&mut self, class: Class) -> &mut Self { self.classes.insert(class); self } pub fn classes(&mut self) -> &mut HashSet { &mut self.classes } } /// Load the PreyLock from Prey.lock file. impl TryFrom for PreyLock { type Error = crate::Error; fn try_from(value: PathBuf) -> Result { let f = OpenOptions::new().read(true).open(value)?; Self::try_from(f) } } impl TryFrom for PreyLock { type Error = crate::Error; fn try_from(mut value: File) -> Result { let mut buf = String::new(); value.read_to_string(&mut buf)?; Ok(toml::from_str(buf.as_str())?) } }