/*!
Contains traits implemented on field paths,taking Structural types as parameters.
*/
use crate::;
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/// Queries the type of a nested field in This,
/// what field is queried is determined by `FieldPath`,
///
/// # Example
///
/// ```
/// use structural::{
/// field::RevGetFieldType,
/// GetFieldType3,StructuralExt,Structural,
/// FP,fp,
/// };
///
/// fn main(){
/// let this=TopLevel::default();
///
/// let baz: &RevGetFieldType<FP!(foo.bar.baz), TopLevel>=
/// this.field_(fp!(foo.bar.baz));
/// assert_eq!( *baz, Vec::new() );
///
/// let strand: &RevGetFieldType<FP!(foo.bar.strand), TopLevel>=
/// this.field_(fp!(foo.bar.strand));
/// assert_eq!( *strand, String::new() );
/// }
///
/// #[derive(Debug,Default,Structural)]
/// struct TopLevel{
/// pub foo:Foo,
/// }
///
/// #[derive(Debug,Default,Structural)]
/// struct Foo{
/// pub bar:Bar,
/// }
///
/// #[derive(Debug,Default,Structural)]
/// struct Bar{
/// pub baz:Vec<()>,
/// pub strand:String,
/// }
/// ```
pub type RevGetFieldType<FieldPath, This> = Ty;
/// Queries the error type returned by `Rev*FieldImpl` methods.
pub type RevFieldErrOut<FieldPath, This> = Err;
/////////////////////////////////////////////////////////////////////////////
/// Like `FieldType`,except that the parameters are reversed.
/// `This` is the type we are accessing,and `Self` is a field path.
/// For querying the error type returned by single-field `Rev*` trait methods.
/////////////////////////////////////////////////////////////////////////////
/// Like `Get*Field`,except that the parameters are reversed,
///
/// `This` is the type we are accessing,and `Self` is a field path.
///
/// This is used by the [`StructuralExt::field_`](../../trait.StructuralExt.html#method.field_)
/// method.
///
/// # Use as bound
///
/// For examples of using `RevGetFieldImpl` as a bound look at example for:
///
/// - [RevGetField](./trait.RevGetField.html):
/// For infallible field access,generally struct fields,not inside of a nested enum.
///
/// - [OptRevGetField](./trait.OptRevGetField.html):
/// Fallible field access,generally for getting a field in a (potentially nested) enum.
///
/// # Example
///
/// This example demonstrates implementing `RevGetFieldImpl` to index a slice from the end.
///
///
/// ```rust
/// use structural::field::{FailedAccess,RevFieldType,RevFieldErr,RevGetFieldImpl};
/// use structural::path::IsSingleFieldPath;
/// use structural::StructuralExt;
///
/// struct FromEnd(usize);
///
/// impl IsSingleFieldPath for FromEnd{}
///
/// impl<'a,T> RevFieldType<[T]> for FromEnd {
/// type Ty = T;
/// }
/// impl<'a,T> RevFieldErr<[T]> for FromEnd {
/// type Err = FailedAccess;
/// }
/// impl<'a,T> RevGetFieldImpl<'a,[T]> for FromEnd {
/// fn rev_get_field(self, this: &'a [T]) -> Result<&'a T, FailedAccess>{
/// let len=this.len();
/// this.get(len.wrapping_sub(self.0 + 1))
/// .ok_or(FailedAccess)
/// }
/// }
///
/// let slice=&[3,5,8,13][..];
///
/// assert_eq!( slice.field_(FromEnd(0)), Some(&13) );
/// assert_eq!( slice.field_(FromEnd(1)), Some(&8) );
/// assert_eq!( slice.field_(FromEnd(2)), Some(&5) );
/// assert_eq!( slice.field_(FromEnd(3)), Some(&3) );
/// assert_eq!( slice.field_(FromEnd(4)), None );
///
///
/// ```
/////////////////////////////////////////////////////////////////////////////
/// Like Get*FieldMut,except that the parameters are reversed,
///
/// `This` is the type we are accessing,and `Self` is a field path.
///
/// This is used by the [`StructuralExt::field_mut`](../../trait.StructuralExt.html#method.field_mut)
/// method.
///
/// # Safety
///
/// The `rev_get_field_raw_mut` function must return a valid pointer derived
/// from the passed in pointer, that is safe to dereference mutably.
///
/// ### Locality of Implementations
///
/// You must only implement `RevGetFieldMutImpl` for field paths defined locally
/// (in the same crate as the implementation itself).
///
/// This allows crate authors to add more `RevGetFieldMutImpl` impls while
/// lowering the rist of aliasing the returned pointer from `rev_get_field_raw_mut`.
///
/// # Use as bound
///
/// For examples of using `RevGetFieldMutImpl` as a bound look at example for:
///
/// - [RevGetFieldMut](./trait.RevGetFieldMut.html):
/// For infallible field access,generally struct fields,not inside of a nested enum.
///
/// - [OptRevGetFieldMut](./trait.OptRevGetFieldMut.html):
/// Fallible field access,generally for getting a field in a (potentially nested) enum.
///
/// # Example
///
/// This example demonstrates implementing `RevGetFieldMutImpl` to choose between 2 fields
/// based on a runtime value.
///
/// ```rust
/// use structural::{
/// field::{FailedAccess, RevFieldErr, RevFieldType, RevGetFieldImpl, RevGetFieldMutImpl},
/// path::IsSingleFieldPath,
/// StructuralExt, ts,
/// };
///
/// let mut tup=(3,5,8,13);
///
/// assert_eq!( tup.field_mut(Choose(Which::First, ts!(0), ts!(1))), &mut 3 );
/// assert_eq!( tup.field_mut(Choose(Which::Second, ts!(0), ts!(1))), &mut 5 );
/// assert_eq!( tup.field_mut(Choose(Which::First, ts!(1), ts!(2))), &mut 5 );
/// assert_eq!( tup.field_mut(Choose(Which::Second, ts!(1), ts!(2))), &mut 8 );
///
///
/// #[derive(Debug,Copy,Clone,PartialEq)]
/// struct Choose<P0,P1>(Which,P0,P1);
///
/// #[derive(Debug,Copy,Clone,PartialEq)]
/// enum Which{
/// First,
/// Second,
/// }
///
/// impl<P0,P1> IsSingleFieldPath for Choose<P0,P1>{}
///
/// impl<P0,P1,T> RevFieldType<T> for Choose<P0,P1>
/// where
/// P0: RevFieldType<T>,
/// P1: RevFieldType<T, Ty=P0::Ty>,
/// {
/// type Ty = P0::Ty;
/// }
///
/// impl<P0,P1,T> RevFieldErr<T> for Choose<P0,P1>
/// where
/// P0: RevFieldErr<T>,
/// P1: RevFieldErr<T, Ty=P0::Ty, Err=P0::Err>,
/// {
/// type Err = P0::Err;
/// }
///
/// impl<'a,P0,P1,T> RevGetFieldImpl<'a,T> for Choose<P0,P1>
/// where
/// P0: RevGetFieldImpl<'a,T>,
/// P1: RevGetFieldImpl<'a,T, Ty=P0::Ty, Err=P0::Err>,
/// {
/// fn rev_get_field(self, this: &'a T) -> Result<&'a P0::Ty, P0::Err>{
/// match self.0 {
/// Which::First=>self.1.rev_get_field(this),
/// Which::Second=>self.2.rev_get_field(this),
/// }
/// }
/// }
///
/// unsafe impl<'a,P0,P1,T> RevGetFieldMutImpl<'a,T> for Choose<P0,P1>
/// where
/// P0: RevGetFieldMutImpl<'a,T>,
/// P1: RevGetFieldMutImpl<'a,T, Ty=P0::Ty, Err=P0::Err>,
/// {
/// fn rev_get_field_mut(self, this: &'a mut T) -> Result<&'a mut P0::Ty, P0::Err>{
/// match self.0 {
/// Which::First=>self.1.rev_get_field_mut(this),
/// Which::Second=>self.2.rev_get_field_mut(this),
/// }
/// }
///
/// unsafe fn rev_get_field_raw_mut(self, this: *mut T) -> Result<*mut P0::Ty, P0::Err>{
/// match self.0 {
/// Which::First=>self.1.rev_get_field_raw_mut(this),
/// Which::Second=>self.2.rev_get_field_raw_mut(this),
/// }
/// }
/// }
///
/// ```
pub unsafe
/////////////////////////////////////////////////////////////////////////////
/// Like `Into*Field::into_*field_`,except that the parameters are reversed,
///
/// `This` is the type we are accessing,and `Self` is a field path.
///
/// This is used by the
/// [`StructuralExt::into_field`](../../trait.StructuralExt.html#method.into_field)
/// and [`StructuralExt::box_into_field`](../../trait.StructuralExt.html#method.box_into_field)
/// method.
///
/// # Use as bound
///
/// For examples of using `RevIntoFieldImpl` as a bound look at example for:
///
/// - [RevIntoField](./trait.RevIntoField.html):
/// For infallible field access,generalerally struct fields,not inside of a nested enum.
///
/// - [OptRevIntoField](./trait.OptRevIntoField.html):
/// Fallible field access,generally for getting a field in a (potentially nested) enum.
///
/// # Example
///
/// This example demonstrates implementing `RevIntoFieldImpl`.
///
/// The transmute in this example is only sound because of the
/// `#[repr(transparent)]` attribute on the `Wrapper` struct,
/// and the reference to` T` is converted into a reference to `Wrapper<T>`.<br>
/// Transmutes like that are not sound in the more general case,
/// like transmuting from an arbitrary `Foo<T>` to `Foo<Newtype<T>>` using `std::mem::transmute`,
/// since the layout of `Foo` is allowed to change.
///
/// ```rust
/// use structural::{
/// field::{FailedAccess, RevFieldErr, RevFieldType, RevGetFieldImpl, RevIntoFieldImpl},
/// path::IsSingleFieldPath,
/// StructuralExt, fp,
/// };
///
/// use core::mem;
///
/// let mut tup=(3,5,8,13);
///
/// assert_eq!( tup.into_field(Wrapped(fp!(0))), Newtype(3) );
/// assert_eq!( tup.into_field(Wrapped(fp!(1))), Newtype(5) );
/// assert_eq!( tup.into_field(Wrapped(fp!(2))), Newtype(8) );
/// assert_eq!( tup.into_field(Wrapped(fp!(3))), Newtype(13) );
///
///
/// #[derive(Debug,Copy,Clone,PartialEq)]
/// struct Wrapped<P>(P);
///
/// #[repr(transparent)]
/// #[derive(Debug,Copy,Clone,PartialEq)]
/// pub struct Newtype<T:?Sized>(T);
///
/// impl<P> IsSingleFieldPath for Wrapped<P>{}
///
/// impl<P,T> RevFieldType<T> for Wrapped<P>
/// where
/// P: RevFieldType<T>,
/// {
/// type Ty = Newtype<P::Ty>;
/// }
///
/// impl<P,T> RevFieldErr<T> for Wrapped<P>
/// where
/// P: RevFieldErr<T>,
/// {
/// type Err = P::Err;
/// }
///
/// impl<P,T> RevIntoFieldImpl<T> for Wrapped<P>
/// where
/// P: RevIntoFieldImpl<T>,
/// P::Ty: Sized,
/// {
/// fn rev_into_field(self, this: T) -> Result<Self::Ty, Self::Err>
/// where
/// Self::Ty: Sized
/// {
/// self.0.rev_into_field(this)
/// .map(Newtype)
/// }
/// }
/// ```