diff --git a/.github/workflows/rust.yml b/.github/workflows/ci.yml similarity index 80% rename from .github/workflows/rust.yml rename to .github/workflows/ci.yml index 75954ee..e5c3bd6 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/ci.yml @@ -1,10 +1,10 @@ -name: Rust +name: Rust CI on: push: - branches: [ master ] + branches: [ master, main ] pull_request: - branches: [ master ] + branches: [ master, main ] env: CARGO_TERM_COLOR: always @@ -16,7 +16,7 @@ jobs: strategy: matrix: - feature-set: ['', '--no-default-features --features alloc_fills'] + feature-set: ['', '--no-default-features'] steps: - uses: actions/checkout@v3 diff --git a/Cargo.lock b/Cargo.lock index f5265ec..1abfbd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "adler" @@ -8,24 +8,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ahash" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "allocator-api2" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" - [[package]] name = "benchmarking" version = "0.4.12" @@ -72,16 +54,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" -dependencies = [ - "ahash", - "allocator-api2", -] - [[package]] name = "miniz_oxide" version = "0.7.2" @@ -92,12 +64,6 @@ dependencies = [ "simd-adler32", ] -[[package]] -name = "once_cell" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" - [[package]] name = "png" version = "0.17.11" @@ -111,78 +77,16 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "proc-macro2" -version = "1.0.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" -dependencies = [ - "unicode-ident", -] - [[package]] name = "quake-util" version = "0.3.2" dependencies = [ "benchmarking", - "hashbrown", "png", ] -[[package]] -name = "quote" -version = "1.0.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" -dependencies = [ - "proc-macro2", -] - [[package]] name = "simd-adler32" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - -[[package]] -name = "syn" -version = "2.0.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "zerocopy" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/Cargo.toml b/Cargo.toml index dc91446..58b2420 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,12 +10,8 @@ repository = "https://github.com/4LT/quake-util" [features] default = ["std"] -alloc_fills = ["hashbrown"] std = [] -[dependencies] -hashbrown = { version = "^0.14", optional = true } - [dev-dependencies] benchmarking = "^0.4" png = "^0.17" diff --git a/examples/bspstats.rs b/examples/bspstats.rs index f916275..00ede99 100644 --- a/examples/bspstats.rs +++ b/examples/bspstats.rs @@ -35,11 +35,28 @@ fn main() { let mut map_name = String::from(""); for edict in qmap.entities.into_iter().map(|e| e.edict) { - let map_name_cstr = if edict.get(&CString::new("classname").unwrap()) + let map_name_cstr = if edict + .iter() + .flat_map(|(key, value)| { + if key == &CString::new("classname").unwrap() { + Some(value) + } else { + None + } + }) + .next() == Some(&CString::new("worldspawn").unwrap()) { edict - .get(&CString::new("message").unwrap()) + .iter() + .flat_map(|(key, value)| { + if key == &CString::new("message").unwrap() { + Some(value) + } else { + None + } + }) + .next() .map(Clone::clone) } else { None diff --git a/src/bsp/parser_test.rs b/src/bsp/parser_test.rs index b62b5d5..7af01db 100644 --- a/src/bsp/parser_test.rs +++ b/src/bsp/parser_test.rs @@ -45,17 +45,21 @@ fn parse_good_bsp() { let qmap = parser.parse_entities().unwrap(); - assert_eq!( - qmap.entities[0] - .edict - .get(&CString::new("classname").unwrap()), - Some(&CString::new("func_door").unwrap()) - ); - - assert_eq!( - qmap.entities[0].edict.get(&CString::new("model").unwrap()), - Some(&CString::new("*37").unwrap()) - ); + let (_, classname) = qmap.entities[0] + .edict + .iter() + .find(|(key, _)| key == &CString::new("classname").unwrap()) + .unwrap(); + + assert_eq!(classname, &CString::new("func_door").unwrap()); + + let (_, model) = qmap.entities[0] + .edict + .iter() + .find(|(key, _)| key == &CString::new("model").unwrap()) + .unwrap(); + + assert_eq!(model, &CString::new("*37").unwrap()); } #[test] diff --git a/src/lib.rs b/src/lib.rs index c633c6b..65f8daf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,5 @@ #![no_std] -#[cfg(all(not(feature = "std"), not(feature = "alloc_fills")))] -compile_error!("Must use feature 'std' or 'alloc_fills'"); - -#[cfg(all(feature = "std", feature = "alloc_fills"))] -compile_error!("Features 'std' and 'alloc_fills' are mutually exclusive"); - #[cfg(feature = "std")] #[macro_use] extern crate std; diff --git a/src/lump/parse.rs b/src/lump/parse.rs index fab3a20..68171f0 100644 --- a/src/lump/parse.rs +++ b/src/lump/parse.rs @@ -46,7 +46,9 @@ pub fn parse_mip_texture( pub fn parse_palette(reader: &mut impl Read) -> BinParseResult> { let mut bytes = [0u8; size_of::()]; reader.read_exact(&mut bytes[..])?; - Ok(Box::from(unsafe { transmute::<_, Palette>(bytes) })) + Ok(Box::from(unsafe { + transmute::<[u8; size_of::()], Palette>(bytes) + })) } /// Attempt to parse a 2D image diff --git a/src/lump/repr.rs b/src/lump/repr.rs index f3da456..6b395e4 100644 --- a/src/lump/repr.rs +++ b/src/lump/repr.rs @@ -48,7 +48,7 @@ impl Image { pub fn from_pixels(width: u32, pixels: Box<[u8]>) -> Self { let pixel_ct: u32 = pixels.len().try_into().expect("Too many pixels"); - if pixels.len() == 0 { + if pixels.is_empty() { return Image { width: 0, height: 0, diff --git a/src/qmap/mod.rs b/src/qmap/mod.rs index be40da3..10f79dc 100644 --- a/src/qmap/mod.rs +++ b/src/qmap/mod.rs @@ -28,15 +28,15 @@ //! //! let mut soldier = Entity::new(); //! -//! soldier.edict.insert( +//! soldier.edict.push(( //! CString::new("classname").unwrap(), //! CString::new("monster_army").unwrap(), -//! ); +//! )); //! -//! soldier.edict.insert( +//! soldier.edict.push(( //! CString::new("origin").unwrap(), //! CString::new("128 -256 24").unwrap(), -//! ); +//! )); //! //! map.entities.push(soldier); //! diff --git a/src/qmap/parser.rs b/src/qmap/parser.rs index 03efb6e..426d1bf 100644 --- a/src/qmap/parser.rs +++ b/src/qmap/parser.rs @@ -73,7 +73,7 @@ fn parse_edict( expect_quoted(&maybe_value)?; let value = strip_quoted(&maybe_value.unwrap().text).to_vec().into(); - edict.insert(key, value); + edict.push((key, value)); } else { break; } @@ -112,7 +112,7 @@ fn parse_brush( } } - expect_byte_or(&tokens.extract()?, b'}', &[b'('])?; + expect_byte_or(&tokens.extract()?, b'}', b"(")?; Ok(surfaces) } diff --git a/src/qmap/parser_test.rs b/src/qmap/parser_test.rs index 852d8f1..90f9eaf 100644 --- a/src/qmap/parser_test.rs +++ b/src/qmap/parser_test.rs @@ -61,9 +61,9 @@ fn parse_point_entity_with_key_value() { assert_eq!(edict.len(), 1); assert_eq!( edict.iter().next().unwrap(), - ( - &CString::new("classname").unwrap(), - &CString::new("light").unwrap() + &( + CString::new("classname").unwrap(), + CString::new("light").unwrap() ) ); } diff --git a/src/qmap/repr.rs b/src/qmap/repr.rs index 9fa98d0..58853e2 100644 --- a/src/qmap/repr.rs +++ b/src/qmap/repr.rs @@ -1,22 +1,14 @@ #[cfg(feature = "std")] extern crate std; -#[cfg(feature = "alloc_fills")] extern crate alloc; #[cfg(feature = "std")] -use std::{ - collections::HashMap, - ffi::{CStr, CString}, - io, - string::String, - vec::Vec, -}; +use std::io; -#[cfg(feature = "alloc_fills")] use { alloc::ffi::CString, alloc::format, alloc::string::String, alloc::vec::Vec, - core::ffi::CStr, hashbrown::HashMap, + core::ffi::CStr, }; #[cfg(feature = "std")] @@ -69,6 +61,12 @@ impl QuakeMap { } } +impl Default for QuakeMap { + fn default() -> Self { + Self::new() + } +} + impl CheckWritable for QuakeMap { fn check_writable(&self) -> ValidationResult { for ent in &self.entities { @@ -149,7 +147,7 @@ impl CheckWritable for Entity { } /// Entity dictionary -pub type Edict = HashMap; +pub type Edict = Vec<(CString, CString)>; impl CheckWritable for Edict { fn check_writable(&self) -> ValidationResult { diff --git a/src/qmap/repr_test.rs b/src/qmap/repr_test.rs index 53d9242..e03ad02 100644 --- a/src/qmap/repr_test.rs +++ b/src/qmap/repr_test.rs @@ -1,24 +1,23 @@ #[cfg(feature = "std")] extern crate std; +extern crate alloc; + use crate::qmap; use qmap::repr::*; use qmap::{CheckWritable, ValidationResult}; #[cfg(feature = "std")] -use { - crate::WriteError, - std::ffi::{CStr, CString}, - std::str, - std::string::String, - std::vec::Vec, -}; +use crate::WriteError; -#[cfg(feature = "alloc_fills")] -use { - alloc::ffi::CString, alloc::format, alloc::str, alloc::vec, core::ffi::CStr, -}; +use {alloc::ffi::CString, alloc::str, core::ffi::CStr}; + +#[cfg(feature = "std")] +use {alloc::string::String, alloc::vec::Vec}; + +#[cfg(not(feature = "std"))] +use alloc::{format, vec}; const GOOD_AXES: [Vec3; 2] = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]; @@ -62,16 +61,16 @@ fn panic_expected_error() { fn simple_edict() -> Edict { let mut edict = Edict::new(); - edict.insert( + edict.push(( CString::new("classname").unwrap(), CString::new("worldspawn").unwrap(), - ); + )); edict } fn bad_edict_key() -> Edict { let mut edict = Edict::new(); - edict.insert(CString::new("\n").unwrap(), CString::new("oops").unwrap()); + edict.push((CString::new("\n").unwrap(), CString::new("oops").unwrap())); edict } @@ -174,7 +173,7 @@ fn check_bad_entities() { let key = CString::new(key).unwrap(); let value = CString::new(value).unwrap(); let mut edict = Edict::new(); - edict.insert(key, value); + edict.push((key, value)); let ent = Entity { edict, brushes: vec![],