mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 09:25:01 +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.
|
||||
///
|
||||
/// 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`.
|
||||
pub fn user_data<T: Any>(&mut self) -> Option<&mut T> {
|
||||
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.
|
||||
///
|
||||
/// 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.
|
||||
pub fn with_user_data<F, T, R>(&mut self, f: F) -> Option<R>
|
||||
where
|
||||
|
Loading…
Reference in New Issue
Block a user