@@ -146,7 +146,7 @@ use clone::Clone;
146
146
use cmp:: { PartialEq , Eq } ;
147
147
use default:: Default ;
148
148
use marker:: { Copy , Send , Sync , Sized } ;
149
- use ops:: { Deref , DerefMut , Drop } ;
149
+ use ops:: { Deref , DerefMut , Drop , FnOnce } ;
150
150
use option:: Option ;
151
151
use option:: Option :: { None , Some } ;
152
152
@@ -576,6 +576,137 @@ impl<'b, T: ?Sized> Ref<'b, T> {
576
576
_borrow : orig. _borrow . clone ( ) ,
577
577
}
578
578
}
579
+
580
+ /// Make a new `Ref` for a component of the borrowed data.
581
+ ///
582
+ /// The `RefCell` is already immutably borrowed, so this cannot fail.
583
+ ///
584
+ /// This is an associated function that needs to be used as `Ref::map(...)`.
585
+ /// A method would interfere with methods of the same name on the contents of a `RefCell`
586
+ /// used through `Deref`.
587
+ ///
588
+ /// # Example
589
+ ///
590
+ /// ```
591
+ /// # #![feature(cell_extras)]
592
+ /// use std::cell::{RefCell, Ref};
593
+ ///
594
+ /// let c = RefCell::new((5, 'b'));
595
+ /// let b1: Ref<(u32, char)> = c.borrow();
596
+ /// let b2: Ref<u32> = Ref::map(b1, |t| &t.0);
597
+ /// assert_eq!(*b2, 5)
598
+ /// ```
599
+ #[ unstable( feature = "cell_extras" , reason = "recently added" ) ]
600
+ #[ inline]
601
+ pub fn map < U : ?Sized , F > ( orig : Ref < ' b , T > , f : F ) -> Ref < ' b , U >
602
+ where F : FnOnce ( & T ) -> & U
603
+ {
604
+ Ref {
605
+ _value : f ( orig. _value ) ,
606
+ _borrow : orig. _borrow ,
607
+ }
608
+ }
609
+
610
+ /// Make a new `Ref` for a optional component of the borrowed data, e.g. an enum variant.
611
+ ///
612
+ /// The `RefCell` is already immutably borrowed, so this cannot fail.
613
+ ///
614
+ /// This is an associated function that needs to be used as `Ref::filter_map(...)`.
615
+ /// A method would interfere with methods of the same name on the contents of a `RefCell`
616
+ /// used through `Deref`.
617
+ ///
618
+ /// # Example
619
+ ///
620
+ /// ```
621
+ /// # #![feature(cell_extras)]
622
+ /// use std::cell::{RefCell, Ref};
623
+ ///
624
+ /// let c = RefCell::new(Ok(5));
625
+ /// let b1: Ref<Result<u32, ()>> = c.borrow();
626
+ /// let b2: Ref<u32> = Ref::filter_map(b1, |o| o.as_ref().ok()).unwrap();
627
+ /// assert_eq!(*b2, 5)
628
+ /// ```
629
+ #[ unstable( feature = "cell_extras" , reason = "recently added" ) ]
630
+ #[ inline]
631
+ pub fn filter_map < U : ?Sized , F > ( orig : Ref < ' b , T > , f : F ) -> Option < Ref < ' b , U > >
632
+ where F : FnOnce ( & T ) -> Option < & U >
633
+ {
634
+ f ( orig. _value ) . map ( move |new| Ref {
635
+ _value : new,
636
+ _borrow : orig. _borrow ,
637
+ } )
638
+ }
639
+ }
640
+
641
+ impl < ' b , T : ?Sized > RefMut < ' b , T > {
642
+ /// Make a new `RefMut` for a component of the borrowed data, e.g. an enum variant.
643
+ ///
644
+ /// The `RefCell` is already mutably borrowed, so this cannot fail.
645
+ ///
646
+ /// This is an associated function that needs to be used as `RefMut::map(...)`.
647
+ /// A method would interfere with methods of the same name on the contents of a `RefCell`
648
+ /// used through `Deref`.
649
+ ///
650
+ /// # Example
651
+ ///
652
+ /// ```
653
+ /// # #![feature(cell_extras)]
654
+ /// use std::cell::{RefCell, RefMut};
655
+ ///
656
+ /// let c = RefCell::new((5, 'b'));
657
+ /// {
658
+ /// let b1: RefMut<(u32, char)> = c.borrow_mut();
659
+ /// let mut b2: RefMut<u32> = RefMut::map(b1, |t| &mut t.0);
660
+ /// assert_eq!(*b2, 5);
661
+ /// *b2 = 42;
662
+ /// }
663
+ /// assert_eq!(*c.borrow(), (42, 'b'));
664
+ /// ```
665
+ #[ unstable( feature = "cell_extras" , reason = "recently added" ) ]
666
+ #[ inline]
667
+ pub fn map < U : ?Sized , F > ( orig : RefMut < ' b , T > , f : F ) -> RefMut < ' b , U >
668
+ where F : FnOnce ( & mut T ) -> & mut U
669
+ {
670
+ RefMut {
671
+ _value : f ( orig. _value ) ,
672
+ _borrow : orig. _borrow ,
673
+ }
674
+ }
675
+
676
+ /// Make a new `RefMut` for a optional component of the borrowed data, e.g. an enum variant.
677
+ ///
678
+ /// The `RefCell` is already mutably borrowed, so this cannot fail.
679
+ ///
680
+ /// This is an associated function that needs to be used as `RefMut::filter_map(...)`.
681
+ /// A method would interfere with methods of the same name on the contents of a `RefCell`
682
+ /// used through `Deref`.
683
+ ///
684
+ /// # Example
685
+ ///
686
+ /// ```
687
+ /// # #![feature(cell_extras)]
688
+ /// use std::cell::{RefCell, RefMut};
689
+ ///
690
+ /// let c = RefCell::new(Ok(5));
691
+ /// {
692
+ /// let b1: RefMut<Result<u32, ()>> = c.borrow_mut();
693
+ /// let mut b2: RefMut<u32> = RefMut::filter_map(b1, |o| o.as_mut().ok()).unwrap();
694
+ /// assert_eq!(*b2, 5);
695
+ /// *b2 = 42;
696
+ /// }
697
+ /// assert_eq!(*c.borrow(), Ok(42));
698
+ /// ```
699
+ #[ unstable( feature = "cell_extras" , reason = "recently added" ) ]
700
+ #[ inline]
701
+ pub fn filter_map < U : ?Sized , F > ( orig : RefMut < ' b , T > , f : F ) -> Option < RefMut < ' b , U > >
702
+ where F : FnOnce ( & mut T ) -> Option < & mut U >
703
+ {
704
+ let RefMut { _value, _borrow } = orig;
705
+ f ( _value) . map ( move |new| RefMut {
706
+ _value : new,
707
+ _borrow : _borrow,
708
+ } )
709
+ }
579
710
}
580
711
581
712
struct BorrowRefMut < ' b > {
0 commit comments