structural/field/
rev_get_field.rs

1/*!
2Contains traits implemented on field paths,taking Structural types as parameters.
3*/
4
5#![allow(non_snake_case)]
6
7use crate::{
8    field::{errors::IsFieldErr, FailedAccess, InfallibleAccess, MovedOutFields},
9    path::{IsSingleFieldPath, ShallowFieldPath},
10};
11
12/////////////////////////////////////////////////////////////////////////////
13
14mod components;
15mod nested_field_path;
16mod path_set_types;
17
18/////////////////////////////////////////////////////////////////////////////
19
20/// Queries the type of a nested field in This,
21/// what field is queried is determined by `FieldPath`,
22///
23/// # Example
24///
25/// ```
26/// use structural::{
27///     field::RevGetFieldType,
28///     GetFieldType3,StructuralExt,Structural,
29///     FP,fp,
30/// };
31///
32/// fn main(){
33///     let this=TopLevel::default();
34///     
35///     let baz: &RevGetFieldType<FP!(foo.bar.baz), TopLevel>=
36///         this.field_(fp!(foo.bar.baz));
37///     assert_eq!( *baz, Vec::new() );
38///     
39///     let strand: &RevGetFieldType<FP!(foo.bar.strand), TopLevel>=
40///         this.field_(fp!(foo.bar.strand));
41///     assert_eq!( *strand, String::new() );
42/// }
43///
44/// #[derive(Debug,Default,Structural)]
45/// struct TopLevel{
46///     pub foo:Foo,
47/// }
48///
49/// #[derive(Debug,Default,Structural)]
50/// struct Foo{
51///     pub bar:Bar,
52/// }
53///
54/// #[derive(Debug,Default,Structural)]
55/// struct Bar{
56///     pub baz:Vec<()>,
57///     pub strand:String,
58/// }
59/// ```
60pub type RevGetFieldType<FieldPath, This> = <FieldPath as RevFieldType<This>>::Ty;
61
62/// Queries the error type returned by `Rev*FieldImpl` methods.
63pub type RevFieldErrOut<FieldPath, This> = <FieldPath as RevFieldErr<This>>::Err;
64
65/////////////////////////////////////////////////////////////////////////////
66
67/// Like `FieldType`,except that the parameters are reversed.
68/// `This` is the type we are accessing,and `Self` is a field path.
69pub trait RevFieldType<This: ?Sized>: IsSingleFieldPath {
70    /// The type of the field.
71    type Ty: ?Sized;
72}
73
74/// For querying the error type returned by single-field `Rev*` trait methods.
75pub trait RevFieldErr<This: ?Sized>: IsSingleFieldPath + RevFieldType<This> {
76    /// The error returned by `rev_*` methods.
77    ///
78    /// This can be either:
79    ///
80    /// - [`InfallibleAccess`]:
81    ///     For `Rev*` accessors that return a field that always exists,
82    ///     most often in a struct.
83    ///
84    /// - [`FailedAccess`]:
85    ///     For `Rev*` accessors that attempt to return a field that may not exist,
86    ///     most often inside an enum.
87    ///
88    /// [`InfallibleAccess`]: ../errors/enum.InfallibleAccess.html
89    /// [`FailedAccess`]: ../errors/struct.FailedAccess.html
90    type Err: IsFieldErr;
91}
92
93/////////////////////////////////////////////////////////////////////////////
94
95/// Like `Get*Field`,except that the parameters are reversed,
96///
97/// `This` is the type we are accessing,and `Self` is a field path.
98///
99/// This is used by the [`StructuralExt::field_`](../../trait.StructuralExt.html#method.field_)
100/// method.
101///
102/// # Use as bound
103///
104/// For examples of using `RevGetFieldImpl` as a bound look at example for:
105///
106/// - [RevGetField](./trait.RevGetField.html):
107/// For infallible field access,generally struct fields,not inside of a nested enum.
108///
109/// - [OptRevGetField](./trait.OptRevGetField.html):
110/// Fallible field access,generally for getting a field in a (potentially nested) enum.
111///
112/// # Example
113///
114/// This example demonstrates implementing `RevGetFieldImpl` to index a slice from the end.
115///
116///
117/// ```rust
118/// use structural::field::{FailedAccess,RevFieldType,RevFieldErr,RevGetFieldImpl};
119/// use structural::path::IsSingleFieldPath;
120/// use structural::StructuralExt;
121///
122/// struct FromEnd(usize);
123///
124/// impl IsSingleFieldPath for FromEnd{}
125///
126/// impl<'a,T> RevFieldType<[T]> for FromEnd {
127///     type Ty = T;
128/// }
129/// impl<'a,T> RevFieldErr<[T]> for FromEnd {
130///     type Err = FailedAccess;
131/// }
132/// impl<'a,T> RevGetFieldImpl<'a,[T]> for FromEnd {
133///     fn rev_get_field(self, this: &'a [T]) -> Result<&'a T, FailedAccess>{
134///         let len=this.len();
135///         this.get(len.wrapping_sub(self.0 + 1))
136///             .ok_or(FailedAccess)
137///     }
138/// }
139///
140/// let slice=&[3,5,8,13][..];
141///
142/// assert_eq!( slice.field_(FromEnd(0)), Some(&13) );
143/// assert_eq!( slice.field_(FromEnd(1)), Some(&8) );
144/// assert_eq!( slice.field_(FromEnd(2)), Some(&5) );
145/// assert_eq!( slice.field_(FromEnd(3)), Some(&3) );
146/// assert_eq!( slice.field_(FromEnd(4)), None );
147///
148///
149/// ```
150pub trait RevGetFieldImpl<'a, This: ?Sized>: RevFieldErr<This> {
151    /// Accesses the field that `self` represents inside of `this`,by reference.
152    fn rev_get_field(self, this: &'a This) -> Result<&'a Self::Ty, Self::Err>;
153}
154
155/////////////////////////////////////////////////////////////////////////////
156
157/// Like Get*FieldMut,except that the parameters are reversed,
158///
159/// `This` is the type we are accessing,and `Self` is a field path.
160///
161/// This is used by the [`StructuralExt::field_mut`](../../trait.StructuralExt.html#method.field_mut)
162/// method.
163///
164/// # Safety
165///
166/// The `rev_get_field_raw_mut` function must return a valid pointer derived
167/// from the passed in pointer, that is safe to dereference mutably.
168///
169/// ### Locality of Implementations
170///
171/// You must only implement `RevGetFieldMutImpl` for field paths defined locally
172/// (in the same crate as the implementation itself).
173///
174/// This allows crate authors to add more `RevGetFieldMutImpl` impls while
175/// lowering the rist of aliasing the returned pointer from `rev_get_field_raw_mut`.
176///
177/// # Use as bound
178///
179/// For examples of using `RevGetFieldMutImpl` as a bound look at example for:
180///
181/// - [RevGetFieldMut](./trait.RevGetFieldMut.html):
182/// For infallible field access,generally struct fields,not inside of a nested enum.
183///
184/// - [OptRevGetFieldMut](./trait.OptRevGetFieldMut.html):
185/// Fallible field access,generally for getting a field in a (potentially nested) enum.
186///
187/// # Example
188///
189/// This example demonstrates implementing `RevGetFieldMutImpl` to choose between 2 fields
190/// based on a runtime value.
191///
192/// ```rust
193/// use structural::{
194///     field::{FailedAccess, RevFieldErr, RevFieldType, RevGetFieldImpl, RevGetFieldMutImpl},
195///     path::IsSingleFieldPath,
196///     StructuralExt, ts,
197/// };
198///
199/// let mut tup=(3,5,8,13);
200///
201/// assert_eq!( tup.field_mut(Choose(Which::First, ts!(0), ts!(1))), &mut 3 );
202/// assert_eq!( tup.field_mut(Choose(Which::Second, ts!(0), ts!(1))), &mut 5 );
203/// assert_eq!( tup.field_mut(Choose(Which::First, ts!(1), ts!(2))), &mut 5 );
204/// assert_eq!( tup.field_mut(Choose(Which::Second, ts!(1), ts!(2))), &mut 8 );
205///
206///
207/// #[derive(Debug,Copy,Clone,PartialEq)]
208/// struct Choose<P0,P1>(Which,P0,P1);
209///
210/// #[derive(Debug,Copy,Clone,PartialEq)]
211/// enum Which{
212///     First,
213///     Second,
214/// }
215///
216/// impl<P0,P1> IsSingleFieldPath for Choose<P0,P1>{}
217///
218/// impl<P0,P1,T> RevFieldType<T> for Choose<P0,P1>
219/// where
220///     P0: RevFieldType<T>,
221///     P1: RevFieldType<T, Ty=P0::Ty>,
222/// {
223///     type Ty = P0::Ty;
224/// }
225///
226/// impl<P0,P1,T> RevFieldErr<T> for Choose<P0,P1>
227/// where
228///     P0: RevFieldErr<T>,
229///     P1: RevFieldErr<T, Ty=P0::Ty, Err=P0::Err>,
230/// {
231///     type Err = P0::Err;
232/// }
233///
234/// impl<'a,P0,P1,T> RevGetFieldImpl<'a,T> for Choose<P0,P1>
235/// where
236///     P0: RevGetFieldImpl<'a,T>,
237///     P1: RevGetFieldImpl<'a,T, Ty=P0::Ty, Err=P0::Err>,
238/// {
239///     fn rev_get_field(self, this: &'a T) -> Result<&'a P0::Ty, P0::Err>{
240///         match self.0 {
241///             Which::First=>self.1.rev_get_field(this),
242///             Which::Second=>self.2.rev_get_field(this),
243///         }
244///     }
245/// }
246///
247/// unsafe impl<'a,P0,P1,T> RevGetFieldMutImpl<'a,T> for Choose<P0,P1>
248/// where
249///     P0: RevGetFieldMutImpl<'a,T>,
250///     P1: RevGetFieldMutImpl<'a,T, Ty=P0::Ty, Err=P0::Err>,
251/// {
252///     fn rev_get_field_mut(self, this: &'a mut T) -> Result<&'a mut P0::Ty, P0::Err>{
253///         match self.0 {
254///             Which::First=>self.1.rev_get_field_mut(this),
255///             Which::Second=>self.2.rev_get_field_mut(this),
256///         }
257///     }
258///
259///     unsafe fn rev_get_field_raw_mut(self, this: *mut  T) -> Result<*mut P0::Ty, P0::Err>{
260///         match self.0 {
261///             Which::First=>self.1.rev_get_field_raw_mut(this),
262///             Which::Second=>self.2.rev_get_field_raw_mut(this),
263///         }
264///     }
265/// }
266///
267/// ```
268pub unsafe trait RevGetFieldMutImpl<'a, This: ?Sized>: RevGetFieldImpl<'a, This> {
269    /// Accesses the field that `self` represents inside of `this`,by mutable reference.
270    fn rev_get_field_mut(self, this: &'a mut This) -> Result<&'a mut Self::Ty, Self::Err>;
271
272    /// Accesses the field that `self` represents inside of `this`,by raw pointer.
273    ///
274    /// # Safety
275    ///
276    /// You must pass a pointer to a fully initialized instance of `This`.
277    unsafe fn rev_get_field_raw_mut(self, this: *mut This) -> Result<*mut Self::Ty, Self::Err>;
278}
279
280/////////////////////////////////////////////////////////////////////////////
281
282/// Like `Into*Field::into_*field_`,except that the parameters are reversed,
283///
284/// `This` is the type we are accessing,and `Self` is a field path.
285///
286/// This is used by the
287/// [`StructuralExt::into_field`](../../trait.StructuralExt.html#method.into_field)
288/// and [`StructuralExt::box_into_field`](../../trait.StructuralExt.html#method.box_into_field)
289/// method.
290///
291/// # Use as bound
292///
293/// For examples of using `RevIntoFieldImpl` as a bound look at example for:
294///
295/// - [RevIntoField](./trait.RevIntoField.html):
296/// For infallible field access,generalerally struct fields,not inside of a nested enum.
297///
298/// - [OptRevIntoField](./trait.OptRevIntoField.html):
299/// Fallible field access,generally for getting a field in a (potentially nested) enum.
300///
301/// # Example
302///
303/// This example demonstrates implementing `RevIntoFieldImpl`.
304///
305/// The transmute in this example is only sound because of the
306/// `#[repr(transparent)]` attribute on the `Wrapper` struct,
307/// and the reference to` T` is converted into a reference to `Wrapper<T>`.<br>
308/// Transmutes like that are not sound in the more general case,
309/// like transmuting from an arbitrary `Foo<T>` to `Foo<Newtype<T>>` using `std::mem::transmute`,
310/// since the layout of `Foo` is allowed to change.
311///
312/// ```rust
313/// use structural::{
314///     field::{FailedAccess, RevFieldErr, RevFieldType, RevGetFieldImpl, RevIntoFieldImpl},
315///     path::IsSingleFieldPath,
316///     StructuralExt, fp,
317/// };
318///
319/// use core::mem;
320///
321/// let mut tup=(3,5,8,13);
322///
323/// assert_eq!( tup.into_field(Wrapped(fp!(0))), Newtype(3) );
324/// assert_eq!( tup.into_field(Wrapped(fp!(1))), Newtype(5) );
325/// assert_eq!( tup.into_field(Wrapped(fp!(2))), Newtype(8) );
326/// assert_eq!( tup.into_field(Wrapped(fp!(3))), Newtype(13) );
327///
328///
329/// #[derive(Debug,Copy,Clone,PartialEq)]
330/// struct Wrapped<P>(P);
331///
332/// #[repr(transparent)]
333/// #[derive(Debug,Copy,Clone,PartialEq)]
334/// pub struct Newtype<T:?Sized>(T);
335///
336/// impl<P> IsSingleFieldPath for Wrapped<P>{}
337///
338/// impl<P,T> RevFieldType<T> for Wrapped<P>
339/// where
340///     P: RevFieldType<T>,
341/// {
342///     type Ty = Newtype<P::Ty>;
343/// }
344///
345/// impl<P,T> RevFieldErr<T> for Wrapped<P>
346/// where
347///     P: RevFieldErr<T>,
348/// {
349///     type Err = P::Err;
350/// }
351///
352/// impl<P,T> RevIntoFieldImpl<T> for Wrapped<P>
353/// where
354///     P: RevIntoFieldImpl<T>,
355///     P::Ty: Sized,
356/// {
357///     fn rev_into_field(self, this: T) -> Result<Self::Ty, Self::Err>
358///     where
359///         Self::Ty: Sized
360///     {
361///         self.0.rev_into_field(this)
362///             .map(Newtype)
363///     }
364/// }
365/// ```
366pub trait RevIntoFieldImpl<This: ?Sized>: RevFieldErr<This> {
367    /// Accesses the field that `self` represents inside of `this`,by value.
368    fn rev_into_field(self, this: This) -> Result<Self::Ty, Self::Err>
369    where
370        This: Sized,
371        Self::Ty: Sized;
372}
373
374/// Like `Into*Field::move_out_*field_`,except that the parameters are reversed,
375///
376/// `This` is the type we are accessing,and `Self` is a field path.
377///
378/// This is used by the implementations of the [`RevIntoMultiFieldImpl`] trait.
379///
380/// [`RevIntoMultiFieldImpl`]: ../multi_fields/trait.RevIntoMultiFieldImpl.html
381///
382/// # Safety
383///
384/// Implementors of this traits must do any of:
385///
386/// - Delegate their implementations to the `IntoField` and `IntoVariantField` traits.
387///
388/// - Be implemented following the safety requirements of the
389/// [`IntoField`](../trait.IntoField.html#implementing-move_out_field_)
390/// (if it's moving out a struct field) or
391/// [`IntoVariantField`](../trait.IntoVariantField.html#implementing-move_out_vfield_)
392/// (if it's moving out an enum field).
393///
394pub unsafe trait RevMoveOutFieldImpl<This: ?Sized>:
395    RevIntoFieldImpl<This> + ShallowFieldPath
396{
397    /// Moves out the field that `self` represents inside of `this`.
398    ///
399    /// # Safety
400    ///
401    /// The same instance of `MovedOutFields` must be passed to every call to
402    /// `rev_move_out_field` on the same instance of `this`,
403    /// as well as not mutating that `MovedOutFields` instance outside of
404    /// `rev_move_out_field` with the same `This` parameter.
405    ///
406    /// Each field must be moved with any method at most once on the same instance of `This`.    
407    unsafe fn rev_move_out_field(
408        self,
409        this: &mut This,
410        moved: &mut MovedOutFields,
411    ) -> Result<Self::Ty, Self::Err>
412    where
413        Self::Ty: Sized;
414}
415
416/////////////////////////////////////////////////////////////////////////////
417
418macro_rules! declare_accessor_trait_alias {
419    (
420        $(#[$attr:meta])*
421        $vis:vis trait $trait_name:ident<$($lt:lifetime,)?$This:ident>=
422        $($supertraits:tt)*
423    ) => (
424        $(#[$attr])*
425        $vis trait $trait_name<$($lt,)? $This >:$($supertraits)* {}
426
427        impl<$($lt,)? Path,$This> $trait_name<$($lt,)? $This > for Path
428        where
429            Path:$($supertraits)*
430        {}
431    )
432}
433
434declare_accessor_trait_alias! {
435    /// A trait alias for an infallible [`RevGetFieldImpl`](./trait.RevGetFieldImpl.html),
436    /// generally used to access fields in structs(not in a nested enum inside the struct).
437    ///
438    ///
439    /// `This` is the type we are accessing,and `Self` is a field path.
440    ///
441    /// # Example
442    ///
443    /// This example shows how to access a nested struct field by reference.
444    ///
445    /// ```rust
446    /// use structural::field::RevGetField;
447    /// use structural::{StructuralExt,FP,fp};
448    ///
449    ///
450    /// # fn main(){
451    /// let tup=(3,5,(8,(13,21)));
452    /// assert_eq!( get_nested(&tup), &13 );
453    /// # }
454    ///
455    /// fn get_nested<'a,T>(this:&'a T)->&'a i32
456    /// where
457    ///     FP!(2.1.0): RevGetField<'a,T,Ty=i32>
458    /// {
459    ///     this.field_(fp!(2.1.0))
460    /// }
461    ///
462    ///
463    /// ```
464    pub trait RevGetField<'a,This>=
465        RevGetFieldImpl<'a,This,Err=InfallibleAccess>
466}
467
468declare_accessor_trait_alias! {
469    /// A trait alias for a fallible [`RevGetFieldImpl`](./trait.RevGetFieldImpl.html),
470    /// generally used to access fields inside enums.
471    ///
472    /// `This` is the type we are accessing,and `Self` is a field path.
473    ///
474    /// # Example
475    ///
476    /// This example shows how you can access an enum field by reference.
477    ///
478    /// ```rust
479    /// use structural::field::OptRevGetField;
480    /// use structural::{StructuralExt,FP,fp};
481    ///
482    /// let tup1=(3,5,(8,(Some(13),21)));
483    /// let tup2=(3,5,(8,(None,21)));
484    ///
485    /// assert_eq!( get_nested(&tup1), Some(&13) );
486    /// assert_eq!( get_nested(&tup2), None );
487    ///
488    /// fn get_nested<'a,T>(this:&'a T)->Option<&'a i32>
489    /// where
490    ///     FP!(2.1.0?): OptRevGetField<'a,T,Ty=i32>
491    /// {
492    ///     this.field_(fp!(2.1.0?))
493    /// }
494    ///
495    ///
496    /// ```
497    pub trait OptRevGetField<'a,This>=
498        RevGetFieldImpl<'a,This,Err=FailedAccess>
499}
500
501declare_accessor_trait_alias! {
502    /// A trait alias for an infallible [`RevGetFieldMutImpl`](./trait.RevGetFieldMutImpl.html),
503    /// generally used to access fields in structs(not in a nested enum inside the struct).
504    ///
505    /// `This` is the type we are accessing,and `Self` is a field path.
506    ///
507    /// # Example
508    ///
509    /// This example shows how to access a nested struct field by mutable reference.
510    ///
511    /// ```rust
512    /// use structural::field::RevGetFieldMut;
513    /// use structural::for_examples::{StructFoo, StructBar, Struct3};
514    /// use structural::{StructuralExt,FP,fp};
515    ///
516    /// let mut struct_=Struct3{
517    ///     foo: Some(0),
518    ///     bar: "hi",
519    ///     baz: StructBar{
520    ///         bar: StructFoo{
521    ///             foo:101,
522    ///         },
523    ///     },
524    /// };
525    ///
526    /// assert_eq!( get_nested(&mut struct_), &mut 101 );
527    ///
528    /// fn get_nested<'a,T>(this:&'a mut T)->&'a mut i32
529    /// where
530    ///     FP!(baz.bar.foo): RevGetFieldMut<'a,T,Ty=i32>
531    /// {
532    ///     this.field_mut(fp!(baz.bar.foo))
533    /// }
534    ///
535    ///
536    /// ```
537    pub trait RevGetFieldMut<'a,This>=
538        RevGetFieldMutImpl<'a,This,Err=InfallibleAccess>
539}
540
541declare_accessor_trait_alias! {
542    /// A trait alias for a fallible [`RevGetFieldMutImpl`](./trait.RevGetFieldMutImpl.html),
543    /// generally used to access fields inside enums.
544    ///
545    /// `This` is the type we are accessing,and `Self` is a field path.
546    ///
547    /// # Example
548    ///
549    /// This example shows how you can access an enum field by mutable reference.
550    ///
551    /// ```rust
552    /// use structural::field::OptRevGetFieldMut;
553    /// use structural::for_examples::{StructFoo, StructBar, Struct3};
554    /// use structural::{StructuralExt,FP,fp};
555    ///
556    /// let mut struct_=Struct3{
557    ///     foo: Some(0),
558    ///     bar: "hi",
559    ///     baz: StructBar{
560    ///         bar: StructFoo{
561    ///             foo:Some("hello"),
562    ///         },
563    ///     },
564    /// };
565    ///
566    /// assert_eq!( get_nested(&mut struct_), Some(&mut "hello") );
567    ///
568    /// fn get_nested<'a,T>(this:&'a mut T)->Option<&'a mut &'static str>
569    /// where
570    ///     FP!(baz.bar.foo?): OptRevGetFieldMut<'a,T,Ty=&'static str>
571    /// {
572    ///     this.field_mut(fp!(baz.bar.foo?))
573    /// }
574    ///
575    ///
576    /// ```
577    pub trait OptRevGetFieldMut<'a,This>=
578        RevGetFieldMutImpl<'a,This,Err=FailedAccess>
579}
580
581declare_accessor_trait_alias! {
582    /// A trait alias for an infallible [`RevIntoFieldImpl`](./trait.RevIntoFieldImpl.html),
583    /// generally used to access fields in structs(not in a nested enum inside the struct).
584    ///
585    /// `This` is the type we are accessing,and `Self` is a field path.
586    ///
587    /// # Example
588    ///
589    /// This example shows how to access a nested struct field by value.
590    ///
591    /// ```rust
592    /// use structural::field::RevIntoField;
593    /// use structural::for_examples::StructBar;
594    /// use structural::{StructuralExt,FP,fp};
595    ///
596    /// use std::cmp::Ordering;
597    ///
598    /// let struct_=StructBar{
599    ///     bar: StructBar{
600    ///         bar: StructBar{
601    ///             bar: Ordering::Greater
602    ///         },
603    ///     },
604    /// };
605    ///
606    /// assert_eq!( get_nested(struct_), Ordering::Greater );
607    ///
608    /// fn get_nested<T>(this:T)->Ordering
609    /// where
610    ///     FP!(bar.bar.bar): RevIntoField<T,Ty=Ordering>
611    /// {
612    ///     this.into_field(fp!(bar.bar.bar))
613    /// }
614    ///
615    ///
616    /// ```
617    pub trait RevIntoField<This>=
618        RevIntoFieldImpl<This,Err=InfallibleAccess>
619}
620
621declare_accessor_trait_alias! {
622    /// A trait alias for a fallible [`RevIntoFieldImpl`](./trait.RevIntoFieldImpl.html),
623    /// generally used to access fields inside enums.
624    ///
625    /// `This` is the type we are accessing,and `Self` is a field path.
626    ///
627    /// # Example
628    ///
629    /// This example shows how you can access an enum field by value.
630    ///
631    /// ```rust
632    /// use structural::field::OptRevIntoField;
633    /// use structural::for_examples::{StructFoo,WithBoom};
634    /// use structural::{StructuralExt,FP,fp};
635    ///
636    /// let nope=StructFoo{ foo: WithBoom::Nope };
637    /// let boom=StructFoo{ foo: WithBoom::Boom{  a: "hello", b: &[3,5,8,13]  } };
638    ///
639    /// assert_eq!( get_nested(nope), None );
640    /// assert_eq!( get_nested(boom), Some(&[3,5,8,13][..]) );
641    ///
642    /// fn get_nested<T>(this:T)->Option<&'static [u16]>
643    /// where
644    ///     FP!(foo::Boom.b): OptRevIntoField<T,Ty=&'static [u16]>
645    /// {
646    ///     this.into_field(fp!(foo::Boom.b))
647    /// }
648    ///
649    ///
650    /// ```
651    pub trait OptRevIntoField<This>=
652        RevIntoFieldImpl<This,Err=FailedAccess>
653}
654
655declare_accessor_trait_alias! {
656    /// A trait alias for infallible [`RevIntoFieldImpl`] + [`RevGetFieldMutImpl`],
657    /// generally used to access fields in structs(not in a nested enum inside the struct).
658    ///
659    /// `This` is the type we are accessing,and `Self` is a field path.
660    ///
661    /// [`RevIntoFieldImpl`]: ./trait.RevIntoFieldImpl.html
662    /// [`RevGetFieldMutImpl`]: ./trait.RevGetFieldMutImpl.html
663    ///
664    /// # Example
665    ///
666    /// This example shows how to access a struct field by mutable reference,and by value.
667    ///
668    /// Also,how to write extension traits with `Rev*` traits.
669    ///
670    /// ```rust
671    /// use structural::field::{RevIntoFieldMut,RevGetFieldType};
672    /// use structural::for_examples::StructBar;
673    /// use structural::{StructuralExt,FP,fp};
674    ///
675    /// let mut foo=StructBar{
676    ///     bar: ([(0,3),(5,8)], [(40,50,60)]),
677    /// };
678    ///
679    /// assert_eq!( foo.get_nested_mut(), &mut (5,8) );
680    /// assert_eq!( foo.into_nested(), (5,8) );
681    ///
682    /// let mut oop=StructBar{
683    ///     bar: [["hello","world"],["uh","no"]],
684    /// };
685    ///
686    /// assert_eq!( oop.get_nested_mut(), &mut "world" );
687    /// assert_eq!( oop.into_nested(), "world" );
688    ///
689    /// trait GetNested: Sized {
690    ///     fn get_nested_mut<'a,Ty>(&'a mut self)->&'a mut Ty
691    ///     where
692    ///         FP!(bar.0.1): RevIntoFieldMut<'a,Self,Ty=Ty>
693    ///     {
694    ///         self.field_mut(fp!(bar.0.1))
695    ///     }
696    ///
697    ///     fn into_nested<'a,Ty>(self)->Ty
698    ///     where
699    ///         FP!(bar.0.1): RevIntoFieldMut<'a,Self,Ty=Ty>
700    ///     {
701    ///         self.into_field(fp!(bar.0.1))
702    ///     }
703    /// }
704    ///
705    /// impl<T> GetNested for T {}
706    ///
707    /// ```
708    pub trait RevIntoFieldMut<'a,This>=
709        RevIntoField<This> + RevGetFieldMut<'a,This>
710}
711
712declare_accessor_trait_alias! {
713    /// A trait alias for fallible [`RevIntoFieldImpl`] + [`RevGetFieldMutImpl`],
714    /// generally used to access fields inside enums.
715    ///
716    /// `This` is the type we are accessing,and `Self` is a field path.
717    ///
718    /// [`RevIntoFieldImpl`]: ./trait.RevIntoFieldImpl.html
719    /// [`RevGetFieldMutImpl`]: ./trait.RevGetFieldMutImpl.html
720    ///
721    /// # Example
722    ///
723    /// This example shows how to access an enum field by mutable reference,and by value.
724    ///
725    /// Also,how to write extension traits with `Rev*` traits.
726    ///
727    /// ```rust
728    /// use structural::field::{OptRevIntoFieldMut,RevGetFieldType};
729    /// use structural::for_examples::{StructFoo,WithBoom};
730    /// use structural::{StructuralExt,FP,fp};
731    ///
732    /// let mut nope=StructFoo{ foo: WithBoom::Nope };
733    /// let mut boom=StructFoo{ foo: WithBoom::Boom{  a: "hello", b: &[3,5,8,13]  } };
734    ///
735    /// assert_eq!( nope.get_nested_mut(), None );
736    /// assert_eq!( boom.get_nested_mut(), Some(&mut &[3,5,8,13][..]) );
737    ///
738    /// assert_eq!( nope.into_nested(), None );
739    /// assert_eq!( boom.into_nested(), Some(&[3,5,8,13][..]) );
740    ///
741    /// trait GetNested: Sized {
742    ///     fn get_nested_mut<'a,Ty>(&'a mut self)->Option<&'a mut Ty>
743    ///     where
744    ///         FP!(foo::Boom.b): OptRevIntoFieldMut<'a,Self,Ty=Ty>
745    ///     {
746    ///         self.field_mut(fp!(foo::Boom.b))
747    ///     }
748    ///
749    ///     fn into_nested<'a,Ty>(self)->Option<Ty>
750    ///     where
751    ///         FP!(foo::Boom.b): OptRevIntoFieldMut<'a,Self,Ty=Ty>
752    ///     {
753    ///         self.into_field(fp!(foo::Boom.b))
754    ///     }
755    /// }
756    ///
757    /// impl<T> GetNested for T {}
758    ///
759    /// ```
760    pub trait OptRevIntoFieldMut<'a,This>=
761        OptRevIntoField<This> + OptRevGetFieldMut<'a,This>
762}
763
764declare_accessor_trait_alias! {
765    /// A trait alias for infallible [`RevIntoFieldImpl`] + [`RevGetFieldImpl`],
766    /// generally used to access fields in structs(not in a nested enum inside the struct).
767    ///
768    /// `This` is the type we are accessing,and `Self` is a field path.
769    ///
770    /// [`RevIntoFieldImpl`]: ./trait.RevIntoFieldImpl.html
771    /// [`RevGetFieldImpl`]: ./trait.RevGetFieldImpl.html
772    ///
773    /// # Example
774    ///
775    /// This example shows how to access a struct field by reference,and by value.
776    ///
777    /// Also,how to write extension traits with `Rev*` traits.
778    ///
779    /// ```rust
780    /// use structural::field::{RevIntoFieldRef,RevGetFieldType};
781    /// use structural::for_examples::StructBar;
782    /// use structural::{StructuralExt,FP,fp};
783    ///
784    /// let foo=StructBar{
785    ///     bar: ([(0,3),(5,8)], [(40,50,60)]),
786    /// };
787    ///
788    /// assert_eq!( foo.get_nested(), &(5,8) );
789    /// assert_eq!( foo.into_nested(), (5,8) );
790    ///
791    /// let oop=StructBar{
792    ///     bar: [["hello","world"],["uh","no"]],
793    /// };
794    ///
795    /// assert_eq!( oop.get_nested(), &"world" );
796    /// assert_eq!( oop.into_nested(), "world" );
797    ///
798    /// trait GetNested: Sized {
799    ///     fn get_nested<'a,Ty>(&'a self)->&'a Ty
800    ///     where
801    ///         FP!(bar.0.1): RevIntoFieldRef<'a,Self,Ty=Ty>
802    ///     {
803    ///         self.field_(fp!(bar.0.1))
804    ///     }
805    ///
806    ///     fn into_nested<'a,Ty>(self)->Ty
807    ///     where
808    ///         FP!(bar.0.1): RevIntoFieldRef<'a,Self,Ty=Ty>
809    ///     {
810    ///         self.into_field(fp!(bar.0.1))
811    ///     }
812    /// }
813    ///
814    /// impl<T> GetNested for T {}
815    ///
816    /// ```
817    pub trait RevIntoFieldRef<'a,This>=
818        RevIntoField<This> + RevGetFieldMut<'a,This>
819}
820
821declare_accessor_trait_alias! {
822    /// A trait alias for fallible [`RevIntoFieldImpl`] + [`RevGetFieldImpl`],
823    /// generally used to access fields inside enums.
824    ///
825    /// `This` is the type we are accessing,and `Self` is a field path.
826    ///
827    /// [`RevIntoFieldImpl`]: ./trait.RevIntoFieldImpl.html
828    /// [`RevGetFieldImpl`]: ./trait.RevGetFieldImpl.html
829    ///
830    /// # Example
831    ///
832    /// This example shows how to access an enum field by reference,and by value.
833    ///
834    /// Also,how to write extension traits with `Rev*` traits.
835    ///
836    /// ```rust
837    /// use structural::field::{OptRevIntoFieldRef,RevGetFieldType};
838    /// use structural::for_examples::{StructFoo,WithBoom};
839    /// use structural::{StructuralExt,FP,fp};
840    ///
841    /// let nope=StructFoo{ foo: WithBoom::Nope };
842    /// let boom=StructFoo{ foo: WithBoom::Boom{  a: "hello", b: &[3,5,8,13]  } };
843    ///
844    /// assert_eq!( nope.get_nested(), None );
845    /// assert_eq!( boom.get_nested(), Some(&&[3,5,8,13][..]) );
846    ///
847    /// assert_eq!( nope.into_nested(), None );
848    /// assert_eq!( boom.into_nested(), Some(&[3,5,8,13][..]) );
849    ///
850    /// trait GetNested: Sized {
851    ///     fn get_nested<'a,Ty>(&'a self)->Option<&'a Ty>
852    ///     where
853    ///         FP!(foo::Boom.b): OptRevIntoFieldRef<'a,Self,Ty=Ty>
854    ///     {
855    ///         self.field_(fp!(foo::Boom.b))
856    ///     }
857    ///
858    ///     fn into_nested<'a,Ty>(self)->Option<Ty>
859    ///     where
860    ///         FP!(foo::Boom.b): OptRevIntoFieldRef<'a,Self,Ty=Ty>
861    ///     {
862    ///         self.into_field(fp!(foo::Boom.b))
863    ///     }
864    /// }
865    ///
866    /// impl<T> GetNested for T {}
867    ///
868    /// ```
869    pub trait OptRevIntoFieldRef<'a,This>=
870        OptRevIntoField<This> + OptRevGetFieldMut<'a,This>
871}