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