From f0f3216e0182f58179b272efe1ae9251c08db030 Mon Sep 17 00:00:00 2001 From: Steppy Date: Thu, 12 Dec 2024 19:45:45 +0100 Subject: [PATCH] Add file module --- src/file.rs | 137 +++++++++++++++++++++ src/main.rs | 1 + test-ressources/files/TestPlugin-1.0.0.jar | 0 test-ressources/files/bin-7.3 | 0 test-ressources/files/test | 0 test-ressources/files/unversioned.jar | 0 6 files changed, 138 insertions(+) create mode 100644 src/file.rs create mode 100644 test-ressources/files/TestPlugin-1.0.0.jar create mode 100644 test-ressources/files/bin-7.3 create mode 100644 test-ressources/files/test create mode 100644 test-ressources/files/unversioned.jar diff --git a/src/file.rs b/src/file.rs new file mode 100644 index 0000000..fedf7b9 --- /dev/null +++ b/src/file.rs @@ -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, + pub ending: Option, +} + +impl TryFrom for FileInfo { + type Error = FileInfoError; + + fn try_from(file: PathBuf) -> Result { + 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::().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") + ); + } +} diff --git a/src/main.rs b/src/main.rs index a28a6cf..eb8458f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod server; +mod file; use clap::{Parser, Subcommand, ValueEnum}; use lazy_regex::{lazy_regex, Lazy, Regex}; diff --git a/test-ressources/files/TestPlugin-1.0.0.jar b/test-ressources/files/TestPlugin-1.0.0.jar new file mode 100644 index 0000000..e69de29 diff --git a/test-ressources/files/bin-7.3 b/test-ressources/files/bin-7.3 new file mode 100644 index 0000000..e69de29 diff --git a/test-ressources/files/test b/test-ressources/files/test new file mode 100644 index 0000000..e69de29 diff --git a/test-ressources/files/unversioned.jar b/test-ressources/files/unversioned.jar new file mode 100644 index 0000000..e69de29