1
Fork 0
mirror of https://github.com/RGBCube/dix synced 2025-07-27 11:47:46 +00:00

main, util: move get_version to util.rs

This commit is contained in:
Bloxx12 2025-05-08 15:27:34 +02:00
parent fb59cccda7
commit 9d0b52a535
No known key found for this signature in database
2 changed files with 69 additions and 60 deletions

View file

@ -3,11 +3,8 @@ mod util;
use clap::Parser; use clap::Parser;
use core::str; use core::str;
use log::{debug, error}; use log::{debug, error};
use regex::Regex;
use std::{ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
string::ToString,
sync::OnceLock,
thread, thread,
}; };
use yansi::Paint; use yansi::Paint;
@ -153,7 +150,7 @@ fn main() {
let mut post = HashMap::<&str, HashSet<&str>>::new(); let mut post = HashMap::<&str, HashSet<&str>>::new();
for p in &package_list_pre { for p in &package_list_pre {
match get_version(&**p) { match util::get_version(&**p) {
Ok((name, version)) => { Ok((name, version)) => {
pre.entry(name).or_default().insert(version); pre.entry(name).or_default().insert(version);
} }
@ -164,7 +161,7 @@ fn main() {
} }
for p in &package_list_post { for p in &package_list_post {
match get_version(&**p) { match util::get_version(&**p) {
Ok((name, version)) => { Ok((name, version)) => {
post.entry(name).or_default().insert(version); post.entry(name).or_default().insert(version);
} }
@ -247,58 +244,3 @@ fn main() {
} }
} }
} }
// Returns a reference to the compiled regex pattern.
// The regex is compiled only once.
fn store_path_regex() -> &'static Regex {
static REGEX: OnceLock<Regex> = OnceLock::new();
REGEX.get_or_init(|| {
Regex::new(r"(.+?)(-([0-9].*?))?$")
.expect("Failed to compile regex pattern for nix store paths")
})
}
/// Parses a nix store path to extract the packages name and version
///
/// This function first drops the inputs first 44 chars, since that is exactly the length of the /nix/store/... prefix. Then it matches that against our store path regex.
///
/// # Returns
///
/// * Result<(&'a str, &'a str)> - The Package's name and version, or an error if
/// one or both cannot be retrieved.
fn get_version<'a>(pack: impl Into<&'a str>) -> Result<(&'a str, &'a str)> {
let path = pack.into();
// We can strip the path since it _always_ follows the format
// /nix/store/<...>-<program_name>-......
// This part is exactly 44 chars long, so we just remove it.
let stripped_path = &path[44..];
debug!("Stripped path: {stripped_path}");
// Match the regex against the input
if let Some(cap) = store_path_regex().captures(stripped_path) {
// Handle potential missing captures safely
let name = cap.get(1).map_or("", |m| m.as_str());
let mut version = cap.get(2).map_or("<none>", |m| m.as_str());
if version.starts_with('-') {
version = &version[1..];
}
if name.is_empty() {
return Err(AppError::ParseError {
message: format!("Failed to extract name from path: {path}"),
context: "get_version".to_string(),
source: None,
});
}
return Ok((name, version));
}
Err(AppError::ParseError {
message: format!("Path does not match expected nix store format: {path}"),
context: "get_version".to_string(),
source: None,
})
}

View file

@ -1,5 +1,18 @@
use crate::error::AppError;
use log::{debug, error};
use regex::Regex;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::{
collections::{HashMap, HashSet},
string::ToString,
sync::OnceLock,
thread,
};
// Use type alias for Result with our custom error type
type Result<T> = std::result::Result<T, AppError>;
#[derive(Eq, PartialEq, Debug)] #[derive(Eq, PartialEq, Debug)]
enum VersionComponent { enum VersionComponent {
Number(u64), Number(u64),
@ -114,3 +127,57 @@ mod test {
); );
} }
} }
/// Parses a nix store path to extract the packages name and version
///
/// This function first drops the inputs first 44 chars, since that is exactly the length of the /nix/store/... prefix. Then it matches that against our store path regex.
///
/// # Returns
///
/// * Result<(&'a str, &'a str)> - The Package's name and version, or an error if
/// one or both cannot be retrieved.
pub fn get_version<'a>(pack: impl Into<&'a str>) -> Result<(&'a str, &'a str)> {
let path = pack.into();
// We can strip the path since it _always_ follows the format
// /nix/store/<...>-<program_name>-......
// This part is exactly 44 chars long, so we just remove it.
let stripped_path = &path[44..];
debug!("Stripped path: {stripped_path}");
// Match the regex against the input
if let Some(cap) = store_path_regex().captures(stripped_path) {
// Handle potential missing captures safely
let name = cap.get(1).map_or("", |m| m.as_str());
let mut version = cap.get(2).map_or("<none>", |m| m.as_str());
if version.starts_with('-') {
version = &version[1..];
}
if name.is_empty() {
return Err(AppError::ParseError {
message: format!("Failed to extract name from path: {path}"),
context: "get_version".to_string(),
source: None,
});
}
return Ok((name, version));
}
Err(AppError::ParseError {
message: format!("Path does not match expected nix store format: {path}"),
context: "get_version".to_string(),
source: None,
})
}
// Returns a reference to the compiled regex pattern.
// The regex is compiled only once.
fn store_path_regex() -> &'static Regex {
static REGEX: OnceLock<Regex> = OnceLock::new();
REGEX.get_or_init(|| {
Regex::new(r"(.+?)(-([0-9].*?))?$")
.expect("Failed to compile regex pattern for nix store paths")
})
}