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}