@@ -781,6 +781,47 @@ impl<'a, T: ?Sized> GcCellRef<'a, T> {
781
781
}
782
782
}
783
783
784
+ /// Makes a new `GcCellRef` for an optional component of the borrowed data.
785
+ /// The original guard is returned as an `Err(..)` if the closure returns
786
+ /// `None`.
787
+ ///
788
+ /// The `GcCell` is already immutably borrowed, so this cannot fail.
789
+ ///
790
+ /// This is an associated function that needs to be used as
791
+ /// `GcCellRef::filter_map(...)`. A method would interfere with methods of
792
+ /// the same name on the contents of a `GcCellRef` used through `Deref`.
793
+ ///
794
+ /// # Examples
795
+ ///
796
+ /// ```
797
+ /// use gc::{GcCell, GcCellRef};
798
+ ///
799
+ /// let c = GcCell::new(vec![1, 2, 3]);
800
+ /// let b1: GcCellRef<Vec<u32>> = c.borrow();
801
+ /// let b2: Result<GcCellRef<u32>, _> = GcCellRef::filter_map(b1, |v| v.get(1));
802
+ /// assert_eq!(*b2.unwrap(), 2);
803
+ /// ```
804
+ #[ inline]
805
+ pub fn filter_map < U , F > ( orig : Self , f : F ) -> Result < GcCellRef < ' a , U > , Self >
806
+ where
807
+ U : ?Sized ,
808
+ F : FnOnce ( & T ) -> Option < & U > ,
809
+ {
810
+ match f ( orig. value ) {
811
+ None => Err ( orig) ,
812
+ Some ( value) => {
813
+ // We have to tell the compiler not to call the destructor of GcCellRef,
814
+ // because it will update the borrow flags.
815
+ let orig = ManuallyDrop :: new ( orig) ;
816
+
817
+ Ok ( GcCellRef {
818
+ flags : orig. flags ,
819
+ value,
820
+ } )
821
+ }
822
+ }
823
+ }
824
+
784
825
/// Splits a `GcCellRef` into multiple `GcCellRef`s for different components of the borrowed data.
785
826
///
786
827
/// The `GcCell` is already immutably borrowed, so this cannot fail.
0 commit comments