1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! The Finally trait provides a method, `finally` on
12 //! stack closures that emulates Java-style try/finally blocks.
14 //! Using the `finally` method is sometimes convenient, but the type rules
15 //! prohibit any shared, mutable state between the "try" case and the
16 //! "finally" case. For advanced cases, the `try_finally` function can
17 //! also be used. See that function for more details.
22 //! use std::finally::Finally;
27 //! // this code is always run
35 /// A trait for executing a destructor unconditionally after a block of code,
36 /// regardless of whether the blocked fails.
37 pub trait Finally<T> {
38 /// Executes this object, unconditionally running `dtor` after this block of
40 fn finally(&mut self, dtor: ||) -> T;
43 impl<'a,T> Finally<T> for ||: 'a -> T {
44 fn finally(&mut self, dtor: ||) -> T {
45 try_finally(&mut (), self,
51 impl<T> Finally<T> for fn() -> T {
52 fn finally(&mut self, dtor: ||) -> T {
53 try_finally(&mut (), (),
60 * The most general form of the `finally` functions. The function
61 * `try_fn` will be invoked first; whether or not it panics, the
62 * function `finally_fn` will be invoked next. The two parameters
63 * `mutate` and `drop` are used to thread state through the two
64 * closures. `mutate` is used for any shared, mutable state that both
65 * closures require access to; `drop` is used for any state that the
66 * `try_fn` requires ownership of.
68 * **WARNING:** While shared, mutable state between the try and finally
69 * function is often necessary, one must be very careful; the `try`
70 * function could have panicked at any point, so the values of the shared
71 * state may be inconsistent.
76 * use std::finally::try_finally;
78 * struct State<'a> { buffer: &'a mut [u8], len: uint }
80 * let mut state = State { buffer: &mut buf, len: 0 };
84 * // use state.buffer, state.len
87 * // use state.buffer, state.len to cleanup
91 pub fn try_finally<T,U,R>(mutate: &mut T,
93 try_fn: |&mut T, U| -> R,
96 let f = Finallyalizer {
100 try_fn(&mut *f.mutate, drop)
103 struct Finallyalizer<'a,A:'a> {
109 impl<'a,A> Drop for Finallyalizer<'a,A> {
112 (self.dtor)(self.mutate);