Skip to content

Commit 495b554

Browse files
committed
feat: add PropertyExt::meta() + meta to Optional
1 parent 08ffd5e commit 495b554

File tree

12 files changed

+145
-37
lines changed

12 files changed

+145
-37
lines changed

crates/ltk_meta/src/property/enum.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use enum_dispatch::enum_dispatch;
22

33
use crate::{
44
property::{Kind, NoMeta},
5-
traits::{ReadProperty as _, WriteProperty as _},
5+
traits::{PropertyExt, ReadProperty as _, WriteProperty as _},
66
Error,
77
};
88
use std::io;
@@ -50,10 +50,9 @@ macro_rules! create_enum {
5050
)]
5151
#[cfg_attr(feature = "serde", serde(tag = "kind", content = "value"))]
5252
#[derive(Clone, Debug, PartialEq)]
53-
#[enum_dispatch(PropertyExt)]
5453
/// The value part of a [`super::BinProperty`]. Holds the type of the value, and the value itself.
5554
pub enum PropertyValueEnum<M = NoMeta> {
56-
$( $variant (pub self::$variant<M>), )*
55+
$( $variant (self::$variant<M>), )*
5756
}
5857

5958

@@ -87,7 +86,35 @@ macro_rules! create_enum {
8786
$(Self::$variant(_) => Kind::$variant,)*
8887
}
8988
}
89+
9090
}
91+
92+
impl<M> PropertyExt for PropertyValueEnum<M> {
93+
type Meta = M;
94+
fn meta(&self) -> &Self::Meta {
95+
match self {
96+
$(Self::$variant(i) => i.meta(),)*
97+
}
98+
}
99+
fn size(&self, include_header: bool) -> usize {
100+
match self {
101+
$(Self::$variant(i) => i.size(include_header),)*
102+
}
103+
}
104+
fn size_no_header(&self) -> usize {
105+
match self {
106+
$(Self::$variant(i) => i.size_no_header(),)*
107+
}
108+
}
109+
}
110+
111+
$(
112+
impl<M> From<values::$variant<M>> for PropertyValueEnum<M> {
113+
fn from(other: values::$variant<M>) -> Self {
114+
Self::$variant(other)
115+
}
116+
}
117+
)*
91118
};
92119
}
93120

crates/ltk_meta/src/property/values/container.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ macro_rules! define_container_enum {
4242
})*
4343
}
4444
}
45+
46+
type Meta = M;
47+
fn meta(&self) -> &Self::Meta {
48+
match &self {
49+
$(Self::$variant{meta,..} => {
50+
meta
51+
})*
52+
}
53+
}
4554
}
4655

4756
$(

crates/ltk_meta/src/property/values/container/iter.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66

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

1111
fn next(&mut self) -> Option<Self::Item> {
1212
self.0.next()
@@ -39,7 +39,7 @@ macro_rules! define_dyn_iter {
3939
}
4040

4141
impl<'a, M> Iterator for ItemsDynInner<'a, M> {
42-
type Item = &'a dyn PropertyValueDyn;
42+
type Item = &'a dyn PropertyValueDyn<Meta = M>;
4343

4444
fn next(&mut self) -> Option<Self::Item> {
4545
match self {

crates/ltk_meta/src/property/values/embedded.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ impl<M> PropertyExt for Embedded<M> {
2121
fn size_no_header(&self) -> usize {
2222
self.0.size_no_header()
2323
}
24+
type Meta = M;
25+
fn meta(&self) -> &Self::Meta {
26+
self.0.meta()
27+
}
2428
}
2529

2630
impl<M: Default> ReadProperty for Embedded<M> {

crates/ltk_meta/src/property/values/map.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ impl<M> PropertyExt for Map<M> {
141141
.map(|(k, v)| k.size_no_header() + v.size_no_header())
142142
.sum::<usize>()
143143
}
144+
145+
type Meta = M;
146+
fn meta(&self) -> &Self::Meta {
147+
&self.meta
148+
}
144149
}
145150

146151
impl<M: Default> ReadProperty for Map<M> {

crates/ltk_meta/src/property/values/none.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ impl<M> PropertyExt for None<M> {
1919
fn size_no_header(&self) -> usize {
2020
0
2121
}
22+
23+
type Meta = M;
24+
fn meta(&self) -> &Self::Meta {
25+
&self.meta
26+
}
2227
}
2328

2429
impl<M: Default> ReadProperty for None<M> {

crates/ltk_meta/src/property/values/optional.rs

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ macro_rules! construct_enum {
1414
)]
1515
#[derive(Clone, PartialEq, Debug)]
1616
pub enum Optional<M = NoMeta> {
17-
$($variant(Option<values::$variant<M>>),)*
17+
$($variant{
18+
value: Option<values::$variant<M>>,
19+
meta: M
20+
},)*
1821
}
1922

2023
impl<M: Default> Optional<M> {
@@ -23,7 +26,7 @@ macro_rules! construct_enum {
2326
/// Helper function to create an empty [`Optional`], if the property kind can be stored in one.
2427
pub fn empty(kind: Kind) -> Option<Self> {
2528
Some(match kind {
26-
$(Kind::$variant => Self::$variant(None),)*
29+
$(Kind::$variant => Self::$variant{value: None, meta: M::default()},)*
2730
_ => return None
2831
})
2932
}
@@ -32,43 +35,73 @@ macro_rules! construct_enum {
3235
impl<M> PropertyExt for Optional<M> {
3336
fn size_no_header(&self) -> usize {
3437
2 + match &self {
35-
$(Self::$variant(inner) => inner.as_ref().map(|i| i.size_no_header()).unwrap_or_default(),)*
38+
$(Self::$variant{value, ..} => value.as_ref().map(|i| i.size_no_header()).unwrap_or_default(),)*
3639
}
3740
}
41+
type Meta = M;
42+
fn meta(&self) -> &Self::Meta {
43+
match &self {
44+
$(Self::$variant{meta, ..} => meta,)*
45+
}
46+
47+
}
3848
}
3949

4050
$(
4151
impl<M: Default> From<Option<values::$variant<M>>> for Optional<M> {
4252
fn from(other: Option<values::$variant<M>>) -> Self {
43-
Self::$variant(other)
53+
Self::$variant{value: other, meta: M::default()}
4454
}
4555

4656
}
4757
)*
4858
$(
4959
impl<M: Default> From<values::$variant<M>> for Optional<M> {
5060
fn from(other: values::$variant<M>) -> Self {
51-
Self::$variant(Some(other))
61+
Self::$variant{value: Some(other), meta: M::default()}
5262
}
5363

5464
}
5565
)*
5666

57-
impl<M: Default> Optional<M> {
58-
pub fn new(item_kind: Kind, value: Option<PropertyValueEnum<M>>) -> Result<Self, Error> {
67+
impl<M> Optional<M> {
68+
#[inline(always)]
69+
pub fn new(item_kind: Kind, value: Option<PropertyValueEnum<M>>) -> Result<Self, Error> where M: Default {
70+
Self::new_with_meta(item_kind, value, M::default())
71+
}
72+
#[inline(always)]
73+
pub fn new_with_meta(item_kind: Kind, value: Option<PropertyValueEnum<M>>, meta: M) -> Result<Self, Error> {
5974
match item_kind {
6075
$(Kind::$variant => match value {
61-
Some(PropertyValueEnum::$variant(inner)) => Ok(Self::$variant(Some(inner))),
62-
None => Ok(Self::$variant(None)),
76+
Some(PropertyValueEnum::$variant(inner)) => Ok(Self::$variant{value: Some(inner), meta}),
77+
None => Ok(Self::$variant{value: None, meta}),
6378
Some(value) => Err(Error::MismatchedContainerTypes {expected: item_kind, got: value.kind()}),
6479
},)*
6580
kind => Err(Error::InvalidNesting(kind)),
6681
}
6782
}
6883

69-
pub fn into_inner(self) -> Option<PropertyValueEnum<M>> {
84+
#[inline(always)]
85+
#[must_use]
86+
pub fn into_parts(self) -> (Option<PropertyValueEnum<M>>, M) {
87+
match self {
88+
$(Optional::$variant{ value, meta } => (value.map(PropertyValueEnum::$variant), meta),)*
89+
}
90+
}
91+
92+
#[inline(always)]
93+
#[must_use]
94+
pub fn is_some(&self) -> bool {
95+
match self {
96+
$(Self::$variant{value,..} => value.is_some(),)*
97+
}
98+
}
99+
100+
#[inline(always)]
101+
#[must_use]
102+
pub fn is_none(&self) -> bool {
70103
match self {
71-
$(Optional::$variant(item) => item.map(PropertyValueEnum::$variant),)*
104+
$(Self::$variant{value,..} => value.is_none(),)*
72105
}
73106
}
74107
}
@@ -79,7 +112,10 @@ container_variants!(construct_enum);
79112

80113
impl<M: Default> Default for Optional<M> {
81114
fn default() -> Self {
82-
Self::None(None)
115+
Self::None {
116+
value: None,
117+
meta: M::default(),
118+
}
83119
}
84120
}
85121

@@ -97,16 +133,11 @@ impl<M> Optional<M> {
97133
container_variants!(property_kinds, (self))
98134
}
99135

100-
#[inline(always)]
101-
#[must_use]
102-
pub fn is_some(&self) -> bool {
103-
match_property!(self, inner => inner.is_some())
136+
pub fn into_inner(self) -> Option<PropertyValueEnum<M>> {
137+
self.into_parts().0
104138
}
105-
106-
#[inline(always)]
107-
#[must_use]
108-
pub fn is_none(&self) -> bool {
109-
match_property!(self, inner => inner.is_none())
139+
pub fn into_meta(self) -> M {
140+
self.into_parts().1
110141
}
111142
}
112143

@@ -132,8 +163,8 @@ impl<M: Default> ReadProperty for Optional<M> {
132163
match $value {
133164
$(
134165
Kind::$variant => match is_some {
135-
true => values::$variant::from_reader(reader, legacy).map(Some).map(Self::$variant),
136-
false => Ok(Self::$variant(None)),
166+
true => Ok(values::$variant::from_reader(reader, legacy)?.into()),
167+
false => Ok(Self::empty_const::<values::$variant<M>>()),
137168
},
138169
)*
139170
kind => { return Err(Error::InvalidNesting(kind)) }
@@ -156,14 +187,19 @@ impl<M> WriteProperty for Optional<M> {
156187
writer.write_property_kind(self.item_kind())?;
157188
writer.write_bool(self.is_some())?;
158189

159-
match_property!(
160-
self,
161-
Some(inner) => {
162-
inner.to_writer(writer, legacy)?;
163-
},
164-
_ => {}
165-
);
190+
macro_rules! write_inner {
191+
(($value:expr)
192+
[$( $variant:ident, )*]) => {
193+
match $value {
194+
$(
195+
Self::$variant{value: Some(value),..} => value.to_writer(writer, legacy),
196+
197+
)*
198+
_ => { Ok(()) }
199+
}
200+
};
201+
}
166202

167-
Ok(())
203+
container_variants!(write_inner, (self))
168204
}
169205
}

crates/ltk_meta/src/property/values/primitives.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ macro_rules! impl_prim {
3232
fn size_no_header(&self) -> usize {
3333
core::mem::size_of::<$rust>()
3434
}
35+
36+
type Meta = M;
37+
fn meta(&self) -> &Self::Meta {
38+
&self.meta
39+
}
3540
}
3641

3742
impl<M> PropertyValueExt for $name<M> {

crates/ltk_meta/src/property/values/string.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ impl<M> PropertyExt for String<M> {
3535
fn size_no_header(&self) -> usize {
3636
self.value.len() + 2
3737
}
38+
39+
type Meta = M;
40+
fn meta(&self) -> &Self::Meta {
41+
&self.meta
42+
}
3843
}
3944

4045
impl<M: Default> ReadProperty for String<M> {

crates/ltk_meta/src/property/values/struct.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ impl<M> PropertyExt for Struct<M> {
3232
_ => 10 + self.properties.values().map(|p| p.size()).sum::<usize>(),
3333
}
3434
}
35+
36+
type Meta = M;
37+
fn meta(&self) -> &Self::Meta {
38+
&self.meta
39+
}
3540
}
3641

3742
impl<M: Default> ReadProperty for Struct<M> {

0 commit comments

Comments
 (0)