Add file module

This commit is contained in:
Leonard Steppy 2024-12-12 19:45:45 +01:00
parent 44a83fe03b
commit f0f3216e01
6 changed files with 138 additions and 0 deletions

137
src/file.rs Normal file
View File

@ -0,0 +1,137 @@
use std::error::Error;
use std::fmt::{Display, Formatter};
use std::path::PathBuf;
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct FileInfo {
pub name: String,
pub version: Option<String>,
pub ending: Option<String>,
}
impl TryFrom<PathBuf> for FileInfo {
type Error = FileInfoError;
fn try_from(file: PathBuf) -> Result<Self, Self::Error> {
if !file.is_file() {
return Err(FileInfoError::NotAFile);
}
let file_name = file.file_name().ok_or(FileInfoError::NotAFile)?;
let file_name = file_name
.to_str()
.ok_or(FileInfoError::InvalidCharactersInFileName)?;
let (file_name_without_version, ending) =
match file_name.rsplit_once('.').filter(|(_, ending)| {
ending.parse::<u32>().is_err() //there are usually no file extensions which are just a number, but rather versions
}) {
Some((name, ending)) => (name, Some(ending.to_string())),
None => (file_name, None),
};
let (name, version) = match file_name_without_version.split_once('-') {
Some((name, version)) => (name, Some(version.to_string())),
None => (file_name_without_version, None),
};
Ok(Self {
name: name.to_string(),
version,
ending,
})
}
}
impl Display for FileInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}{}{}",
self.name,
self
.version
.as_ref()
.map(|v| format!("-{v}"))
.unwrap_or_default(),
self
.ending
.as_ref()
.map(|e| format!(".{e}"))
.unwrap_or_default()
)
}
}
#[derive(Debug)]
pub enum FileInfoError {
NotAFile,
InvalidCharactersInFileName,
}
impl Display for FileInfoError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
FileInfoError::NotAFile => write!(f, "Path doesn't point to a file"),
FileInfoError::InvalidCharactersInFileName => write!(f, "Invalid characters in file name"),
}
}
}
impl Error for FileInfoError {}
#[cfg(test)]
mod test_file_info {
use crate::file::FileInfo;
use std::path::PathBuf;
#[test]
fn test_from_plugin() {
assert_eq!(
FileInfo {
name: "TestPlugin".to_string(),
version: Some("1.0.0".to_string()),
ending: Some("jar".to_string()),
},
FileInfo::try_from(PathBuf::from("test-ressources/files/TestPlugin-1.0.0.jar"))
.expect("valid file")
);
}
#[test]
fn test_from_unversioned() {
assert_eq!(
FileInfo {
name: "unversioned".to_string(),
version: None,
ending: Some("jar".to_string()),
},
FileInfo::try_from(PathBuf::from("test-ressources/files/unversioned.jar"))
.expect("valid file")
);
}
#[test]
fn test_from_versioned_bin() {
assert_eq!(
FileInfo {
name: "bin".to_string(),
version: Some("7.3".to_string()),
ending: None,
},
FileInfo::try_from(PathBuf::from("test-ressources/files/bin-7.3")).expect("valid file")
);
}
#[test]
fn test_from_unversioned_bin() {
assert_eq!(
FileInfo {
name: "test".to_string(),
version: None,
ending: None,
},
FileInfo::try_from(PathBuf::from("test-ressources/files/test")).expect("valid file")
);
}
}

View File

@ -1,4 +1,5 @@
mod server;
mod file;
use clap::{Parser, Subcommand, ValueEnum};
use lazy_regex::{lazy_regex, Lazy, Regex};

View File

View File

View File