Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rc): Use rc instead of vec #7

Merged
merged 1 commit into from
Sep 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion models/src/bio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub struct Biography(pub VarriableCharArray);

impl Model for Biography {
fn new(buffer: &[u8]) -> Self {
Self(VarriableCharArray(buffer.to_vec()))
Self(VarriableCharArray(buffer.into()))
}

fn create_as_rc(buffer: &[u8]) -> Rc<dyn Model> {
Expand Down
26 changes: 20 additions & 6 deletions models/src/common/varriable_char_array.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use std::fmt::{Debug, Display};
use std::{
fmt::{Debug, Display},
rc::Rc,
};

use serde::{Serialize, Serializer};

pub const DEFAULT: &VarriableCharArray = &VarriableCharArray(vec![]);

#[derive(PartialEq, Eq)]
pub struct VarriableCharArray(pub Vec<u8>);
pub struct VarriableCharArray(pub Rc<[u8]>);

impl Display for VarriableCharArray {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Expand All @@ -27,11 +28,10 @@ impl Debug for VarriableCharArray {

impl From<&str> for VarriableCharArray {
fn from(value: &str) -> Self {
Self(value.as_bytes().to_vec())
Self(value.as_bytes().into())
}
}

// TODO: Make this less expensive
impl Clone for VarriableCharArray {
fn clone(&self) -> Self {
Self(self.0.clone())
Expand All @@ -46,3 +46,17 @@ impl Serialize for VarriableCharArray {
serializer.collect_str(&format!("{}", self))
}
}

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn strips_nulls_and_returns() {
let from = "BALDUR\0";
let expected = "BALDUR";
assert_eq!(
VarriableCharArray(from.as_bytes().into()).to_string(),
expected
)
}
}
20 changes: 12 additions & 8 deletions models/src/ids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ use serde::Serialize;

use crate::{
common::{
fixed_char_array::FixedCharSlice,
header::Header,
varriable_char_array::{VarriableCharArray, DEFAULT},
fixed_char_array::FixedCharSlice, header::Header, varriable_char_array::VarriableCharArray,
},
model::Model,
resources::utils::row_parser,
Expand All @@ -30,12 +28,18 @@ impl Model for Ids {
fn new(buffer: &[u8]) -> Self {
let (headers, mut end) = row_parser(buffer, 0);

let signature = headers.first().unwrap_or(DEFAULT);
let header = Header {
signature: FixedCharSlice::<3>::try_from(signature).unwrap_or_default(),
version: FixedCharSlice::<4>::try_from(headers.last().unwrap_or(signature))
.unwrap_or_default(),
let signature = if let Some(_) = headers.first() {
FixedCharSlice::<3>::from(&buffer[0..3])
} else {
FixedCharSlice::<3>::default()
};
let version = match headers.last() {
Some(x) if FixedCharSlice::<4>::try_from(x).is_ok() => {
FixedCharSlice::<4>::try_from(x).unwrap()
}
_ => FixedCharSlice::<4>::from(signature.0.as_ref()),
};
let header = Header { signature, version };

let mut data_entries = vec![];
while end < buffer.len() {
Expand Down
2 changes: 1 addition & 1 deletion models/src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl BiffIndex {
let end = start + usize::try_from(header.file_name_length).unwrap_or(0);
buffer.get(start..end).map(|buff| BiffIndex {
header: *header,
name: VarriableCharArray(buff.to_vec()),
name: VarriableCharArray(buff.into()),
})
}
}
Expand Down
33 changes: 20 additions & 13 deletions models/src/resources/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::{
mem::{size_of, ManuallyDrop},
ptr, vec,
ptr,
rc::Rc,
vec,
};

use crate::common::varriable_char_array::VarriableCharArray;
Expand Down Expand Up @@ -41,18 +43,23 @@ const CARRAGE_RETURN: u8 = 0xD;
const NEW_LINE: u8 = 0xA;

pub fn dumb_row_parser(buffer: &[u8]) -> Vec<VarriableCharArray> {
buffer
.iter()
.fold(vec![], |mut acc: Vec<VarriableCharArray>, x: &u8| {
match x {
x if x == &NEW_LINE || x == &CARRAGE_RETURN => {
acc.push(VarriableCharArray(vec![32]))
}
x if acc.last().is_some() => acc.last_mut().unwrap().0.push(*x),
_ => acc.push(VarriableCharArray(vec![*x])),
let mut acc = vec![];
let mut pos = 0;
for (i, x) in buffer.iter().enumerate() {
if x == &NEW_LINE || x == &CARRAGE_RETURN {
if pos < i {
acc.push(VarriableCharArray(buffer.get(pos..i).unwrap().into()))
}
acc
})
acc.push(VarriableCharArray(Rc::new([32])));
pos = i;
}
}
if pos < buffer.len() {
acc.push(VarriableCharArray(
buffer.get(pos..buffer.len()).unwrap().into(),
))
}
acc
}

pub fn row_parser(buffer: &[u8], row_start: usize) -> (Vec<VarriableCharArray>, usize) {
Expand All @@ -70,7 +77,7 @@ pub fn row_parser(buffer: &[u8], row_start: usize) -> (Vec<VarriableCharArray>,
if buff.is_empty() {
return None;
}
Some(VarriableCharArray(buff.to_vec()))
Some(VarriableCharArray(buff.into()))
})
.collect();

Expand Down
2 changes: 1 addition & 1 deletion models/src/tlk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ impl TLKDataEntry {
+ usize::try_from(entry.offset_of_this_string_relative_to_the_strings_section)
.unwrap_or(0);
let buff_end = buff_start + usize::try_from(entry.length_of_this_string).unwrap_or(0);
let strings = VarriableCharArray(buffer.get(buff_start..buff_end).unwrap().to_vec());
let strings = VarriableCharArray(buffer.get(buff_start..buff_end).unwrap().into());

TLKDataEntry {
entry: *entry,
Expand Down
31 changes: 19 additions & 12 deletions models/src/twoda.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use serde::Serialize;

use crate::common::fixed_char_array::FixedCharSlice;
use crate::common::header::Header;
use crate::common::varriable_char_array::{VarriableCharArray, DEFAULT};
use crate::common::varriable_char_array::VarriableCharArray;
use crate::model::Model;
use crate::resources::utils::row_parser;
use crate::tlk::Lookup;
Expand Down Expand Up @@ -46,13 +46,22 @@ impl Model for TwoDA {
}
end = row_end;
}

let signature = if let Some(_) = headers.first() {
FixedCharSlice::<3>::from(&buffer[0..3])
} else {
FixedCharSlice::<3>::default()
};
let version = match headers.last() {
Some(x) if FixedCharSlice::<4>::try_from(x).is_ok() => {
FixedCharSlice::<4>::try_from(x).unwrap()
}
_ => FixedCharSlice::<4>::from(signature.0.as_ref()),
};
let header = Header { signature, version };

Self {
header: Header {
signature: FixedCharSlice::<3>::try_from(headers.first().unwrap_or(DEFAULT))
.unwrap_or_else(|_| "2DA".into()),
version: FixedCharSlice::<4>::try_from(headers.last().unwrap_or(DEFAULT))
.unwrap_or_default(),
},
header,
default_value: default_values.first().unwrap().clone(),
data_entries: DataEntry {
data_entry_headers,
Expand All @@ -73,8 +82,6 @@ impl Model for TwoDA {
#[cfg(test)]
mod tests {

use crate::common::varriable_char_array::DEFAULT;

use super::*;
use std::{
fs::File,
Expand Down Expand Up @@ -102,12 +109,12 @@ mod tests {
item.data_entries
.data_entry_headers
.first()
.unwrap_or(DEFAULT)
.unwrap()
.to_string(),
"VALUE"
);
let last_values = item.data_entries.values.last().unwrap();
assert_eq!(last_values.first().unwrap_or(DEFAULT).to_string(), "SHAMAN");
assert_eq!(last_values.last().unwrap_or(DEFAULT).to_string(), "-1");
assert_eq!(last_values.first().unwrap().to_string(), "SHAMAN");
assert_eq!(last_values.last().unwrap().to_string(), "-1");
}
}
Loading