@@ -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
80113impl < 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}
0 commit comments