diff --git a/crates/league-toolkit/src/core/animation/mod.rs b/crates/league-toolkit/src/core/animation/mod.rs index 4611bce1..a355ae9b 100644 --- a/crates/league-toolkit/src/core/animation/mod.rs +++ b/crates/league-toolkit/src/core/animation/mod.rs @@ -1,3 +1,4 @@ +//! Skeletons (rigs, joints) & animations pub mod joint; pub use joint::*; diff --git a/crates/league-toolkit/src/core/mem/mod.rs b/crates/league-toolkit/src/core/mem/mod.rs index 397997fa..b8702ed6 100644 --- a/crates/league-toolkit/src/core/mem/mod.rs +++ b/crates/league-toolkit/src/core/mem/mod.rs @@ -1,3 +1,4 @@ +//! League memory primitives (index / vertex buffers, etc) pub mod index_buffer; pub use index_buffer::*; pub mod vertex_buffer; diff --git a/crates/league-toolkit/src/core/mesh/mod.rs b/crates/league-toolkit/src/core/mesh/mod.rs index d2cdc11a..fc1aec13 100644 --- a/crates/league-toolkit/src/core/mesh/mod.rs +++ b/crates/league-toolkit/src/core/mesh/mod.rs @@ -1,3 +1,4 @@ +//! Skinned & static meshes mod r#static; use error::ParseError; diff --git a/crates/league-toolkit/src/core/meta/bin_tree/mod.rs b/crates/league-toolkit/src/core/meta/bin_tree/mod.rs index af0e8e7a..e3810d4f 100644 --- a/crates/league-toolkit/src/core/meta/bin_tree/mod.rs +++ b/crates/league-toolkit/src/core/meta/bin_tree/mod.rs @@ -1,14 +1,14 @@ use std::collections::HashMap; mod object; -use super::error::ParseError; pub use object::*; -pub mod read; -pub mod write; +mod read; +mod write; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, PartialEq)] +/// The top level tree of a bin file pub struct BinTree { pub is_override: bool, pub version: u32, diff --git a/crates/league-toolkit/src/core/meta/bin_tree/object.rs b/crates/league-toolkit/src/core/meta/bin_tree/object.rs index 91707500..abf1911b 100644 --- a/crates/league-toolkit/src/core/meta/bin_tree/object.rs +++ b/crates/league-toolkit/src/core/meta/bin_tree/object.rs @@ -2,11 +2,12 @@ use std::{collections::HashMap, io}; use io_ext::{measure, window}; -use super::{super::BinProperty, ParseError}; +use super::super::{BinProperty, Error}; use byteorder::{ReadBytesExt, WriteBytesExt, LE}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, PartialEq)] +/// A node in the bin tree pub struct BinTreeObject { pub path_hash: u32, pub class_hash: u32, @@ -25,7 +26,7 @@ impl BinTreeObject { reader: &mut R, class_hash: u32, legacy: bool, - ) -> Result { + ) -> Result { let size = reader.read_u32::()?; let (real_size, value) = measure(reader, |reader| { let path_hash = reader.read_u32::()?; @@ -37,7 +38,7 @@ impl BinTreeObject { properties.insert(prop.name_hash, prop); } - Ok::<_, ParseError>(Self { + Ok::<_, Error>(Self { path_hash, class_hash, properties, @@ -45,7 +46,7 @@ impl BinTreeObject { })?; if size as u64 != real_size { - return Err(ParseError::InvalidSize(size as _, real_size)); + return Err(Error::InvalidSize(size as _, real_size)); } Ok(value) } diff --git a/crates/league-toolkit/src/core/meta/bin_tree/read.rs b/crates/league-toolkit/src/core/meta/bin_tree/read.rs index 9a04e66b..a7cc08f0 100644 --- a/crates/league-toolkit/src/core/meta/bin_tree/read.rs +++ b/crates/league-toolkit/src/core/meta/bin_tree/read.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, io}; -use crate::core::meta::ParseError; +use crate::core::meta::Error; use super::{BinTree, BinTreeObject}; use byteorder::{ReadBytesExt, LE}; @@ -17,14 +17,14 @@ impl BinTree { /// * `reader` - A reader that implements io::Read and io::Seek. pub fn from_reader( reader: &mut R, - ) -> Result { + ) -> Result { let magic = reader.read_u32::()?; let is_override = match magic { Self::PROP => false, Self::PTCH => { let override_version = reader.read_u32::()?; if override_version != 1 { - return Err(ParseError::InvalidFileVersion(override_version)); + return Err(Error::InvalidFileVersion(override_version)); } // It might be possible to create an override property bin @@ -41,17 +41,17 @@ impl BinTree { Self::PTCH, magic ); - return Err(ParseError::InvalidFileSignature); + return Err(Error::InvalidFileSignature); } true } - _ => return Err(ParseError::InvalidFileSignature), + _ => return Err(Error::InvalidFileSignature), }; let version = reader.read_u32::()?; if !matches!(version, 1..=3) { // TODO (alan): distinguish override/non-override version - return Err(ParseError::InvalidFileVersion(version)); + return Err(Error::InvalidFileVersion(version)); } let dependencies = match version { @@ -75,7 +75,7 @@ impl BinTree { let mut objects = HashMap::with_capacity(obj_count); match Self::try_read_objects(reader, &obj_classes, &mut objects, false) { Ok(_) => {} - Err(ParseError::InvalidPropertyTypePrimitive(kind)) => { + Err(Error::InvalidPropertyTypePrimitive(kind)) => { log::warn!("Invalid prop type {kind}. Trying reading objects as legacy."); Self::try_read_objects(reader, &obj_classes, &mut objects, true)?; } @@ -108,7 +108,7 @@ impl BinTree { obj_classes: &[u32], objects: &mut HashMap, legacy: bool, - ) -> Result<(), ParseError> { + ) -> Result<(), Error> { objects.clear(); for &class_hash in obj_classes { let tree_obj = BinTreeObject::from_reader(reader, class_hash, legacy)?; diff --git a/crates/league-toolkit/src/core/meta/error.rs b/crates/league-toolkit/src/core/meta/error.rs index a695b88f..eb89616f 100644 --- a/crates/league-toolkit/src/core/meta/error.rs +++ b/crates/league-toolkit/src/core/meta/error.rs @@ -3,7 +3,7 @@ use miette::Diagnostic; use super::property::BinPropertyKind; #[derive(Debug, thiserror::Error, Diagnostic)] -pub enum ParseError { +pub enum Error { #[error("Invalid file signature")] InvalidFileSignature, #[error("Invalid file version '{0}'")] diff --git a/crates/league-toolkit/src/core/meta/mod.rs b/crates/league-toolkit/src/core/meta/mod.rs index 4eceb1ee..a992503d 100644 --- a/crates/league-toolkit/src/core/meta/mod.rs +++ b/crates/league-toolkit/src/core/meta/mod.rs @@ -1,10 +1,11 @@ -pub mod property; -pub use property::BinProperty; +//! Bin file & properties +mod property; +pub use property::*; mod bin_tree; pub use bin_tree::*; -pub mod error; +mod error; pub use error::*; pub mod traits; diff --git a/crates/league-toolkit/src/core/meta/property/mod.rs b/crates/league-toolkit/src/core/meta/property/mod.rs index debfb5ef..21918230 100644 --- a/crates/league-toolkit/src/core/meta/property/mod.rs +++ b/crates/league-toolkit/src/core/meta/property/mod.rs @@ -1,10 +1,10 @@ use num_enum::{IntoPrimitive, TryFromPrimitive}; use std::io; -use value::PropertyValueEnum; -use super::ParseError; +use super::Error; pub mod value; +pub use value::PropertyValueEnum; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive( @@ -45,6 +45,8 @@ pub enum BinPropertyKind { } impl BinPropertyKind { + /// Converts a u8 into a BinPropertyKind, accounting for pre/post WadChunkLink. + /// /// The WadChunkLink bin property type was newly added by Riot. For some reason they decided to put it in the middle of the enum, /// so we need to handle cases from before and after it existed. /// @@ -52,15 +54,14 @@ impl BinPropertyKind { /// /// "Non-legacy" property types can just be used as is. /// - pub fn unpack(raw: u8, legacy: bool) -> Result { + pub fn unpack(raw: u8, legacy: bool) -> Result { use BinPropertyKind as BPK; if !legacy { - // TODO (alan): don't panic here return Ok(BPK::try_from_primitive(raw)?); } let mut fudged = raw; - // if the prop type comes after where WadChunkLink is now, we need to + // if the prop type comes after where WadChunkLink is now, we need to fudge it if fudged >= BPK::WadChunkLink.into() && fudged < BPK::Container.into() { fudged -= Into::::into(BPK::WadChunkLink); fudged |= Into::::into(BPK::Container); @@ -73,6 +74,7 @@ impl BinPropertyKind { Ok(BinPropertyKind::try_from_primitive(fudged)?) } + /// Whether this property kind is a primitive type. (i8, u8, .. u32, u64, f32, Vector2, Vector3, Vector4, Matrix44, Color, String, Hash, WadChunkLink), pub fn is_primitive(&self) -> bool { use BinPropertyKind::*; matches!( @@ -98,6 +100,7 @@ impl BinPropertyKind { ) } + /// Whether this property kind is a container type (container, unordered container, optional, map). pub fn is_container(&self) -> bool { use BinPropertyKind::*; matches!(self, Container | UnorderedContainer | Optional | Map) @@ -107,7 +110,7 @@ impl BinPropertyKind { self, reader: &mut R, legacy: bool, - ) -> Result { + ) -> Result { PropertyValueEnum::from_reader(reader, self, legacy) } } @@ -122,10 +125,11 @@ pub struct BinProperty { use super::traits::PropertyValue as _; impl BinProperty { + /// Read a BinProperty from a reader. This will read the name_hash, prop kind and then value, in that order. pub fn from_reader( reader: &mut R, legacy: bool, - ) -> Result { + ) -> Result { use super::traits::ReaderExt; use byteorder::{ReadBytesExt as _, LE}; let name_hash = reader.read_u32::()?; diff --git a/crates/league-toolkit/src/core/meta/property/value/container.rs b/crates/league-toolkit/src/core/meta/property/value/container.rs index 1c3420ad..4123be1b 100644 --- a/crates/league-toolkit/src/core/meta/property/value/container.rs +++ b/crates/league-toolkit/src/core/meta/property/value/container.rs @@ -3,7 +3,7 @@ use std::io; use crate::core::meta::{ property::BinPropertyKind, traits::{PropertyValue as Value, ReadProperty, ReaderExt, WriteProperty, WriterExt}, - ParseError, + Error, }; use super::PropertyValueEnum; @@ -27,10 +27,10 @@ impl ReadProperty for ContainerValue { fn from_reader( reader: &mut R, legacy: bool, - ) -> Result { + ) -> Result { let item_kind = reader.read_property_kind(legacy)?; if item_kind.is_container() { - return Err(ParseError::InvalidNesting(item_kind)); + return Err(Error::InvalidNesting(item_kind)); } let size = reader.read_u32::()?; @@ -41,11 +41,11 @@ impl ReadProperty for ContainerValue { let prop = PropertyValueEnum::from_reader(reader, item_kind, legacy)?; items.push(prop); } - Ok::<_, ParseError>(items) + Ok::<_, Error>(items) })?; if size as u64 != real_size { - return Err(ParseError::InvalidSize(size as _, real_size)); + return Err(Error::InvalidSize(size as _, real_size)); } Ok(Self { item_kind, items }) diff --git a/crates/league-toolkit/src/core/meta/property/value/embedded.rs b/crates/league-toolkit/src/core/meta/property/value/embedded.rs index c23cb4ae..c48c2106 100644 --- a/crates/league-toolkit/src/core/meta/property/value/embedded.rs +++ b/crates/league-toolkit/src/core/meta/property/value/embedded.rs @@ -16,7 +16,7 @@ impl ReadProperty for EmbeddedValue { fn from_reader( reader: &mut R, legacy: bool, - ) -> Result { + ) -> Result { StructValue::from_reader(reader, legacy).map(Self) } } diff --git a/crates/league-toolkit/src/core/meta/property/value/map.rs b/crates/league-toolkit/src/core/meta/property/value/map.rs index 2d72c455..be749490 100644 --- a/crates/league-toolkit/src/core/meta/property/value/map.rs +++ b/crates/league-toolkit/src/core/meta/property/value/map.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, hash::Hash, io}; use crate::core::meta::{ property::BinPropertyKind, traits::{PropertyValue, ReadProperty, ReaderExt, WriteProperty, WriterExt}, - ParseError, + Error, }; use byteorder::{ReadBytesExt, WriteBytesExt, LE}; use io_ext::{measure, window}; @@ -66,14 +66,14 @@ impl ReadProperty for MapValue { fn from_reader( reader: &mut R, legacy: bool, - ) -> Result { + ) -> Result { let key_kind = reader.read_property_kind(legacy)?; if !key_kind.is_primitive() { - return Err(ParseError::InvalidKeyType(key_kind)); + return Err(Error::InvalidKeyType(key_kind)); } let value_kind = reader.read_property_kind(legacy)?; if value_kind.is_container() { - return Err(ParseError::InvalidNesting(value_kind)); + return Err(Error::InvalidNesting(value_kind)); } let size = reader.read_u32::()?; let (real_size, value) = measure(reader, |reader| { @@ -85,7 +85,7 @@ impl ReadProperty for MapValue { value_kind.read(reader, legacy)?, ); } - Ok::<_, ParseError>(Self { + Ok::<_, Error>(Self { key_kind, value_kind, entries, @@ -93,7 +93,7 @@ impl ReadProperty for MapValue { })?; if size as u64 != real_size { - return Err(ParseError::InvalidSize(size as _, real_size)); + return Err(Error::InvalidSize(size as _, real_size)); } Ok(value) } diff --git a/crates/league-toolkit/src/core/meta/property/value/mod.rs b/crates/league-toolkit/src/core/meta/property/value/mod.rs index 0ee21396..7f57b51c 100644 --- a/crates/league-toolkit/src/core/meta/property/value/mod.rs +++ b/crates/league-toolkit/src/core/meta/property/value/mod.rs @@ -1,3 +1,4 @@ +//! Value types for [`super::BinProperty`]. mod container; mod embedded; mod map; @@ -21,7 +22,7 @@ pub use unordered_container::*; use std::io; use crate::core::meta::{ - property::BinPropertyKind, traits::ReadProperty as _, traits::WriteProperty as _, ParseError, + property::BinPropertyKind, traits::ReadProperty as _, traits::WriteProperty as _, Error, }; use enum_dispatch::enum_dispatch; @@ -54,6 +55,7 @@ macro_rules! enum_kind { #[cfg_attr(feature = "serde", serde(tag = "kind", content = "value"))] #[derive(Clone, Debug, PartialEq)] #[enum_dispatch(PropertyValue)] +/// The value part of a [`super::BinProperty`]. Holds the type of the value, and the value itself. pub enum PropertyValueEnum { None(pub NoneValue), Bool(pub BoolValue), @@ -85,6 +87,7 @@ pub enum PropertyValueEnum { } impl PropertyValueEnum { + #[must_use] pub fn kind(&self) -> BinPropertyKind { enum_kind!( self, @@ -119,11 +122,12 @@ impl PropertyValueEnum { ] ) } + #[must_use] pub fn from_reader( reader: &mut R, kind: BinPropertyKind, legacy: bool, - ) -> Result { + ) -> Result { Ok(enum_construct!( kind, from_reader(reader, legacy)?, diff --git a/crates/league-toolkit/src/core/meta/property/value/none.rs b/crates/league-toolkit/src/core/meta/property/value/none.rs index 3da758b5..b38ac0f0 100644 --- a/crates/league-toolkit/src/core/meta/property/value/none.rs +++ b/crates/league-toolkit/src/core/meta/property/value/none.rs @@ -14,7 +14,7 @@ impl ReadProperty for NoneValue { fn from_reader( _reader: &mut R, _legacy: bool, - ) -> Result { + ) -> Result { Ok(Self) } } diff --git a/crates/league-toolkit/src/core/meta/property/value/optional.rs b/crates/league-toolkit/src/core/meta/property/value/optional.rs index f6009203..08547ae4 100644 --- a/crates/league-toolkit/src/core/meta/property/value/optional.rs +++ b/crates/league-toolkit/src/core/meta/property/value/optional.rs @@ -2,7 +2,7 @@ use super::PropertyValueEnum; use crate::core::meta::{ property::BinPropertyKind, traits::{PropertyValue, ReadProperty, ReaderExt, WriteProperty, WriterExt}, - ParseError, + Error, }; use io_ext::{ReaderExt as _, WriterExt as _}; @@ -26,10 +26,10 @@ impl ReadProperty for OptionalValue { fn from_reader( reader: &mut R, legacy: bool, - ) -> Result { + ) -> Result { let kind = reader.read_property_kind(legacy)?; if kind.is_container() { - return Err(ParseError::InvalidNesting(kind)); + return Err(Error::InvalidNesting(kind)); } let is_some = reader.read_bool()?; diff --git a/crates/league-toolkit/src/core/meta/property/value/primitives.rs b/crates/league-toolkit/src/core/meta/property/value/primitives.rs index 5d2371ef..6cc13ecb 100644 --- a/crates/league-toolkit/src/core/meta/property/value/primitives.rs +++ b/crates/league-toolkit/src/core/meta/property/value/primitives.rs @@ -18,7 +18,7 @@ macro_rules! impl_prim { fn from_reader( reader: &mut R, _legacy: bool, - ) -> Result { + ) -> Result { Ok(Self(paste::paste!(reader.[]::<$($endian,)*>()?))) } } diff --git a/crates/league-toolkit/src/core/meta/property/value/string.rs b/crates/league-toolkit/src/core/meta/property/value/string.rs index 875d4658..4ad07c0e 100644 --- a/crates/league-toolkit/src/core/meta/property/value/string.rs +++ b/crates/league-toolkit/src/core/meta/property/value/string.rs @@ -17,7 +17,7 @@ impl ReadProperty for StringValue { fn from_reader( reader: &mut R, _legacy: bool, - ) -> Result { + ) -> Result { Ok(Self(reader.read_len_prefixed_string::()?)) } } diff --git a/crates/league-toolkit/src/core/meta/property/value/struct.rs b/crates/league-toolkit/src/core/meta/property/value/struct.rs index 53bf975c..84b9d1aa 100644 --- a/crates/league-toolkit/src/core/meta/property/value/struct.rs +++ b/crates/league-toolkit/src/core/meta/property/value/struct.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, io}; use crate::core::meta::{ traits::{PropertyValue as Value, ReadProperty, WriteProperty}, - BinProperty, ParseError, + BinProperty, Error, }; use byteorder::{ReadBytesExt as _, WriteBytesExt as _, LE}; use io_ext::{measure, window}; @@ -27,7 +27,7 @@ impl ReadProperty for StructValue { fn from_reader( reader: &mut R, legacy: bool, - ) -> Result { + ) -> Result { let class_hash = reader.read_u32::()?; if class_hash == 0 { return Ok(Self { @@ -45,16 +45,14 @@ impl ReadProperty for StructValue { let prop = BinProperty::from_reader(reader, legacy)?; properties.insert(prop.name_hash, prop); } - Ok::<_, ParseError>(Self { + Ok::<_, Error>(Self { class_hash, properties, }) })?; if size as u64 != real_size { - return Err(crate::core::meta::ParseError::InvalidSize( - size as _, real_size, - )); + return Err(crate::core::meta::Error::InvalidSize(size as _, real_size)); } Ok(value) diff --git a/crates/league-toolkit/src/core/meta/property/value/unordered_container.rs b/crates/league-toolkit/src/core/meta/property/value/unordered_container.rs index 3da47f39..461411d5 100644 --- a/crates/league-toolkit/src/core/meta/property/value/unordered_container.rs +++ b/crates/league-toolkit/src/core/meta/property/value/unordered_container.rs @@ -16,7 +16,7 @@ impl ReadProperty for UnorderedContainerValue { fn from_reader( reader: &mut R, legacy: bool, - ) -> Result { + ) -> Result { Ok(Self(ContainerValue::from_reader(reader, legacy)?)) } } diff --git a/crates/league-toolkit/src/core/meta/traits.rs b/crates/league-toolkit/src/core/meta/traits.rs index e1686919..8d507fba 100644 --- a/crates/league-toolkit/src/core/meta/traits.rs +++ b/crates/league-toolkit/src/core/meta/traits.rs @@ -6,9 +6,10 @@ use enum_dispatch::enum_dispatch; const HEADER_SIZE: usize = 5; -/// Trait for property values +/// General methods for property values #[enum_dispatch] pub trait PropertyValue { + /// Get the size of the property value, including the kind header if specified fn size(&self, include_header: bool) -> usize { self.size_no_header() + match include_header { @@ -19,28 +20,28 @@ pub trait PropertyValue { fn size_no_header(&self) -> usize; } -/// Trait for reading property values +/// Methods for reading properties pub trait ReadProperty: Sized { fn from_reader( reader: &mut R, legacy: bool, - ) -> Result; + ) -> Result; } -/// Extension trait for reading property values +/// Extension trait for reading property kinds pub trait ReaderExt: io::Read { /// Reads a u8 as a property kind fn read_property_kind( &mut self, legacy: bool, - ) -> Result { + ) -> Result { BinPropertyKind::unpack(self.read_u8()?, legacy) } } impl ReaderExt for R {} -/// Trait for writing property values +/// Methods for writing properties pub trait WriteProperty: Sized { fn to_writer( &self, diff --git a/crates/league-toolkit/src/core/wad/chunk.rs b/crates/league-toolkit/src/core/wad/chunk.rs index caa5b6ec..268d3721 100644 --- a/crates/league-toolkit/src/core/wad/chunk.rs +++ b/crates/league-toolkit/src/core/wad/chunk.rs @@ -18,6 +18,7 @@ pub enum WadChunkCompression { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Clone, Copy, Debug, PartialEq, Eq)] +/// A single wad chunk pub struct WadChunk { pub path_hash: u64, pub data_offset: usize, diff --git a/crates/league-toolkit/src/core/wad/mod.rs b/crates/league-toolkit/src/core/wad/mod.rs index 739dfef8..1e2beb5e 100644 --- a/crates/league-toolkit/src/core/wad/mod.rs +++ b/crates/league-toolkit/src/core/wad/mod.rs @@ -1,3 +1,4 @@ +//! Wad file handling mod chunk; mod decoder; mod error; @@ -15,6 +16,7 @@ use byteorder::{ReadBytesExt as _, LE}; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug)] +/// A wad file pub struct Wad { chunks: HashMap, #[cfg_attr(feature = "serde", serde(skip))]