92 lines
3.2 KiB
Rust
92 lines
3.2 KiB
Rust
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<Url, url::ParseError> {
|
|
self.url.join(&format!("{}.tar.zstd", self))
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
pub struct Database {
|
|
pub packages: HashMap<String, Package>,
|
|
pub available: HashMap<String, Repository>,
|
|
}
|
|
|
|
impl Database {
|
|
pub fn update(&mut self) -> Result<(), Box<dyn Error>> {
|
|
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<Package> {
|
|
self.packages.remove(name)
|
|
}
|
|
|
|
pub fn get_upgradable(&mut self) -> Result<HashMap<String, Update>, Box<dyn Error>> {
|
|
self.update()?;
|
|
let mut updates = HashMap::<String, Update>::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)
|
|
}
|
|
}
|