1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
//! `projection` provides you easy access struct fields of a Option<T>. //! //! # Examples //! //! To use `projection`, you first need to annotate your type with the `projection` attribute //! //! ``` //! use ::projection::projection; //! #[projection] //! struct AType { //! a: u32, //! b: u32 //! } //! ``` //! //! Then, you can use `project()` to access fields of `AType` from a `Option<AType>` //! //! ``` //! # use ::projection::projection; //! # #[projection] //! # struct AType { //! # a: u32, //! # b: u32 //! # } //! use ::projection::prelude::*; //! //! let var: Option<AType> = None; //! let var = var.project(); //! assert_eq!(var.a, None); //! //! let var = Some(AType { a: 1, b: 1 }); //! let var = var.project(); //! assert_eq!(var.a, Some(1)); //! //! // You can choose to borrow the values //! let mut var = Some(AType { a: 1, b: 1 }); //! let var = var.as_mut().project(); //! assert_eq!(var.a, Some(&mut 1)); //! //! let var = Some(AType { a: 1, b: 1 }); //! let var = var.as_ref().project(); //! assert_eq!(var.a, Some(&1)); //! ``` pub use projection_macros::projection; pub mod prelude { /// Implemented for `T` where a projection can be created for `Option<T>` pub trait OptionProjectable: Sized { type P; fn project(f: Option<Self>) -> Self::P; } #[doc(hidden)] pub trait ResultProjectable<E>: Sized { type P; fn project(f: Result<Self, E>) -> Self::P; } /// Provides `.project()` for `Option<T>` pub trait Projectable { type P; fn project(self) -> Self::P; } impl<T: OptionProjectable> Projectable for Option<T> { type P = <T as OptionProjectable>::P; fn project(self) -> <T as OptionProjectable>::P { OptionProjectable::project(self) } } impl<E, T: ResultProjectable<E>> Projectable for Result<T, E> { type P = <T as ResultProjectable<E>>::P; fn project(self) -> <T as ResultProjectable<E>>::P { ResultProjectable::project(self) } } } pub use crate::prelude::*;