structural/macros/
enum_derivation.rs

1/// For creating a raw pointer of an enum field,as either `Some(NonNull<_>)` or `None`.
2///
3/// # Safety
4///
5/// The `$pointer` must be raw pointer to a valid(and fully initialized)
6/// instance of the `$enum` type.
7///
8/// # Example
9///
10/// For an example of using this macro look at
11/// [the manual implementation example for `GetVariantFieldMut`
12/// ](./field/trait.GetVariantFieldMut.html#manual-impl-example)
13#[macro_export]
14macro_rules! z_raw_borrow_enum_field {
15    (
16        $pointer:expr,
17        $enum:ident::$variant:ident.$field:tt : $field_ty:ty
18    ) => {{
19        match *$pointer {
20            $enum::$variant {
21                $field: ref mut field,
22                ..
23            } => {
24                if false {
25                    let _: *mut $field_ty = field;
26                }
27                let ptr = field as *mut $field_ty;
28                Some($crate::pmr::NonNull::new_unchecked(ptr))
29            }
30            #[allow(unreachable_patterns)]
31            _ => None,
32        }
33    }};
34}
35
36/// Implements the [`get_vfield_raw_mut_fn`] and [`get_vfield_raw_mut_unchecked_fn`]
37/// methods from the [`GetVariantFieldMut`] trait.
38///
39/// # Safety
40///
41/// The `$Self` argument must be the `Self` type in the impl block.
42///
43/// # Example
44///
45/// For an example of using this macro look at
46/// [the manual implementation example
47/// ](./field/trait.GetVariantFieldMut.html#manual-impl-example)
48/// for [`GetVariantFieldMut`]
49///
50/// [`GetVariantFieldMut`]: ./field/trait.GetVariantFieldMut.html
51/// [`get_vfield_raw_mut_fn`]:
52/// ./field/trait.GetVariantFieldMut.html#tymethod.get_vfield_raw_mut_fn
53/// [`get_vfield_raw_mut_unchecked_fn`]:
54/// ./field/trait.GetVariantFieldMut.html#tymethod.get_vfield_raw_mut_unchecked_fn
55#[macro_export]
56macro_rules! z_unsafe_impl_get_vfield_raw_mut_fn {
57    (
58        Self=$Self:ty,
59        variant_tstr=$variant_name:ty,
60        field_tstr=$field_name:ty,
61        field_type=$field_ty:ty,
62    ) => {
63        fn get_vfield_raw_mut_fn(
64            &self,
65        ) -> $crate::pmr::GetVFieldRawMutFn<$variant_name, $field_name, $field_ty> {
66            <$Self as
67                        $crate::pmr::GetVariantFieldMut<$variant_name,$field_name>
68                    >::get_vfield_raw_mut_
69        }
70
71        fn get_vfield_raw_mut_unchecked_fn(
72            &self,
73        ) -> $crate::pmr::GetFieldRawMutFn<$field_name, $field_ty> {
74            <$Self as
75                                        $crate::pmr::GetVariantFieldMut<$variant_name, $field_name>
76                                    >::get_vfield_raw_mut_unchecked
77        }
78    };
79}
80
81/// Implements enum variant+field getter(s)
82#[doc(hidden)]
83#[macro_export]
84macro_rules! _private_impl_getter_enum{
85    ////////////////////////////////////////////////////////////////////////////
86    ////            All the ways to implement GetVariantField
87    ////////////////////////////////////////////////////////////////////////////
88    (
89        GetVariantField
90        shared(
91            impl[$($typarams:tt)*] $self_:ty
92            where[$($where_:tt)*]
93
94            enum=$enum_:ident
95            variant=$variant:ident
96            variant_name($variant_name_str:ty)
97        )
98        newtype(
99            $field_name:tt : $field_ty:ty,
100            dropping $dropping:tt
101            $(,$field_name_param:ty)? $( , )*
102        )
103    )=>{
104        impl<$($typarams)* __F>
105            $crate::FieldType< $crate::VariantField<$variant_name_str,__F> >
106        for $self_
107        where
108            $field_ty: $crate::GetField<__F>,
109            $($where_)*
110        {
111            type Ty=$crate::GetFieldType<$field_ty,__F>;
112        }
113
114        unsafe impl<$($typarams)* __F,__Ty>
115            $crate::pmr::GetVariantField<$variant_name_str,__F>
116        for $self_
117        where
118            $field_ty: $crate::GetField<__F,Ty=__Ty>,
119            $($where_)*
120        {
121            #[inline(always)]
122            fn get_vfield_(
123                &self,
124                _:$variant_name_str,
125                fname:__F
126            )->Option<&__Ty>{
127                match self {
128                    $enum_::$variant{$field_name:field,..}=>{
129                        Some($crate::GetField::get_field_(field,fname))
130                    }
131                    #[allow(unreachable_patterns)]
132                    _=>None,
133                }
134            }
135        }
136    };
137    (
138        GetVariantField
139        shared(
140            impl[$($typarams:tt)*] $self_:ty
141            where[$($where_:tt)*]
142
143            enum=$enum_:ident
144            variant=$variant:ident
145            variant_name($variant_name_str:ty)
146        )
147        regular(
148            $field_name:tt : $field_ty:ty,
149            dropping $dropping:tt,
150            $field_name_param:ty $( , )*
151        )
152    )=>{
153
154        impl<$($typarams)*>
155            $crate::FieldType<
156                $crate::VariantField<$variant_name_str,$field_name_param>
157            >
158        for $self_
159        where
160            $($where_)*
161        {
162            type Ty=$field_ty;
163        }
164
165        unsafe impl<$($typarams)*>
166            $crate::pmr::GetVariantField<$variant_name_str,$field_name_param>
167        for $self_
168        where
169            $($where_)*
170        {
171            #[inline(always)]
172            fn get_vfield_(
173                &self,
174                _:$variant_name_str,
175                _:$field_name_param,
176            )->Option<&$field_ty>{
177                match self {
178                    $enum_::$variant{$field_name:field,..}=>
179                        Some(field),
180                    #[allow(unreachable_patterns)]
181                    _=>None
182                }
183            }
184        }
185    };
186
187    ////////////////////////////////////////////////////////////////////////////
188    ////            All the ways to implement GetVariantFieldMut
189    ////////////////////////////////////////////////////////////////////////////
190    (
191        GetVariantFieldMut
192        shared(
193            impl[$($typarams:tt)*] $self_:ty
194            where[$($where_:tt)*]
195
196            enum=$enum_:ident
197            variant=$variant:ident
198            variant_name($variant_name_str:ty)
199        )
200        newtype(
201            $field_name:tt : $field_ty:ty,
202            dropping $dropping:tt
203            $(,$field_name_param:ty)? $( , )*
204        )
205    )=>{
206        unsafe impl<$($typarams)* __F,__Ty>
207            $crate::GetVariantFieldMut<$variant_name_str,__F>
208        for $self_
209        where
210            $field_ty: $crate::GetFieldMut<__F,Ty=__Ty>,
211            $($where_)*
212        {
213            #[inline(always)]
214            fn get_vfield_mut_(
215                &mut self,
216                _: $variant_name_str,
217                name: __F,
218            )->Option<&mut __Ty>{
219                match self {
220                    $enum_::$variant{$field_name:field,..}=>
221                        Some($crate::GetFieldMut::get_field_mut_(field,name)),
222                    #[allow(unreachable_patterns)]
223                    _=>None
224                }
225            }
226
227            #[inline(always)]
228            unsafe fn get_vfield_raw_mut_(
229                this:*mut  (),
230                _:$variant_name_str,
231                name:__F,
232            )->Option<$crate::pmr::NonNull<__Ty>> {
233                match *(this as *mut  Self) {
234                    $enum_::$variant{$field_name:ref mut field,..}=>{
235                        let field=field as *mut $field_ty as *mut  ();
236                        let ptr=<$field_ty as $crate::GetFieldMut<__F>>::get_field_raw_mut(
237                            field,
238                            name,
239                        );
240                        // Safety:
241                        // Calling `NonNull::new_unchecked` because the pointer returned by
242                        // `get_field_raw_mut` must be valid.
243                        Some($crate::pmr::NonNull::new_unchecked(ptr))
244                    }
245                    #[allow(unreachable_patterns)]
246                    _=>None
247                }
248            }
249
250            #[inline(always)]
251            fn get_vfield_raw_mut_fn(
252                &self,
253            )->$crate::pmr::GetVFieldRawMutFn<
254                $variant_name_str,
255                __F,
256                __Ty,
257            >{
258                <Self as $crate::GetVariantFieldMut<$variant_name_str,__F>>::get_vfield_raw_mut_
259            }
260
261            #[inline(always)]
262            fn get_vfield_raw_mut_unchecked_fn(
263                &self,
264            )->$crate::pmr::GetFieldRawMutFn<
265                __F,
266                __Ty,
267            >{
268                <Self as
269                    $crate::GetVariantFieldMut<$variant_name_str,__F>
270                >::get_vfield_raw_mut_unchecked
271            }
272        }
273
274
275    };
276    (
277        GetVariantFieldMut
278        shared(
279            impl[$($typarams:tt)*] $self_:ty
280            where[$($where_:tt)*]
281
282            enum=$enum_:ident
283            variant=$variant:ident
284            variant_name($variant_name_str:ty)
285        )
286        regular(
287            $field_name:tt : $field_ty:ty,
288            dropping $dropping:tt,
289            $field_name_param:ty $( , )*
290        )
291    )=>{
292        unsafe impl<$($typarams)*>
293            $crate::GetVariantFieldMut<$variant_name_str,$field_name_param>
294        for $self_
295        where
296            $($where_)*
297        {
298            #[inline(always)]
299            fn get_vfield_mut_(
300                &mut self,
301                _: $variant_name_str,
302                _: $field_name_param,
303            )->Option<&mut $field_ty>{
304                match self {
305                    $enum_::$variant{$field_name:field,..}=>Some(field),
306                    #[allow(unreachable_patterns)]
307                    _=>None
308                }
309            }
310
311            #[inline(always)]
312            unsafe fn get_vfield_raw_mut_(
313                this:*mut  (),
314                _:$variant_name_str,
315                _:$field_name_param,
316            )->Option<$crate::pmr::NonNull<$field_ty>> {
317                $crate::z_raw_borrow_enum_field!(
318                    this as *mut  Self,
319                    $enum_::$variant.$field_name : $field_ty
320                )
321            }
322
323            #[inline(always)]
324            fn get_vfield_raw_mut_fn(
325                &self,
326            )->$crate::pmr::GetVFieldRawMutFn<
327                $variant_name_str,
328                $field_name_param,
329                $field_ty,
330            >{
331                <Self as
332                    $crate::GetVariantFieldMut<$variant_name_str,$field_name_param>
333                >::get_vfield_raw_mut_
334            }
335
336            #[inline(always)]
337            fn get_vfield_raw_mut_unchecked_fn(
338                &self,
339            )->$crate::pmr::GetFieldRawMutFn<
340                $field_name_param,
341                $field_ty,
342            >{
343                <Self as
344                    $crate::GetVariantFieldMut<$variant_name_str,$field_name_param>
345                >::get_vfield_raw_mut_unchecked
346            }
347        }
348    };
349    ////////////////////////////////////////////////////////////////////////////
350    ////            All the ways to implement IntoVariantField
351    ////////////////////////////////////////////////////////////////////////////
352    (
353        IntoVariantField
354        shared(
355            impl[$($typarams:tt)*] $self_:ty
356            where[$($where_:tt)*]
357
358            enum=$enum_:ident
359            variant=$variant:ident
360            variant_name($variant_name_str:ty)
361        )
362        newtype(
363            $field_name:tt : $field_ty:ty,
364            dropping($field_var:ident, $field_index:expr)
365            $(,$field_name_param:ty)? $( , )*
366        )
367    )=>{
368        unsafe impl<$($typarams)* __F,__Ty>
369            $crate::pmr::IntoVariantField<$variant_name_str,__F>
370        for $self_
371        where
372            $field_ty: $crate::IntoField<__F,Ty=__Ty>,
373            Self: $crate::pmr::DropFields,
374            $($where_)*
375        {
376            #[inline(always)]
377            fn into_vfield_(self, _:$variant_name_str, name:__F) -> Option<Self::Ty> {
378                match self {
379                    $enum_::$variant{$field_name:field,..}=>{
380                        Some($crate::IntoField::into_field_(field,name))
381                    }
382                    #[allow(unreachable_patterns)]
383                    _=>None
384                }
385            }
386
387            #[inline(always)]
388            unsafe fn move_out_vfield_(
389                &mut self,
390                _:$variant_name_str,
391                name:__F,
392                moved_fields: &mut $crate::pmr::MovedOutFields,
393            ) -> Option<Self::Ty> {
394                match self {
395                    $enum_::$variant{$field_name:field,..}=>{
396                        Some($crate::IntoField::move_out_field_(field,name,moved_fields))
397                    }
398                    #[allow(unreachable_patterns)]
399                    _=>None
400                }
401            }
402        }
403    };
404    (
405        IntoVariantField
406        shared(
407            impl[$($typarams:tt)*] $self_:ty
408            where[$($where_:tt)*]
409
410            enum=$enum_:ident
411            variant=$variant:ident
412            variant_name($variant_name_str:ty)
413        )
414        regular(
415            $field_name:tt : $field_ty:ty,
416            dropping($field_var:ident, $field_index:expr),
417            $field_name_param:ty $( , )*
418        )
419    )=>{
420        unsafe impl<$($typarams)*>
421            $crate::pmr::IntoVariantField<$variant_name_str,$field_name_param>
422        for $self_
423        where
424            Self: $crate::pmr::DropFields,
425            $($where_)*
426        {
427            #[inline(always)]
428            fn into_vfield_(self, _:$variant_name_str, _:$field_name_param)->Option<$field_ty>{
429                match self {
430                    $enum_::$variant{$field_name:field,..}=>Some(field),
431                    #[allow(unreachable_patterns)]
432                    _=>None
433                }
434            }
435
436            #[inline(always)]
437            unsafe fn move_out_vfield_(
438                &mut self,
439                _:$variant_name_str,
440                _:$field_name_param,
441                moved_fields: &mut $crate::pmr::MovedOutFields,
442            )->Option<$field_ty>{
443                match self {
444                    $enum_::$variant{$field_name:field,..}=>{
445                        {
446                            use $crate::pmr::FieldBit;
447                            const BIT: FieldBit = FieldBit::new($field_index);
448                            moved_fields.set_moved_out(BIT);
449                        }
450                        Some((field as *mut $field_ty).read())
451                    },
452                    #[allow(unreachable_patterns)]
453                    _=>None
454                }
455            }
456        }
457    };
458    ////////////////////////////////////////////////////////////////////////////
459    ////                delegate_to
460    ////////////////////////////////////////////////////////////////////////////
461    (
462        shared $shared:tt
463        kind=$kind:tt
464
465        delegate_to( GetVariantField, $($field_params:tt)* )
466    )=>{
467        $crate::_private_impl_getter_enum!{
468            GetVariantField
469            shared $shared
470            $kind($($field_params)*)
471        }
472    };
473    (
474        shared $shared:tt
475        kind=$kind:tt
476        delegate_to( GetVariantFieldMut, $($field_params:tt)* )
477    )=>{
478        $crate::_private_impl_getter_enum!{
479            GetVariantField
480            shared $shared
481            $kind($($field_params)*)
482        }
483        $crate::_private_impl_getter_enum!{
484            GetVariantFieldMut
485            shared $shared
486            $kind($($field_params)*)
487        }
488    };
489    (
490        shared $shared:tt
491        kind=$kind:tt
492        delegate_to( IntoVariantField, $($field_params:tt)* )
493    )=>{
494        $crate::_private_impl_getter_enum!{
495            GetVariantField
496            shared $shared
497            $kind($($field_params)*)
498        }
499        $crate::_private_impl_getter_enum!{
500            IntoVariantField
501            shared $shared
502            $kind($($field_params)*)
503        }
504    };
505    (
506        shared $shared:tt
507        kind=$kind:tt
508        delegate_to( IntoVariantFieldMut, $($field_params:tt)* )
509    )=>{
510        $crate::_private_impl_getter_enum!{
511            GetVariantField
512            shared $shared
513            $kind($($field_params)*)
514        }
515        $crate::_private_impl_getter_enum!{
516            GetVariantFieldMut
517            shared $shared
518            $kind($($field_params)*)
519        }
520        $crate::_private_impl_getter_enum!{
521            IntoVariantField
522            shared $shared
523            $kind($($field_params)*)
524        }
525    };
526    (
527        $trait_:ident
528        shared $shared:tt
529        newtype_as_field(
530            shared (
531                impl[$($typarams:tt)*] $self_:ty
532                where[$($where_:tt)*]
533
534                enum=$enum_:ident
535                variant=$variant:ident
536                variant_name($variant_name_str:ty)
537            )
538
539            $($field_params:tt)*
540        )
541    )=>{
542        $crate::_private_impl_getter_enum!{
543            $trait_
544            shared $shared
545            newtype(
546                $($field_params)*
547            )
548        }
549    };
550    ////////////////////////////////////////////////////////////////////////////
551    ////                variants code
552    ////////////////////////////////////////////////////////////////////////////
553    (
554        shared $shared:tt
555        kind=newtype
556        fields(
557            (
558                $trait_:ident,
559                $field_name:tt : $field_ty:ty,
560                dropping $dropping:tt
561                $(,$field_name_param:ty)? $( , )*
562            )
563        )
564    )=>{
565        $crate::_private_impl_getter_enum!{
566            shared $shared
567            kind=newtype_as_field
568            delegate_to(
569                $trait_,
570
571                shared $shared
572
573                $field_name : $field_ty, dropping $dropping $(,$field_name_param)?
574            )
575        }
576    };
577
578    (
579        shared $shared:tt
580        kind=regular
581        fields( $($fields:tt)* )
582    )=>{
583        $(
584            $crate::_private_impl_getter_enum!{
585                shared $shared
586                kind=regular
587                delegate_to $fields
588            }
589        )*
590    };
591}
592
593#[doc(hidden)]
594#[macro_export]
595macro_rules! _private_impl_getters_for_derive_enum{
596    (
597        $(#[doc=$docs:literal])*
598        impl $typarams:tt $self_:ty
599        where $where_preds:tt
600        {
601            enum=$enum_:ident
602            drop_fields=$drop_kind:tt
603            $(variant_count=$variant_count:ty,)?
604            $((
605                $variant:ident,
606                $variant_tstr:ty,
607                kind=$variant_kind:ident,
608                not_public( $(($priv_field:tt = $priv_field_var:ident))* ),
609                fields($( $field:tt )*)
610            ))*
611        }
612
613    )=>{
614
615        $crate::_private_impl_structural!{
616            $(#[doc=$docs])*
617            impl $typarams Structural for $self_
618            where $where_preds
619        }
620
621        $(
622            $crate::_private_impl_getter_enum!{
623                shared(
624                    impl $typarams $self_
625                    where $where_preds
626
627                    enum=$enum_
628                    variant=$variant
629                    variant_name($variant_tstr)
630                )
631                kind= $variant_kind
632                fields(
633                    $( $field )*
634                )
635            }
636
637            $crate::_private_impl_getters_for_derive_enum!{
638                @impl_is_variant
639                impl $typarams $self_
640                where $where_preds
641
642                enum=$enum_
643                variant=$variant
644                variant_name($variant_tstr)
645            }
646        )*
647
648        $crate::_private_impl_drop_fields!{
649            struct_or_enum(enum),
650            for_drop=$drop_kind
651
652            impl $typarams DropFields for $self_
653            where $where_preds
654            {
655                $(
656                    $variant(
657                        kind=$variant_kind,
658
659                        not_public( $(($priv_field = $priv_field_var))* ),
660
661                        fields( $( $field )* ),
662                    )
663                )*
664            }
665        }
666
667
668        $(
669            $crate::_private_impl_getters_for_derive_enum!{
670                @inner
671                impl $typarams $self_
672                where $where_preds
673
674                variant_count=$variant_count,
675            }
676        )?
677    };
678    (@inner
679        impl[$($typarams:tt)*] $self_:ty
680        where[$($where_:tt)*]
681        variant_count=$variant_count:ty,
682    )=>{
683        unsafe impl<$($typarams)*> $crate::pmr::VariantCount for $self_
684        where
685            $($where_)*
686        {
687            type Count=$variant_count;
688        }
689    };
690    (@impl_is_variant
691        impl[$($typarams:tt)*] $self_:ty
692        where[$($where_:tt)*]
693
694        enum=$enum_:ident
695        variant=$variant:ident
696        variant_name($variant_name_str:ty)
697    )=>{
698        unsafe impl<$($typarams)*>
699            $crate::pmr::IsVariant<$variant_name_str>
700        for $self_
701        where $($where_)*
702        {
703            #[inline]
704            #[allow(unreachable_patterns)]
705            fn is_variant_(&self,_:$variant_name_str)->bool{
706                match self {
707                    $enum_::$variant{..}=>true,
708                    #[allow(unreachable_patterns)]
709                    _=>false,
710                }
711            }
712        }
713    };
714}