1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- use core::{mem, intrinsics};
- struct ExitGuard;
- impl Drop for ExitGuard {
- fn drop(&mut self) {
-
-
- log!(ERROR, "Unwinding in a `take` closure.");
-
- unsafe { intrinsics::abort(); }
- }
- }
- #[inline]
- pub fn replace_with<T, F>(val: &mut T, replace: F)
- where F: FnOnce(T) -> T {
-
- let guard = ExitGuard;
- unsafe {
-
- let old = ptr::read(val);
-
- let new = closure(old);
-
- ptr::write(val, new);
- }
-
- mem::forget(guard);
- }
- #[cfg(test)]
- mod test {
- use super::*;
- use core::cell::Cell;
- #[test]
- fn replace_with() {
- let mut x = Some("test");
- replace_with(&mut x, |_| None);
- assert!(x.is_none());
- }
- #[test]
- fn replace_with_2() {
- let is_called = Cell::new(false);
- let mut x = 2;
- replace_with(&mut x, |_| {
- is_called.set(true);
- 3
- });
- assert!(is_called.get());
- }
- }
|