Skip to content

Commit af6442f

Browse files
committed
update tests and api for try map ref
1 parent c1602a7 commit af6442f

File tree

1 file changed

+67
-38
lines changed

1 file changed

+67
-38
lines changed

sdk/pinocchio/src/account_info.rs

Lines changed: 67 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Data structures to represent account information.
22
33
use core::{
4-
convert::Infallible,
54
marker::PhantomData,
65
mem::ManuallyDrop,
76
ptr::{write, NonNull},
@@ -662,25 +661,36 @@ impl<'a, T: ?Sized> Ref<'a, T> {
662661
pub fn map<U: ?Sized, F>(orig: Ref<'a, T>, f: F) -> Ref<'a, U>
663662
where
664663
F: FnOnce(&T) -> &U,
665-
{
666-
Self::try_map::<_, _, Infallible>(orig, |x| Ok(f(x))).unwrap()
667-
}
668-
669-
/// Maps a reference to a new type in a fallible map, returning an error if the map fails.
670-
#[inline]
671-
pub fn try_map<U: ?Sized, F, E>(orig: Ref<'a, T>, f: F) -> Result<Ref<'a, U>, E>
672-
where
673-
F: FnOnce(&T) -> Result<&U, E>,
674664
{
675665
// Avoid decrementing the borrow flag on Drop.
676666
let orig = ManuallyDrop::new(orig);
677-
678-
Ok(Ref {
679-
value: NonNull::from(f(&*orig)?),
667+
Ref {
668+
value: NonNull::from(f(&*orig)),
680669
state: orig.state,
681670
borrow_shift: orig.borrow_shift,
682671
marker: PhantomData,
683-
})
672+
}
673+
}
674+
675+
/// Tries to makes a new `Ref` for a component of the borrowed data.
676+
/// On failure, the original guard is returned alongside with the error
677+
/// returned by the closure.
678+
#[inline]
679+
pub fn try_map<U: ?Sized, E>(
680+
orig: Ref<'a, T>,
681+
f: impl FnOnce(&T) -> Result<&U, E>,
682+
) -> Result<Ref<'a, U>, (Self, E)> {
683+
// Avoid decrementing the borrow flag on Drop.
684+
let orig = ManuallyDrop::new(orig);
685+
match f(&*orig) {
686+
Ok(value) => Ok(Ref {
687+
value: NonNull::from(value),
688+
state: orig.state,
689+
borrow_shift: orig.borrow_shift,
690+
marker: PhantomData,
691+
}),
692+
Err(e) => Err((ManuallyDrop::into_inner(orig), e)),
693+
}
684694
}
685695

686696
/// Filters and maps a reference to a new type.
@@ -743,26 +753,36 @@ impl<'a, T: ?Sized> RefMut<'a, T> {
743753
pub fn map<U: ?Sized, F>(orig: RefMut<'a, T>, f: F) -> RefMut<'a, U>
744754
where
745755
F: FnOnce(&mut T) -> &mut U,
746-
{
747-
Self::try_map::<_, _, Infallible>(orig, |x| Ok(f(x))).unwrap()
748-
}
749-
750-
/// Maps a mutable reference to a new type in a fallible map, returning an error if the map fails.
751-
#[inline]
752-
pub fn try_map<U: ?Sized, F, E>(orig: RefMut<'a, T>, f: F) -> Result<RefMut<'a, U>, E>
753-
where
754-
F: FnOnce(&mut T) -> Result<&mut U, E>,
755756
{
756757
// Avoid decrementing the borrow flag on Drop.
757758
let mut orig = ManuallyDrop::new(orig);
758-
let value = f(&mut *orig)?;
759-
760-
Ok(RefMut {
761-
value: NonNull::from(value),
759+
RefMut {
760+
value: NonNull::from(f(&mut *orig)),
762761
state: orig.state,
763762
borrow_bitmask: orig.borrow_bitmask,
764763
marker: PhantomData,
765-
})
764+
}
765+
}
766+
767+
/// Tries to makes a new `RefMut` for a component of the borrowed data.
768+
/// On failure, the original guard is returned alongside with the error
769+
/// returned by the closure.
770+
#[inline]
771+
pub fn try_map<U: ?Sized, E>(
772+
orig: RefMut<'a, T>,
773+
f: impl FnOnce(&mut T) -> Result<&mut U, E>,
774+
) -> Result<RefMut<'a, U>, (Self, E)> {
775+
// Avoid decrementing the borrow flag on Drop.
776+
let mut orig = ManuallyDrop::new(orig);
777+
match f(&mut *orig) {
778+
Ok(value) => Ok(RefMut {
779+
value: NonNull::from(value),
780+
state: orig.state,
781+
borrow_bitmask: orig.borrow_bitmask,
782+
marker: PhantomData,
783+
}),
784+
Err(e) => Err((ManuallyDrop::into_inner(orig), e)),
785+
}
766786
}
767787

768788
/// Filters and maps a mutable reference to a new type.
@@ -773,17 +793,13 @@ impl<'a, T: ?Sized> RefMut<'a, T> {
773793
{
774794
// Avoid decrementing the mutable borrow flag on Drop.
775795
let mut orig = ManuallyDrop::new(orig);
776-
777796
match f(&mut *orig) {
778-
Some(value) => {
779-
let value = NonNull::from(value);
780-
Ok(RefMut {
781-
value,
782-
state: orig.state,
783-
borrow_bitmask: orig.borrow_bitmask,
784-
marker: PhantomData,
785-
})
786-
}
797+
Some(value) => Ok(RefMut {
798+
value: NonNull::from(value),
799+
state: orig.state,
800+
borrow_bitmask: orig.borrow_bitmask,
801+
marker: PhantomData,
802+
}),
787803
None => Err(ManuallyDrop::into_inner(orig)),
788804
}
789805
}
@@ -841,6 +857,19 @@ mod tests {
841857
assert_eq!(state, NOT_BORROWED - (1 << DATA_BORROW_SHIFT));
842858
assert_eq!(*new_ref, 3);
843859

860+
let Ok(new_ref) = Ref::try_map::<_, u8>(new_ref, |_| Ok(&4)) else {
861+
unreachable!()
862+
};
863+
864+
assert_eq!(state, NOT_BORROWED - (1 << DATA_BORROW_SHIFT));
865+
assert_eq!(*new_ref, 4);
866+
867+
let (new_ref, err) = Ref::try_map::<u8, u8>(new_ref, |_| Err(5)).unwrap_err();
868+
assert_eq!(state, NOT_BORROWED - (1 << DATA_BORROW_SHIFT));
869+
assert_eq!(err, 5);
870+
// Unchanged
871+
assert_eq!(*new_ref, 4);
872+
844873
let new_ref = Ref::filter_map(new_ref, |_| Option::<&u8>::None);
845874

846875
assert_eq!(state, NOT_BORROWED - (1 << DATA_BORROW_SHIFT));

0 commit comments

Comments
 (0)