use std::fmt; use { crate::{Package, Repository, Version}, serde::{Deserialize, Serialize}, std::{collections::HashMap, error::Error}, url::Url, }; #[derive(Clone, Debug)] pub struct Update { pub name: String, pub version: Version, pub release: u8, pub url: Url, } impl fmt::Display for Update { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}-{}_{}", self.name, self.version, self.release) } } impl Update { pub fn full_url(&self) -> Result { self.url.join(&format!("{}.tar.zstd", self)) } } #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Database { pub packages: HashMap, pub available: HashMap, } impl Database { pub fn update(&mut self) -> Result<(), Box> { unimplemented!(); } pub fn add_package(&mut self, package: Package) { let name = package.name.clone(); self.packages.insert(name, package); } pub fn remove_package(&mut self, name: &str) -> Option { self.packages.remove(name) } pub fn get_upgradable(&mut self) -> Result, Box> { self.update()?; let mut updates = HashMap::::new(); for local_package in self.packages.values() { let name = local_package.name.clone(); for repo in self.available.values() { // Check if the remote has a package by this name if let Some(remote_package) = repo.packages.get(&name) { // Check if the remote package is an update if remote_package.is_upgrade(&local_package) { // Check if we've already pulled in an update from another repo, // and if so compare versions if let Some(other_update) = updates.get(&name) { if remote_package.version > other_update.version { // The remote version is an update to the already // pulled in update, so swap it out let update = Update { name: name.clone(), version: remote_package.version.clone(), release: remote_package.release, url: repo.base_url.clone(), }; updates.insert(name.clone(), update); } } else { // First time we've seen this update, so insert it // into our hashmap let update = Update { name: name.clone(), version: remote_package.version.clone(), release: remote_package.release, url: repo.base_url.clone(), }; updates.insert(name.clone(), update); } } } } } Ok(updates) } }