Overhaul: migrated from anyhow to my own FError so error handling would be much better and precise

This commit is contained in:
mykola2312 2023-09-09 15:37:45 +03:00
parent bf5810c4d7
commit eff42b2605
17 changed files with 133 additions and 93 deletions

7
Cargo.lock generated
View file

@ -8,12 +8,6 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "byteorder"
version = "1.4.3"
@ -54,7 +48,6 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
name = "fot-save-edit"
version = "0.1.0"
dependencies = [
"anyhow",
"byteorder",
"deflate",
"encoding_rs",

View file

@ -6,7 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.75"
byteorder = "1.4.3"
deflate = "1.0.0"
encoding_rs = "0.8.33"

View file

@ -3,6 +3,7 @@ mod decoder;
mod entity;
mod entitylist;
mod esh;
mod ferror;
mod fstring;
mod raw;
pub mod save;

View file

@ -1,9 +1,9 @@
use crate::fot::decoder::Decoder;
use super::esh::{ESHValue, ESH};
use super::ferror::FError as FE;
use super::stream::{ReadStream, WriteStream};
use super::tag::Tag;
use anyhow::{anyhow, Result};
use indexmap::IndexMap;
const MAX_STATS: usize = 7;
@ -273,13 +273,13 @@ pub struct Attributes {
}
impl Attributes {
pub fn from_binary(bin: &[u8]) -> Result<Self> {
pub fn from_binary(bin: &[u8]) -> Result<Self, FE> {
let mut rd = ReadStream::new(bin, 0);
let size1 = rd.read_u32()?;
let esh: ESH = rd.read()?;
if esh.props["Binary"] == ESHValue::Bool(false) {
return Err(anyhow!("Attributes Binary == false"));
return Err(FE::AttributesNonBinary);
}
let mut stats: IndexMap<&'static str, u32> = IndexMap::with_capacity(7);
@ -339,11 +339,11 @@ impl Attributes {
addictions,
})
} else {
return Err(anyhow!("Attributes has no esbin"));
return Err(FE::AttributesNoESBIN);
}
}
pub fn into_binary(mut self) -> Result<Vec<u8>> {
pub fn into_binary(mut self) -> Result<Vec<u8>, FE> {
let esbin = {
let mut wd = WriteStream::new(self.enc_size);

View file

@ -1,32 +1,32 @@
use super::ferror::FError as FE;
use super::stream::{ReadStream, WriteStream};
use anyhow::{anyhow, Result};
use std::str;
pub trait Decoder: Sized {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self>;
fn encode(&self, wd: &mut WriteStream) -> Result<()>;
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self, FE>;
fn encode(&self, wd: &mut WriteStream) -> Result<(), FE>;
fn get_enc_size(&self) -> usize;
}
pub trait DecoderCtx<DCtx, ECtx>: Sized {
fn decode<'a>(rd: &mut ReadStream<'a>, ctx: DCtx) -> Result<Self>;
fn encode(&self, wd: &mut WriteStream, ctx: ECtx) -> Result<()>;
fn decode<'a>(rd: &mut ReadStream<'a>, ctx: DCtx) -> Result<Self, FE>;
fn encode(&self, wd: &mut WriteStream, ctx: ECtx) -> Result<(), FE>;
fn get_enc_size(&self) -> usize;
}
impl Decoder for String {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self> {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self, FE> {
let bytes = rd.as_byte_arr();
let pos = match bytes.iter().position(|&c| c == 0) {
Some(pos) => pos,
None => return Err(anyhow!("No zero-terminator found")),
None => return Err(FE::NoZeroTerminator),
};
let str = str::from_utf8(rd.as_bytes(pos)?)?;
rd.skip(1);
Ok(str.to_string())
}
fn encode(&self, wd: &mut WriteStream) -> Result<()> {
fn encode(&self, wd: &mut WriteStream) -> Result<(), FE> {
wd.write_bytes(self.as_bytes());
wd.write_u8(0)?;
Ok(())

View file

@ -2,8 +2,8 @@ use super::attributes::Attributes;
use super::decoder::DecoderCtx;
use super::entitylist::{EntityEncoding, EntityList};
use super::esh::{ESHValue, ESH};
use super::ferror::FError as FE;
use super::stream::{ReadStream, WriteStream};
use anyhow::{anyhow, Result};
pub const NO_FLAGS: u32 = 0;
pub const NO_ESH: usize = 0xFFFF;
@ -16,34 +16,34 @@ pub struct Entity {
}
impl Entity {
pub fn get_esh(&self) -> Result<&ESH> {
pub fn get_esh(&self) -> Result<&ESH, FE> {
match &self.esh {
Some(esh) => Ok(esh),
None => Err(anyhow!("Entity has no ESH")),
None => Err(FE::EntityNoESH),
}
}
pub fn get_esh_mut(&mut self) -> Result<&mut ESH> {
pub fn get_esh_mut(&mut self) -> Result<&mut ESH, FE> {
match &mut self.esh {
Some(esh) => Ok(esh),
None => Err(anyhow!("Entity has no ESH")),
None => Err(FE::EntityNoESH),
}
}
pub fn get_attributes(&self) -> Result<Attributes> {
pub fn get_attributes(&self) -> Result<Attributes, FE> {
let value = match self.get_esh()?.get("Attributes") {
Some(value) => value,
None => return Err(anyhow!("Entity has no Attributes")),
None => return Err(FE::EntityNoAttributes),
};
if let ESHValue::Binary(bin) = value {
Ok(Attributes::from_binary(&bin)?)
} else {
Err(anyhow!("Attributes is not binary"))
Err(FE::AttributesNonBinary)
}
}
pub fn set_attributes(&mut self, attrs: Attributes) -> Result<()> {
pub fn set_attributes(&mut self, attrs: Attributes) -> Result<(), FE> {
self.get_esh_mut()?
.set("Attributes", ESHValue::Binary(attrs.into_binary()?));
@ -52,7 +52,7 @@ impl Entity {
}
impl DecoderCtx<&mut EntityList, &EntityList> for Entity {
fn decode<'a>(rd: &mut ReadStream<'a>, ctx: &mut EntityList) -> Result<Self> {
fn decode<'a>(rd: &mut ReadStream<'a>, ctx: &mut EntityList) -> Result<Self, FE> {
let offset = rd.offset();
Ok(match ctx.get_entity_encoding() {
EntityEncoding::File => {
@ -87,7 +87,7 @@ impl DecoderCtx<&mut EntityList, &EntityList> for Entity {
})
}
fn encode(&self, wd: &mut WriteStream, ctx: &EntityList) -> Result<()> {
fn encode(&self, wd: &mut WriteStream, ctx: &EntityList) -> Result<(), FE> {
match ctx.get_entity_encoding() {
EntityEncoding::File => {
wd.write(ctx.get_type_name(self.type_idx))?;

View file

@ -1,10 +1,9 @@
use super::decoder::{Decoder, DecoderCtx};
use super::entity::Entity;
use super::ferror::FError as FE;
use super::fstring::{FString, FStringEncoding};
use super::stream::{ReadStream, WriteStream};
use super::tag::{CTag, Tag};
use anyhow::anyhow;
use anyhow::Result;
use std::path::Path;
#[derive(Clone, Copy, PartialEq)]
@ -66,10 +65,10 @@ impl EntityList {
&mut self.ents[id - 1]
}
pub fn dump_to_entfile(&self, ent: &Entity, path: &Path) -> Result<()> {
pub fn dump_to_entfile(&self, ent: &Entity, path: &Path) -> Result<(), FE> {
let esh = match &ent.esh {
Some(esh) => esh,
None => return Err(anyhow!("entity has no esh")),
None => return Err(FE::EntityNoESH),
};
let tag = DEFAULT_ENTITY_TAG.to_tag();
@ -87,7 +86,7 @@ impl EntityList {
}
impl DecoderCtx<EntityEncoding, EntityEncoding> for EntityList {
fn decode<'a>(rd: &mut ReadStream<'a>, ctx: EntityEncoding) -> Result<Self> {
fn decode<'a>(rd: &mut ReadStream<'a>, ctx: EntityEncoding) -> Result<Self, FE> {
let offset = rd.offset();
let mut ent_list = EntityList {
encoding: ctx,
@ -137,7 +136,7 @@ impl DecoderCtx<EntityEncoding, EntityEncoding> for EntityList {
})
}
fn encode(&self, wd: &mut WriteStream, ctx: EntityEncoding) -> Result<()> {
fn encode(&self, wd: &mut WriteStream, ctx: EntityEncoding) -> Result<(), FE> {
match ctx {
EntityEncoding::File => {
for ent in self.ents.iter() {

View file

@ -1,8 +1,8 @@
use super::decoder::Decoder;
use super::ferror::FError as FE;
use super::fstring::FString;
use super::stream::{ReadStream, WriteStream};
use super::tag::Tag;
use anyhow::Result;
use indexmap::IndexMap;
use std::fmt;
@ -77,7 +77,7 @@ impl ESHValue {
}
impl Decoder for ESHValue {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self> {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self, FE> {
let data_type = rd.read_u32()?;
let data_size = rd.read_u32()?;
@ -120,7 +120,7 @@ impl Decoder for ESHValue {
})
}
fn encode(&self, wd: &mut WriteStream) -> Result<()> {
fn encode(&self, wd: &mut WriteStream) -> Result<(), FE> {
match self {
ESHValue::Unknown(unk) => {
wd.write_u32(unk.data_type)?;
@ -266,7 +266,7 @@ impl ESH {
}
impl Decoder for ESH {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self> {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self, FE> {
let offset = rd.offset();
let tag: Tag = rd.read()?;
@ -286,7 +286,7 @@ impl Decoder for ESH {
})
}
fn encode(&self, wd: &mut WriteStream) -> Result<()> {
fn encode(&self, wd: &mut WriteStream) -> Result<(), FE> {
wd.write(&self.tag)?;
wd.write_u32(self.props.len() as u32)?;

51
src/fot/ferror.rs Normal file
View file

@ -0,0 +1,51 @@
#[derive(Debug)]
pub enum FError {
IOError(std::io::Error),
Utf8Error(std::str::Utf8Error),
DeflateError(String),
NoWorld,
NoCampaign,
UnknownWorldSize,
StreamOverflow(usize, usize, usize),
NoZeroTerminator,
EntityNoESH,
EntityNoAttributes,
AttributesNonBinary,
AttributesNoESBIN,
}
impl std::fmt::Display for FError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
use FError as FE;
match self {
FE::IOError(e) => write!(f, "IOError {}", e),
FE::Utf8Error(e) => write!(f, "Utf8Error {}", e),
FE::DeflateError(e) => write!(f, "DeflateError {}", e),
FE::NoWorld => write!(f, "No world found in file"),
FE::NoCampaign => write!(f, "No campaign found after world"),
FE::UnknownWorldSize => write!(f, "Unable to determine world block size"),
FE::StreamOverflow(offset, size, read) => write!(
f,
"stream read {} at offset {} overflow size {}",
read, offset, size
),
FE::NoZeroTerminator => write!(f, "No zero-terminator when String::decode"),
FE::EntityNoESH => write!(f, "Entity has no ESH"),
FE::EntityNoAttributes => write!(f, "Entity has no Attributes"),
FE::AttributesNonBinary => write!(f, "Attributes Binary != true"),
FE::AttributesNoESBIN => write!(f, "Attributes has no esbin"),
}
}
}
impl From<std::io::Error> for FError {
fn from(value: std::io::Error) -> Self {
FError::IOError(value)
}
}
impl From<std::str::Utf8Error> for FError {
fn from(value: std::str::Utf8Error) -> Self {
FError::Utf8Error(value)
}
}

View file

@ -1,6 +1,6 @@
use super::decoder::Decoder;
use super::ferror::FError as FE;
use super::stream::{ReadStream, WriteStream};
use anyhow::Result;
use encoding_rs::WINDOWS_1251;
use std::borrow::Borrow;
use std::fmt;
@ -22,7 +22,7 @@ pub struct FString {
}
impl Decoder for FString {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self> {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self, FE> {
//let mut rdr = Cursor::new(&raw.mem[offset..]);
let flen = rd.read_u32()? as usize;
let len = flen & !(1 << 31);
@ -48,7 +48,7 @@ impl Decoder for FString {
}
}
fn encode(&self, wd: &mut WriteStream) -> Result<()> {
fn encode(&self, wd: &mut WriteStream) -> Result<(), FE> {
let (chars, _, _) = WINDOWS_1251.encode(self.str.as_str());
if self.encoding == FStringEncoding::ANSI {
wd.write_u32(chars.len() as u32 & !(1 << 31))?;

View file

@ -1,4 +1,4 @@
use anyhow::Result;
use super::ferror::FError as FE;
use memmem::{Searcher, TwoWaySearcher};
use std::fs;
use std::fs::OpenOptions;
@ -31,7 +31,7 @@ impl Raw {
None
}
pub fn load_file(path: &Path) -> Result<Raw> {
pub fn load_file(path: &Path) -> Result<Raw, FE> {
let mem = fs::read(path)?;
Ok(Self {
@ -41,7 +41,7 @@ impl Raw {
})
}
pub fn assemble_file(&self, path: &Path, blocks: Vec<Raw>) -> Result<()> {
pub fn assemble_file(&self, path: &Path, blocks: Vec<Raw>) -> Result<(), FE> {
let mut file = BufWriter::new(
OpenOptions::new()
.create(true)
@ -76,7 +76,7 @@ impl Raw {
Ok(())
}
pub fn dump(&self, path: &Path) -> Result<()> {
pub fn dump(&self, path: &Path) -> Result<(), FE> {
let mut file = BufWriter::new(
OpenOptions::new()
.create(true)

View file

@ -1,9 +1,8 @@
use super::decoder::DecoderCtx;
use super::ferror::FError as FE;
use super::raw::Raw;
use super::stream::{ReadStream, WriteStream};
use super::world::World;
use anyhow::anyhow;
use anyhow::Result;
use byteorder::{ByteOrder, LittleEndian};
use std::path::Path;
use std::str;
@ -17,18 +16,18 @@ impl Save {
const WORLD_TAG: &str = "<world>";
const CAMPAIGN_TAG: &str = "<campaign>";
pub fn load(path: &Path) -> Result<Self> {
pub fn load(path: &Path) -> Result<Self, FE> {
let raw = Raw::load_file(path)?;
let world_offset = match raw.find_str_backwards(Self::WORLD_TAG) {
Some(offset) => offset,
None => return Err(anyhow!("no world found in file")),
None => return Err(FE::NoWorld),
};
let mut world_size: usize = 0;
{
let campaign = match raw.find_str(Self::CAMPAIGN_TAG, world_offset) {
Some(campaign) => world_offset + campaign,
None => return Err(anyhow!("no campaign found after world")),
None => return Err(FE::NoCampaign),
};
for i in (campaign - 256..campaign).rev() {
@ -43,7 +42,7 @@ impl Save {
}
}
if world_size == 0 {
return Err(anyhow!("Unable to determine world block size"));
return Err(FE::UnknownWorldSize);
}
let mut rd = ReadStream::new(&raw.mem, world_offset);
@ -51,7 +50,7 @@ impl Save {
Ok(Save { raw, world })
}
pub fn save(&self, path: &Path) -> Result<()> {
pub fn save(&self, path: &Path) -> Result<(), FE> {
let raw = {
let mut wd = WriteStream::new(0);
wd.write_ctx(&self.world, ())?;

View file

@ -1,8 +1,8 @@
use super::decoder::Decoder;
use super::ferror::FError as FE;
use super::fstring::FString;
use super::stream::{ReadStream, WriteStream};
use super::tag::Tag;
use anyhow::Result;
use indexmap::IndexMap;
#[derive(Debug)]
@ -14,7 +14,7 @@ pub struct SGD {
}
impl Decoder for SGD {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self> {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self, FE> {
let offset = rd.offset();
let tag: Tag = rd.read()?;
let unk1 = rd.read_bytes(0x48)?;
@ -47,7 +47,7 @@ impl Decoder for SGD {
})
}
fn encode(&self, wd: &mut WriteStream) -> Result<()> {
fn encode(&self, wd: &mut WriteStream) -> Result<(), FE> {
wd.write(&self.tag)?;
wd.write_bytes(&self.unk1);

View file

@ -1,7 +1,7 @@
use super::decoder::Decoder;
use super::ferror::FError as FE;
use super::stream::{ReadStream, WriteStream};
use super::tag::Tag;
use anyhow::Result;
#[derive(Debug)]
pub struct SSG {
@ -10,13 +10,13 @@ pub struct SSG {
}
impl Decoder for SSG {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self> {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self, FE> {
let tag: Tag = rd.read()?;
let unk1 = rd.read_bytes(0x14)?;
Ok(SSG { tag, unk1 })
}
fn encode(&self, wd: &mut WriteStream) -> Result<()> {
fn encode(&self, wd: &mut WriteStream) -> Result<(), FE> {
wd.write(&self.tag)?;
wd.write_bytes(&self.unk1);
Ok(())

View file

@ -1,7 +1,6 @@
use super::decoder::{Decoder, DecoderCtx};
use super::ferror::FError as FE;
use super::raw::Raw;
use anyhow::anyhow;
use anyhow::Result;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::io::Cursor;
@ -37,10 +36,10 @@ impl<'a> ReadStream<'a> {
&self.mem[self.offset()..]
}
pub fn as_bytes(&mut self, size: usize) -> Result<&'a [u8]> {
pub fn as_bytes(&mut self, size: usize) -> Result<&'a [u8], FE> {
if self.offset() + size > self.mem.len() {
dbg!(self.offset(), size, self.mem.len());
Err(anyhow!("as_bytes/read_bytes size is bigger than buffer"))
Err(FE::StreamOverflow(self.offset(), self.size(), size))
} else {
let buf = &self.mem[self.offset()..self.offset() + size];
self.skip(size);
@ -48,7 +47,7 @@ impl<'a> ReadStream<'a> {
}
}
pub fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>> {
pub fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>, FE> {
Ok(self.as_bytes(size)?.to_vec())
}
@ -58,35 +57,35 @@ impl<'a> ReadStream<'a> {
// read_opt - decode with optional paramters. required for complex structure
// with different origins (save / entfile) like entities
pub fn read_ctx<T: DecoderCtx<DCtx, ECtx>, DCtx, ECtx>(&mut self, ctx: DCtx) -> Result<T> {
pub fn read_ctx<T: DecoderCtx<DCtx, ECtx>, DCtx, ECtx>(&mut self, ctx: DCtx) -> Result<T, FE> {
Ok(T::decode(self, ctx)?)
}
pub fn read<T: Decoder>(&mut self) -> Result<T> {
pub fn read<T: Decoder>(&mut self) -> Result<T, FE> {
Ok(T::decode(self)?)
}
pub fn read_u8(&mut self) -> Result<u8> {
pub fn read_u8(&mut self) -> Result<u8, FE> {
Ok(self.rdr.read_u8()?)
}
pub fn read_bool(&mut self) -> Result<bool> {
pub fn read_bool(&mut self) -> Result<bool, FE> {
Ok(self.read_u8()? != 0)
}
pub fn read_u16(&mut self) -> Result<u16> {
pub fn read_u16(&mut self) -> Result<u16, FE> {
Ok(self.rdr.read_u16::<LittleEndian>()?)
}
pub fn read_i32(&mut self) -> Result<i32> {
pub fn read_i32(&mut self) -> Result<i32, FE> {
Ok(self.rdr.read_i32::<LittleEndian>()?)
}
pub fn read_u32(&mut self) -> Result<u32> {
pub fn read_u32(&mut self) -> Result<u32, FE> {
Ok(self.rdr.read_u32::<LittleEndian>()?)
}
pub fn read_f32(&mut self) -> Result<f32> {
pub fn read_f32(&mut self) -> Result<f32, FE> {
Ok(self.rdr.read_f32::<LittleEndian>()?)
}
}
@ -132,39 +131,39 @@ impl WriteStream {
&mut self,
val: &T,
ctx: ECtx,
) -> Result<()> {
) -> Result<(), FE> {
self.reserve(val.get_enc_size());
val.encode(self, ctx)?;
Ok(())
}
pub fn write<T: Decoder>(&mut self, val: &T) -> Result<()> {
pub fn write<T: Decoder>(&mut self, val: &T) -> Result<(), FE> {
self.reserve(val.get_enc_size());
val.encode(self)?;
Ok(())
}
pub fn write_u8(&mut self, val: u8) -> Result<()> {
pub fn write_u8(&mut self, val: u8) -> Result<(), FE> {
Ok(self.buf.write_u8(val)?)
}
pub fn write_bool(&mut self, val: bool) -> Result<()> {
pub fn write_bool(&mut self, val: bool) -> Result<(), FE> {
self.write_u8(val as u8)
}
pub fn write_u16(&mut self, val: u16) -> Result<()> {
pub fn write_u16(&mut self, val: u16) -> Result<(), FE> {
Ok(self.buf.write_u16::<LittleEndian>(val)?)
}
pub fn write_i32(&mut self, val: i32) -> Result<()> {
pub fn write_i32(&mut self, val: i32) -> Result<(), FE> {
Ok(self.buf.write_i32::<LittleEndian>(val)?)
}
pub fn write_u32(&mut self, val: u32) -> Result<()> {
pub fn write_u32(&mut self, val: u32) -> Result<(), FE> {
Ok(self.buf.write_u32::<LittleEndian>(val)?)
}
pub fn write_f32(&mut self, val: f32) -> Result<()> {
pub fn write_f32(&mut self, val: f32) -> Result<(), FE> {
Ok(self.buf.write_f32::<LittleEndian>(val)?)
}
}

View file

@ -1,6 +1,6 @@
use super::decoder::Decoder;
use super::ferror::FError as FE;
use super::stream::{ReadStream, WriteStream};
use anyhow::Result;
#[derive(Debug)]
pub struct Tag {
@ -9,13 +9,13 @@ pub struct Tag {
}
impl Decoder for Tag {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self> {
fn decode<'a>(rd: &mut ReadStream<'a>) -> Result<Self, FE> {
let name: String = rd.read()?;
let version: String = rd.read()?;
Ok(Tag { name, version })
}
fn encode(&self, wd: &mut WriteStream) -> Result<()> {
fn encode(&self, wd: &mut WriteStream) -> Result<(), FE> {
wd.write(&self.name)?;
wd.write(&self.version)?;
Ok(())

View file

@ -1,13 +1,12 @@
use super::decoder::DecoderCtx;
use super::entitylist::{EntityEncoding, EntityList};
use super::esh::ESHValue;
use super::ferror::FError as FE;
use super::fstring::FString;
use super::sgd::SGD;
use super::ssg::SSG;
use super::stream::{ReadStream, WriteStream};
use super::tag::Tag;
use anyhow::anyhow;
use anyhow::Result;
use deflate::deflate_bytes_zlib;
use inflate::inflate_bytes_zlib;
@ -30,7 +29,7 @@ pub struct World {
impl World {
const WORLD_HDR_LEN: usize = 0x13;
pub fn test(&mut self) -> Result<()> {
pub fn test(&mut self) -> Result<(), FE> {
//let actor_type = self.entlist.get_type_idx("Actor").unwrap();
//let ent = self.entlist.get_entity_mut(2122);
let ent = self.entlist.get_entity_mut(2158);
@ -68,7 +67,7 @@ impl World {
pub type WorldOffsetSize = (usize, usize);
impl DecoderCtx<WorldOffsetSize, ()> for World {
fn decode<'a>(enc: &mut ReadStream<'a>, ctx: WorldOffsetSize) -> Result<Self> {
fn decode<'a>(enc: &mut ReadStream<'a>, ctx: WorldOffsetSize) -> Result<Self, FE> {
let offset = ctx.0;
let size = ctx.1;
@ -76,7 +75,7 @@ impl DecoderCtx<WorldOffsetSize, ()> for World {
let uncompressed_size = enc.read_u32()?;
enc.skip(4);
let data = inflate_bytes_zlib(enc.as_bytes(size)?).map_err(|e| anyhow!(e))?;
let data = inflate_bytes_zlib(enc.as_bytes(size)?).map_err(|e| FE::DeflateError(e))?;
let mut rd = ReadStream::new(&data, 0);
let mission: FString = rd.read()?;
@ -101,7 +100,7 @@ impl DecoderCtx<WorldOffsetSize, ()> for World {
})
}
fn encode(&self, wd: &mut WriteStream, _: ()) -> Result<()> {
fn encode(&self, wd: &mut WriteStream, _: ()) -> Result<(), FE> {
let data = {
let mut wd = WriteStream::new(self.uncompressed_size as usize);