Skip to content

Commit

Permalink
Remove length hint from FixedByteSize trait
Browse files Browse the repository at this point in the history
  • Loading branch information
vE5li committed Feb 21, 2024
1 parent e7533a0 commit c5aec56
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 67 deletions.
18 changes: 7 additions & 11 deletions procedural/src/byte/fixed_size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,21 @@ pub fn derive_fixed_byte_size_struct(data_struct: DataStruct, generics: Generics
syn::Fields::Unit => panic!("unit types are not supported"),
};

let length_hints = fields.into_iter().map(|mut field| {
let sizes = fields.into_iter().zip(types.iter()).map(|(mut field, field_type)| {
get_unique_attribute(&mut field.attrs, "length_hint")
.map(|attribute| match attribute.meta {
syn::Meta::List(list) => list.tokens,
syn::Meta::Path(_) | syn::Meta::NameValue(_) => panic!("expected token stream in attribute"),
})
.map(|length_hint| quote!(Some(((#length_hint) as usize))))
.unwrap_or(quote!(None))
.map(|length_hint| quote!((#length_hint) as usize))
.unwrap_or(quote!(<#field_type as crate::loaders::FixedByteSize>::size_in_bytes()))
});

quote! {
impl #impl_generics const crate::loaders::FixedByteSize for #name #type_generics #where_clause {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());

fn size_in_bytes() -> usize {
let mut total = 0;
#(total += <#types as crate::loaders::FixedByteSize>::size_in_bytes(#length_hints);)*
#(total += #sizes;)*
total
}
}
Expand All @@ -48,10 +46,8 @@ pub fn derive_fixed_byte_size_enum(generics: Generics, mut attributes: Vec<Attri

quote! {
impl #impl_generics const crate::loaders::FixedByteSize for #name #type_generics #where_clause {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());

<#numeric_type as crate::loaders::FixedByteSize>::size_in_bytes(None)
fn size_in_bytes() -> usize {
<#numeric_type as crate::loaders::FixedByteSize>::size_in_bytes()
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion procedural/src/byte/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ pub fn byte_convertable_helper(data_struct: DataStruct) -> (Vec<TokenStream>, Ve
.expect("repeating_remaining is used but no packet_length attribute is set");

quote!({
let repeat_count = (#packet_length - ((byte_stream.get_offset() - base_offset) as u16) - 2) / (<#field_type as crate::loaders::FixedByteSizeWrapper>::size_in_bytes(None) as u16);
let repeat_count = (#packet_length - ((byte_stream.get_offset() - base_offset) as u16) - 2) / (<#field_type as crate::loaders::FixedByteSizeWrapper>::size_in_bytes() as u16);
// TODO: Add check to make sure this allocation is not too big.
let mut vector = Vec::with_capacity(repeat_count as usize);

Expand Down
4 changes: 2 additions & 2 deletions src/loaders/archive/native/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ pub struct NativeArchive {

const MAGIC_BYTES: &[u8] = b"Master of Magic\0";
const UNPACKED_SIZE_OF_MAGIC_STRING: usize = MAGIC_BYTES.len();
const UNPACKED_SIZE_OF_ARCHIVEHEADER: usize = Header::size_in_bytes(None);
const UNPACKED_SIZE_OF_FILETABLE: usize = AssetTable::size_in_bytes(None);
const UNPACKED_SIZE_OF_ARCHIVEHEADER: usize = Header::size_in_bytes();
const UNPACKED_SIZE_OF_FILETABLE: usize = AssetTable::size_in_bytes();

impl Archive for NativeArchive {
fn from_path(path: &Path) -> Self {
Expand Down
80 changes: 27 additions & 53 deletions src/loaders/fixed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,144 +4,118 @@ use cgmath::{Matrix3, Quaternion, Vector2, Vector3, Vector4};

#[const_trait]
pub trait FixedByteSizeWrapper {
fn size_in_bytes(length_hint: Option<usize>) -> usize;
fn size_in_bytes() -> usize;
}

impl<T: ~const FixedByteSize> const FixedByteSizeWrapper for Vec<T> {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
T::size_in_bytes(length_hint)
fn size_in_bytes() -> usize {
T::size_in_bytes()
}
}

#[const_trait]
pub trait FixedByteSize {
fn size_in_bytes(length_hint: Option<usize>) -> usize;
fn size_in_bytes() -> usize;
}

impl const FixedByteSize for u8 {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
fn size_in_bytes() -> usize {
core::mem::size_of::<Self>()
}
}

impl const FixedByteSize for u16 {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
fn size_in_bytes() -> usize {
core::mem::size_of::<Self>()
}
}

impl const FixedByteSize for u32 {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
fn size_in_bytes() -> usize {
core::mem::size_of::<Self>()
}
}

impl const FixedByteSize for u64 {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
fn size_in_bytes() -> usize {
core::mem::size_of::<Self>()
}
}

impl const FixedByteSize for i8 {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
fn size_in_bytes() -> usize {
core::mem::size_of::<Self>()
}
}

impl const FixedByteSize for i16 {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
fn size_in_bytes() -> usize {
core::mem::size_of::<Self>()
}
}

impl const FixedByteSize for i32 {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
fn size_in_bytes() -> usize {
core::mem::size_of::<Self>()
}
}

impl const FixedByteSize for i64 {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
fn size_in_bytes() -> usize {
core::mem::size_of::<Self>()
}
}

impl const FixedByteSize for f32 {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
fn size_in_bytes() -> usize {
core::mem::size_of::<Self>()
}
}

impl const FixedByteSize for f64 {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
fn size_in_bytes() -> usize {
core::mem::size_of::<Self>()
}
}

impl<T: ~const FixedByteSize, const SIZE: usize> const FixedByteSize for [T; SIZE] {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
T::size_in_bytes(None) * SIZE
fn size_in_bytes() -> usize {
T::size_in_bytes() * SIZE
}
}

impl<T: ~const FixedByteSize> const FixedByteSize for Vector2<T> {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
T::size_in_bytes(None) * 2
fn size_in_bytes() -> usize {
T::size_in_bytes() * 2
}
}

impl<T: ~const FixedByteSize> const FixedByteSize for Vector3<T> {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
T::size_in_bytes(None) * 3
fn size_in_bytes() -> usize {
T::size_in_bytes() * 3
}
}

impl<T: ~const FixedByteSize> const FixedByteSize for Vector4<T> {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
T::size_in_bytes(None) * 4
fn size_in_bytes() -> usize {
T::size_in_bytes() * 4
}
}

impl<T: ~const FixedByteSize> const FixedByteSize for Quaternion<T> {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
T::size_in_bytes(None) * 4
fn size_in_bytes() -> usize {
T::size_in_bytes() * 4
}
}

impl<T: ~const FixedByteSize> const FixedByteSize for Matrix3<T> {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
T::size_in_bytes(None) * 9
fn size_in_bytes() -> usize {
T::size_in_bytes() * 9
}
}

impl const FixedByteSize for Ipv4Addr {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
assert!(length_hint.is_none());
fn size_in_bytes() -> usize {
4
}
}

impl const FixedByteSize for String {
fn size_in_bytes(length_hint: Option<usize>) -> usize {
match length_hint {
Some(length) => length,
None => panic!("fixed size string needs to have a length hint"),
}
}
}

0 comments on commit c5aec56

Please sign in to comment.