mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add Cursive::take_user_data
This commit is contained in:
parent
a159753ad1
commit
fb0d26fb4a
@ -214,15 +214,63 @@ impl Cursive {
|
|||||||
|
|
||||||
/// Attempts to access the user-provided data.
|
/// Attempts to access the user-provided data.
|
||||||
///
|
///
|
||||||
/// If some data was set previously with the same type, returns a reference to it.
|
/// If some data was set previously with the same type, returns a
|
||||||
|
/// reference to it.
|
||||||
|
///
|
||||||
/// If nothing was set or if the type is different, returns `None`.
|
/// If nothing was set or if the type is different, returns `None`.
|
||||||
pub fn user_data<T: Any>(&mut self) -> Option<&mut T> {
|
pub fn user_data<T: Any>(&mut self) -> Option<&mut T> {
|
||||||
self.user_data.downcast_mut()
|
self.user_data.downcast_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attemps to take by value the current user-data.
|
||||||
|
///
|
||||||
|
/// If successful, this will replace the current user-data with the unit
|
||||||
|
/// type `()`.
|
||||||
|
///
|
||||||
|
/// If the current user data is not of the requested type, `None` will be
|
||||||
|
/// returned.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// let mut siv = cursive::Cursive::dummy();
|
||||||
|
///
|
||||||
|
/// // Start with a simple `Vec<i32>` as user data.
|
||||||
|
/// siv.set_user_data(vec![1i32, 2, 3]);
|
||||||
|
/// assert_eq!(siv.user_data::<Vec<i32>>(), Some(&mut vec![1i32, 2, 3]));
|
||||||
|
///
|
||||||
|
/// // Let's mutate the data a bit.
|
||||||
|
/// siv.with_user_data(|numbers: &mut Vec<i32>| numbers.push(4));
|
||||||
|
///
|
||||||
|
/// // If mutable reference is not enough, we can take the data by value.
|
||||||
|
/// let data: Vec<i32> = siv.take_user_data().unwrap();
|
||||||
|
/// assert_eq!(data, vec![1i32, 2, 3, 4]);
|
||||||
|
///
|
||||||
|
/// // At this point the user data was removed and is no longer available.
|
||||||
|
/// assert_eq!(siv.user_data::<Vec<i32>>(), None);
|
||||||
|
/// ```
|
||||||
|
pub fn take_user_data<T: Any>(&mut self) -> Option<T> {
|
||||||
|
// Start by taking the user data and replacing it with a dummy.
|
||||||
|
let user_data = std::mem::replace(&mut self.user_data, Box::new(()));
|
||||||
|
|
||||||
|
// Downcast the data to the requested type.
|
||||||
|
// If it works, unbox it.
|
||||||
|
// It if doesn't, take it back.
|
||||||
|
user_data
|
||||||
|
.downcast()
|
||||||
|
.map_err(|user_data| {
|
||||||
|
// If we asked for the wrong type, put it back.
|
||||||
|
self.user_data = user_data;
|
||||||
|
})
|
||||||
|
.map(|boxed| *boxed)
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
/// Runs the given closure on the stored user data, if any.
|
/// Runs the given closure on the stored user data, if any.
|
||||||
///
|
///
|
||||||
/// If no user data was supplied, or if the type is different, nothing will be run.
|
/// If no user data was supplied, or if the type is different, nothing
|
||||||
|
/// will be run.
|
||||||
|
///
|
||||||
/// Otherwise, the result will be returned.
|
/// Otherwise, the result will be returned.
|
||||||
pub fn with_user_data<F, T, R>(&mut self, f: F) -> Option<R>
|
pub fn with_user_data<F, T, R>(&mut self, f: F) -> Option<R>
|
||||||
where
|
where
|
||||||
|
Loading…
Reference in New Issue
Block a user