diff --git a/Cargo.lock b/Cargo.lock index 35a1a76..ada2d87 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + [[package]] name = "glam" version = "0.25.0" @@ -18,6 +27,41 @@ dependencies = [ "syn", ] +[[package]] +name = "lazy-regex" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d12be4595afdf58bd19e4a9f4e24187da2a66700786ff660a418e9059937a4c" +dependencies = [ + "lazy-regex-proc_macros", + "once_cell", + "regex", +] + +[[package]] +name = "lazy-regex-proc_macros" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44bcd58e6c97a7fcbaffcdc95728b393b8d98933bfadad49ed4097845b57ef0b" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn", +] + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + [[package]] name = "proc-macro2" version = "1.0.78" @@ -36,6 +80,35 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + [[package]] name = "strafesnet_common" version = "0.1.0" @@ -49,6 +122,7 @@ dependencies = [ name = "strafesnet_texture_loader" version = "0.1.0" dependencies = [ + "lazy-regex", "strafesnet_common", ] diff --git a/Cargo.toml b/Cargo.toml index a606919..3740f77 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,9 +6,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -legacy = [] +legacy = ["dep:lazy-regex"] #roblox = [] #source = [] [dependencies] +lazy-regex = { version = "3.1.0", optional = true } strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "43f771fb0f19a3751875df1f25bf9cb5874f75f4" } diff --git a/src/legacy.rs b/src/legacy.rs index 56ee92a..20f80b1 100644 --- a/src/legacy.rs +++ b/src/legacy.rs @@ -3,8 +3,33 @@ use std::collections::HashMap; use crate::texture_loader::{Texture,Textures}; use strafesnet_common::model::TextureId; +#[derive(Hash,Eq,PartialEq)] +struct RobloxAssetId(u64); +#[derive(Debug)] +pub struct RobloxAssetIdParseErr(String); +impl std::str::FromStr for RobloxAssetId{ + type Err=RobloxAssetIdParseErr; + fn from_str(s:&str)->Result{ + let regman=lazy_regex::regex!(r"(\d+)$"); + if let Some(captures)=regman.captures(s){ + if captures.len()==2{//captures[0] is all captures concatenated, and then each individual capture + if let Ok(id)=captures[0].parse::(){ + return Ok(Self(id)); + } + } + } + Err(RobloxAssetIdParseErr(s.to_owned())) + } +} +impl std::fmt::Display for RobloxAssetIdParseErr{ + fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ + write!(f,"{self:?}") + } +} +impl std::error::Error for RobloxAssetIdParseErr{} + pub struct TextureLoader{ - texture_names:HashMap, + texture_names:HashMap, } impl TextureLoader{ pub fn new()->Self{ @@ -15,15 +40,16 @@ impl TextureLoader{ } impl crate::texture_loader::TextureLoaderTrait for TextureLoader{ - type Error=std::io::Error; - fn acquire_id(&mut self,name:&str)->TextureId{ + type AcquireError=RobloxAssetIdParseErr; + type LoadError=std::io::Error; + fn acquire_id(&mut self,name:&str)->Result{ let texture_id=TextureId::new(self.texture_names.len() as u32); - *self.texture_names.entry(name.to_owned()).or_insert(texture_id) + Ok(*self.texture_names.entry(name.parse::()?).or_insert(texture_id)) } - fn load(&self)->Result{ + fn load(&self)->Result{ let mut texture_data=vec![Vec::::new();self.texture_names.len()]; for (texture_name,texture_id) in &self.texture_names{ - let path=std::path::PathBuf::from(format!("textures/{}.dds",texture_name.as_str())); + let path=std::path::PathBuf::from(format!("textures/{}.dds",texture_name.0)); if let Ok(mut file)=std::fs::File::open(path){ //TODO: parallel file.read_to_end(texture_data.get_mut(texture_id.get() as usize).unwrap())?; diff --git a/src/texture_loader.rs b/src/texture_loader.rs index 90f1742..aa9c9b6 100644 --- a/src/texture_loader.rs +++ b/src/texture_loader.rs @@ -29,42 +29,67 @@ impl Textures{ } pub trait TextureLoaderTrait{ - type Error; + type AcquireError; + type LoadError; //write down the name of a texture to be fetched later, return a unique id for that texture - fn acquire_id(&mut self,name:&str)->TextureId; - fn load(&self)->Result; + fn acquire_id(&mut self,name:&str)->Result; + fn load(&self)->Result; } -pub enum TextureLoaderError{ +#[derive(Debug)] +pub enum TextureLoaderAcquireError{ #[cfg(feature="legacy")] - Legacy(::Error), + Legacy(::AcquireError), #[cfg(feature="roblox")] - Roblox(::Error), + Roblox(::AcquireError), #[cfg(feature="source")] - Source(::Error), + Source(::AcquireError), } +impl std::fmt::Display for TextureLoaderAcquireError{ + fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ + write!(f,"{self:?}") + } +} +impl std::error::Error for TextureLoaderAcquireError{} + +#[derive(Debug)] +pub enum TextureLoaderLoadError{ + #[cfg(feature="legacy")] + Legacy(::LoadError), + #[cfg(feature="roblox")] + Roblox(::LoadError), + #[cfg(feature="source")] + Source(::LoadError), +} +impl std::fmt::Display for TextureLoaderLoadError{ + fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ + write!(f,"{self:?}") + } +} +impl std::error::Error for TextureLoaderLoadError{} impl TextureLoaderTrait for TextureLoader{ - type Error=TextureLoaderError; - fn acquire_id(&mut self,name:&str)->TextureId{ + type AcquireError=TextureLoaderAcquireError; + type LoadError=TextureLoaderLoadError; + fn acquire_id(&mut self,name:&str)->Result{ match self{ #[cfg(feature="legacy")] - TextureLoader::Legacy(loader)=>loader.acquire_id(name), + TextureLoader::Legacy(loader)=>loader.acquire_id(name).map_err(TextureLoaderAcquireError::Legacy), #[cfg(feature="roblox")] - TextureLoader::Roblox(loader)=>loader.acquire_id(name), + TextureLoader::Roblox(loader)=>loader.acquire_id(name).map_err(TextureLoaderAcquireError::Roblox), #[cfg(feature="source")] - TextureLoader::Source(loader)=>loader.acquire_id(name), + TextureLoader::Source(loader)=>loader.acquire_id(name).map_err(TextureLoaderAcquireError::Source), _=>unreachable!(), } } - fn load(&self)->Result{ + fn load(&self)->Result{ match self{ #[cfg(feature="legacy")] - TextureLoader::Legacy(loader)=>loader.load().map_err(TextureLoaderError::Legacy), + TextureLoader::Legacy(loader)=>loader.load().map_err(TextureLoaderLoadError::Legacy), #[cfg(feature="roblox")] - TextureLoader::Roblox(loader)=>loader.load().map_err(TextureLoaderError::Roblox), + TextureLoader::Roblox(loader)=>loader.load().map_err(TextureLoaderLoadError::Roblox), #[cfg(feature="source")] - TextureLoader::Source(loader)=>loader.load().map_err(TextureLoaderError::Source), + TextureLoader::Source(loader)=>loader.load().map_err(TextureLoaderLoadError::Source), _=>unreachable!(), } }