@@ -781,6 +781,47 @@ impl<'a, T: ?Sized> GcCellRef<'a, T> {
781781 }
782782 }
783783
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+
784825 /// Splits a `GcCellRef` into multiple `GcCellRef`s for different components of the borrowed data.
785826 ///
786827 /// The `GcCell` is already immutably borrowed, so this cannot fail.
0 commit comments