Skip to content
Draft
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
6 changes: 3 additions & 3 deletions crates/ltk_meta/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ for (path_hash, object) in &tree.objects {

```
use ltk_meta::{Bin, BinObject};
use ltk_meta::property::values;
use ltk_meta::property::{values, NoMeta};

// Using the builder pattern
let tree = Bin::builder()
.dependency("common.bin")
.object(
BinObject::builder(0x12345678, 0xABCDEF00)
BinObject::<NoMeta>::builder(0x12345678, 0xABCDEF00)
.property(0x1111, values::I32::new(42))
.property(0x2222, values::String::from("hello"))
.build()
Expand Down Expand Up @@ -70,7 +70,7 @@ tree.to_writer(&mut output)?;
```
*/
pub mod property;
pub use property::{BinProperty, Kind as PropertyKind, PropertyValueEnum};
pub use property::{Kind as PropertyKind, PropertyValueEnum};

mod tree;
pub use tree::*;
Expand Down
42 changes: 0 additions & 42 deletions crates/ltk_meta/src/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,8 @@ pub use kind::*;
mod r#enum;
pub use r#enum::*;

use super::traits::{ReaderExt as _, WriterExt as _};
use super::Error;
use byteorder::{ReadBytesExt as _, WriteBytesExt as _, LE};
use std::io;

use crate::traits::PropertyExt;

#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NoMeta;

#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, PartialEq, Debug)]
pub struct BinProperty {
pub name_hash: u32,
#[cfg_attr(feature = "serde", serde(flatten))]
pub value: PropertyValueEnum,
}

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<R: io::Read + std::io::Seek + ?Sized>(
reader: &mut R,
legacy: bool,
) -> Result<Self, Error> {
let name_hash = reader.read_u32::<LE>()?;
let kind = reader.read_property_kind(legacy)?;

Ok(Self {
name_hash,
value: PropertyValueEnum::from_reader(reader, kind, legacy)?,
})
}
pub fn to_writer<W: io::Write + std::io::Seek + ?Sized>(
&self,
writer: &mut W,
) -> Result<(), io::Error> {
writer.write_u32::<LE>(self.name_hash)?;
writer.write_property_kind(self.value.kind())?;

self.value.to_writer(writer)?;
Ok(())
}
pub fn size(&self) -> usize {
5 + self.value.size_no_header()
}
}
50 changes: 45 additions & 5 deletions crates/ltk_meta/src/property/enum.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use enum_dispatch::enum_dispatch;

use crate::{
property::{Kind, NoMeta},
traits::{ReadProperty as _, WriteProperty as _},
traits::{PropertyExt, ReadProperty as _, WriteProperty as _},
Error,
};
use std::io;
Expand Down Expand Up @@ -50,10 +48,9 @@ macro_rules! create_enum {
)]
#[cfg_attr(feature = "serde", serde(tag = "kind", content = "value"))]
#[derive(Clone, Debug, PartialEq)]
#[enum_dispatch(PropertyExt)]
/// The value part of a [`super::BinProperty`]. Holds the type of the value, and the value itself.
pub enum PropertyValueEnum<M = NoMeta> {
$( $variant (pub self::$variant<M>), )*
$( $variant (self::$variant<M>), )*
}


Expand Down Expand Up @@ -81,13 +78,56 @@ macro_rules! create_enum {
}
}
impl<M> PropertyValueEnum<M> {
#[inline(always)]
#[must_use]
pub fn kind(&self) -> Kind {
match self {
$(Self::$variant(_) => Kind::$variant,)*
}
}

#[inline(always)]
#[must_use]
pub fn no_meta(self) -> PropertyValueEnum<NoMeta> {
match self {
$(Self::$variant(i) => PropertyValueEnum::$variant(i.no_meta()),)*
}
}

}

impl<M> PropertyExt for PropertyValueEnum<M> {
type Meta = M;
fn meta(&self) -> &Self::Meta {
match self {
$(Self::$variant(i) => i.meta(),)*
}
}
fn meta_mut(&mut self) -> &mut Self::Meta {
match self {
$(Self::$variant(i) => i.meta_mut(),)*
}
}

fn size(&self, include_header: bool) -> usize {
match self {
$(Self::$variant(i) => i.size(include_header),)*
}
}
fn size_no_header(&self) -> usize {
match self {
$(Self::$variant(i) => i.size_no_header(),)*
}
}
}

$(
impl<M> From<values::$variant<M>> for PropertyValueEnum<M> {
fn from(other: values::$variant<M>) -> Self {
Self::$variant(other)
}
}
)*
};
}

Expand Down
60 changes: 59 additions & 1 deletion crates/ltk_meta/src/property/values/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,22 @@ macro_rules! define_container_enum {
})*
}
}

type Meta = M;
fn meta(&self) -> &Self::Meta {
match &self {
$(Self::$variant{meta,..} => {
meta
})*
}
}
fn meta_mut(&mut self) -> &mut Self::Meta {
match self {
$(Self::$variant{meta,..} => {
meta
})*
}
}
}

$(
Expand Down Expand Up @@ -108,6 +124,48 @@ macro_rules! define_container_enum {
}

impl<M> Container<M> {
#[inline(always)]
pub fn empty(item_kind: Kind) -> Result<Self, Error>
where
M: Default
{
match item_kind {
$(Kind::$variant => Ok(Self::$variant {
items: vec![],
meta: M::default(),
}),)*
kind => Err(Error::InvalidNesting(kind)),

}
}

#[inline(always)]
#[must_use]
pub fn no_meta(self) -> Container<NoMeta> {
match self {
$(Self::$variant{items,..} => {
Container::$variant {
items: items.into_iter().map(|i| i.no_meta()).collect(),
meta: NoMeta
}
})*
}
}

pub fn push(&mut self, value: PropertyValueEnum<M>) -> Result<(), Error>{
let got = value.kind();
let expected = self.item_kind();
match (self, value) {
$((Self::$variant{items,..}, PropertyValueEnum::$variant(item)) => {
items.push(item);
Ok(())
})*
_ => {
Err(Error::MismatchedContainerTypes { got, expected })
}
}
}

/// Iterator that returns each item as a [`PropertyValueEnum`] for convenience.
#[inline(always)]
#[must_use]
Expand Down Expand Up @@ -149,7 +207,7 @@ impl<M> Container<M> {
Self::from(items)
}

pub fn empty<T>() -> Self
pub fn empty_const<T>() -> Self
where
Self: From<Vec<T>>,
{
Expand Down
4 changes: 2 additions & 2 deletions crates/ltk_meta/src/property/values/container/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{

pub struct ItemsDyn<'a, M>(ItemsDynInner<'a, M>);
impl<'a, M> Iterator for ItemsDyn<'a, M> {
type Item = &'a dyn PropertyValueDyn;
type Item = &'a dyn PropertyValueDyn<Meta = M>;

fn next(&mut self) -> Option<Self::Item> {
self.0.next()
Expand Down Expand Up @@ -39,7 +39,7 @@ macro_rules! define_dyn_iter {
}

impl<'a, M> Iterator for ItemsDynInner<'a, M> {
type Item = &'a dyn PropertyValueDyn;
type Item = &'a dyn PropertyValueDyn<Meta = M>;

fn next(&mut self) -> Option<Self::Item> {
match self {
Expand Down
72 changes: 36 additions & 36 deletions crates/ltk_meta/src/property/values/container/variants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,42 +23,42 @@ macro_rules! container_variants {
};
}

macro_rules! match_property {
($value:expr, $on:ident, $inner:pat => $body:expr, $def:pat => $def_body: expr) => {
container_variants!(match_property_arms, ($value, $on, $inner => $body, $def => $def_body))
};
($value:expr, $on:ident, $inner:pat => $body:expr) => {
container_variants!(match_property_arms, ($value, $on, $inner => $body))
};

($value:expr, $inner:pat => $body:expr, $def:pat => $def_body: expr) => {
container_variants!(match_property_arms, ($value, Self, $inner => $body, $def => $def_body))
};
($value:expr, $inner:pat => $body:expr) => {
container_variants!(match_property_arms, ($value, Self, $inner => $body))
};
}

macro_rules! match_property_arms {
(($value:expr, $on:ident, $inner:pat => $body:expr, $def:pat => $def_body: expr)
[$( $variant:ident, )*]) => {
match $value {
$(
$on::$variant($inner) => $body,
)*
$def => $def_body
}
};

(($value:expr, $on:ident, $inner:pat => $body:expr)
[$( $variant:ident, )*]) => {
match $value {
$(
$on::$variant($inner) => $body,
)*
}
};
}
// macro_rules! match_property {
// ($value:expr, $on:ident, $inner:pat => $body:expr, $def:pat => $def_body: expr) => {
// container_variants!(match_property_arms, ($value, $on, $inner => $body, $def => $def_body))
// };
// ($value:expr, $on:ident, $inner:pat => $body:expr) => {
// container_variants!(match_property_arms, ($value, $on, $inner => $body))
// };
//
// ($value:expr, $inner:pat => $body:expr, $def:pat => $def_body: expr) => {
// container_variants!(match_property_arms, ($value, Self, $inner => $body, $def => $def_body))
// };
// ($value:expr, $inner:pat => $body:expr) => {
// container_variants!(match_property_arms, ($value, Self, $inner => $body))
// };
// }
//
// macro_rules! match_property_arms {
// (($value:expr, $on:ident, $inner:pat => $body:expr, $def:pat => $def_body: expr)
// [$( $variant:ident, )*]) => {
// match $value {
// $(
// $on::$variant($inner) => $body,
// )*
// $def => $def_body
// }
// };
//
// (($value:expr, $on:ident, $inner:pat => $body:expr)
// [$( $variant:ident, )*]) => {
// match $value {
// $(
// $on::$variant($inner) => $body,
// )*
// }
// };
// }

// macro_rules! match_enum_inner {
// (($value:expr, $on:ident, ||, $body:expr)
Expand Down
17 changes: 16 additions & 1 deletion crates/ltk_meta/src/property/values/embedded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ use super::Struct;
#[derive(Clone, PartialEq, Debug, Default)]
pub struct Embedded<M = NoMeta>(pub Struct<M>);

impl<M> Embedded<M> {
#[inline(always)]
#[must_use]
pub fn no_meta(self) -> Embedded<NoMeta> {
Embedded(self.0.no_meta())
}
}

impl<M> PropertyValueExt for Embedded<M> {
const KIND: Kind = Kind::Embedded;
}
Expand All @@ -21,6 +29,13 @@ impl<M> PropertyExt for Embedded<M> {
fn size_no_header(&self) -> usize {
self.0.size_no_header()
}
type Meta = M;
fn meta(&self) -> &Self::Meta {
self.0.meta()
}
fn meta_mut(&mut self) -> &mut Self::Meta {
self.0.meta_mut()
}
}

impl<M: Default> ReadProperty for Embedded<M> {
Expand All @@ -31,7 +46,7 @@ impl<M: Default> ReadProperty for Embedded<M> {
Struct::<M>::from_reader(reader, legacy).map(Self)
}
}
impl<M> WriteProperty for Embedded<M> {
impl<M: Clone> WriteProperty for Embedded<M> {
fn to_writer<R: std::io::Write + std::io::Seek + ?Sized>(
&self,
writer: &mut R,
Expand Down
Loading
Loading