diff --git a/src/storage/file_id.rs b/src/storage/file_id.rs index a82f889d..03e507e0 100644 --- a/src/storage/file_id.rs +++ b/src/storage/file_id.rs @@ -6,10 +6,15 @@ use std::path::{Path, PathBuf}; use std::convert::From; use std::convert::Into; +use regex::Regex; + #[derive(Debug)] #[derive(Clone)] +#[derive(PartialEq)] +#[derive(Eq)] // #[derive(Display)] pub enum FileIDType { + NONE, UUID, } @@ -32,6 +37,10 @@ impl FileID { self.id.is_some() } + pub fn get_type(&self) -> FileIDType { + self.id_type.clone() + } + } impl Debug for FileID { @@ -71,15 +80,52 @@ impl Into for FileID { impl From for FileID { fn from(s: String) -> FileID { - unimplemented!() + FileID::from(&s) } } impl<'a> From<&'a String> for FileID { - fn from(s: &'a String) -> FileID { - unimplemented!() + fn from(string: &'a String) -> FileID { + + let regex = Regex::new(r"([:alnum:]*)-([:upper:]*)-([A-Za-z0-9-_]*)\.(.*)").unwrap(); + let s = string.split("/").last().unwrap_or(""); + + debug!("Regex build: {:?}", regex); + debug!("Matching string: '{}'", s); + regex.captures(s).and_then(|capts| { + // first one is the whole string, index 1-N are the matches. + if capts.len() != 5 { + debug!("Matches, but not expected number of groups"); + return None; + } + debug!("Matches: {}", capts.len()); + + let modname = capts.at(1).unwrap(); + let hashname = capts.at(2).unwrap(); + let mut hash = capts.at(3).unwrap(); + + debug!("Destructure FilePath to ID:"); + debug!(" FilePath: {:?}", s); + debug!(" Module Name: {:?}", modname); + debug!(" Hash Name: {:?}", hashname); + debug!(" Hash: {:?}", hash); + + let idtype = select_id_type_from_str(hashname); + match idtype { + FileIDType::NONE => hash = "INVALID", + _ => {}, + } + + Some(FileID::new(idtype, String::from(hash))) + }).unwrap_or({ + debug!("Did not match"); + FileID { + id_type: FileIDType::NONE, + id: None, + } + }) } } @@ -146,5 +192,61 @@ impl<'a> Display for FileIDError { } +fn select_id_type_from_str(s: &str) -> FileIDType { + match s { + "UUID" => FileIDType::UUID, + _ => FileIDType::NONE, + } +} + pub type FileIDResult = Result; +#[cfg(test)] +mod test { + + use super::{FileID, FileIDType}; + + #[test] + fn file_id_from_string() { + setup_logger(); + + let s1 = String::from("/home/user/testmodule-UUID-some-id.imag"); + let s2 = String::from("/home/user/testmodule-UUID-some-id.extension.imag"); + let s3 = String::from("/home/user/testmodule-NOHASH-some-id.imag"); + + let id1 = FileID::from(s1); + let id2 = FileID::from(s2); + let id3 = FileID::from(s3); + + println!("Id 1 : {:?}", id1); + println!("Id 2 : {:?}", id2); + println!("Id 3 : {:?}", id3); + + assert_eq!(FileIDType::UUID, id1.get_type()); + assert_eq!(FileIDType::UUID, id2.get_type()); + assert_eq!(FileIDType::NONE, id3.get_type()); + + let f1 : String = id1.into(); + let f2 : String = id2.into(); + let f3 : String = id3.into(); + + assert_eq!(String::from("some-id"), f1); + assert_eq!(String::from("some-id"), f2); + assert_eq!(String::from("INVALID"), f3); + } + + fn setup_logger() { + extern crate log; + use log::{LogLevelFilter, set_logger}; + use runtime::ImagLogger; + + log::set_logger(|max_log_lvl| { + let lvl = LogLevelFilter::Debug; + max_log_lvl.set(lvl); + Box::new(ImagLogger::new(lvl.to_log_level().unwrap())) + }); + debug!("Init logger for test"); + } + +} +