1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
#![cfg_attr(feature = "nightly", feature(external_doc), doc(include = "../README.md") )] #![allow(nonstandard_style)] #[must_use = "You need to call `.try_eval()`"] pub const fn with_state<State> (state: State) -> Runner<State> { Runner { state } } pub struct Runner<State> { state: State, } pub struct RunnerWithTryEval<State, try_eval> { state: State, try_eval: try_eval, } impl<State> Runner<State> { #[must_use = "`.try_eval()` is lazy and does nothing: you need to call `.finally()`" ] pub fn try_eval<R, try_eval> ( self: Runner<State>, __: try_eval, ) -> RunnerWithTryEval<State, try_eval> where try_eval: FnOnce(&'_ mut State) -> R, { let Runner { state } = self; RunnerWithTryEval { state, try_eval: __, } } #[doc(hidden)] pub fn finally<R, F> ( self: Runner<State>, _: F, ) -> R where Self : __::missing_try_eval<F>, { <Self as __::missing_try_eval<F>>::unreachable() } } mod __ { pub trait missing_try_eval<F> { fn unreachable() -> !; } } impl<State, try_eval> RunnerWithTryEval<State, try_eval> { pub fn finally<R, finally> ( self: RunnerWithTryEval<State, try_eval>, __: finally, ) -> R where try_eval: FnOnce(&'_ mut State) -> R, finally: FnOnce(State), { use ::core::mem::ManuallyDrop as MD; struct WithDrop<State, Finally> where Finally : FnOnce(State), { state: MD<State>, finally: MD<Finally>, } impl<State, Finally> Drop for WithDrop<State, Finally> where Finally : FnOnce(State), { fn drop (self: &'_ mut Self) { unsafe { let state = MD::take(&mut self.state); let finally = MD::take(&mut self.finally); let () = finally(state); } } } let RunnerWithTryEval { state, try_eval } = self; let ref mut state_with_drop = WithDrop { state: MD::new(state), finally: MD::new(__), }; try_eval(&mut state_with_drop.state) } } #[cfg(all(doc, feature = "nightly"))] #[doc(include = "compile_fail_tests.md")] mod compile_fail_tests {}