infinite_rs/tag/structure.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
//! Hierarchical structure entry of tag.
use byteorder::{ReadBytesExt, LE};
use num_enum::TryFromPrimitive;
use std::io::BufRead;
use crate::common::errors::{Error, TagError};
use crate::common::extensions::Enumerable;
use crate::Result;
#[derive(Default, Debug, TryFromPrimitive, PartialEq, Eq)]
#[repr(u16)]
/// Enum defining what the tag struct is pointing to.
pub enum TagStructType {
#[default]
/// "Root" of structure.
MainStruct,
/// An array of items in structure.
TagBlock,
/// Reference to child resource.
Resource,
/// Reference to "external" resource.
Custom,
/// Unknown
Literal,
}
#[derive(Default, Debug)]
/// Structure defining the hierarchical order of info in tags.
pub struct TagStruct {
/// GUID of the structure referenced.
pub guid: u128,
/// Where the structure is located.
pub struct_type: TagStructType,
/// Unknown (but important)
unknown: u16,
/// For main struct and tag block structs, the index of the block containing the struct.
/// For resource structs, index of the resource.
/// Can be -1 if the tag field doesn't point to anything.
pub target_index: i32,
/// The index of the data block containing the tag field which refers to this struct.
/// Can be -1 for the main struct.
pub field_block: i32,
/// The offset of the tag field inside the data block.
pub field_offset: u32,
}
impl Enumerable for TagStruct {
fn read<R: BufRead>(&mut self, reader: &mut R) -> Result<()> {
self.guid = reader.read_u128::<LE>()?;
self.struct_type = TagStructType::try_from(reader.read_u16::<LE>()?)
.map_err(|e| Error::TagError(TagError::InvalidTagStruct(e)))?;
self.unknown = reader.read_u16::<LE>()?;
self.target_index = reader.read_i32::<LE>()?;
self.field_block = reader.read_i32::<LE>()?;
self.field_offset = reader.read_u32::<LE>()?;
Ok(())
}
}