# [−][src]Crate scopeguard

A scope guard will run a given closure when it goes out of scope, even if the code between panics. (as long as panic doesn't abort)

# Examples

## `defer!`

Use the `defer` macro to run an operation at scope exit, either regular scope exit or during unwinding from a panic.

    #[macro_use(defer)] extern crate scopeguard;

    use std::cell::Cell;

    fn main() {
        // use a cell to observe drops during and after the scope guard is active
        let drop_counter = Cell::new(0);
        {
            // Create a scope guard using `defer!` for the current scope
            defer! {{
                drop_counter.set(1 + drop_counter.get());
            }};

            // Do regular operations here in the meantime.

            // Just before scope exit: it hasn't run yet.
            assert_eq!(drop_counter.get(), 0);

            // The following scope end is where the defer closure is called
        }
        assert_eq!(drop_counter.get(), 1);
    }

## Scope Guard with Value

If the scope guard closure needs to access an outer value that is also mutated outside of the scope guard, then you may want to use the scope guard with a value. The guard works like a smart pointer, so the inner value can be accessed by reference or by mutable reference.

### 1. The guard owns a file

In this example, the scope guard owns a file and ensures pending writes are synced at scope exit.

    extern crate scopeguard;

    use std::fs::File;
    use std::io::{self, Write};

    fn try_main() -> io::Result<()> {
        let f = File::create("newfile.txt")?;
        let mut file = scopeguard::guard(f, |f| {
            // ensure we flush file at return or panic
            let _ = f.sync_all();
        });
        // Access the file through the scope guard itself
        file.write(b"test me\n").map(|_| ())
    }

    fn main() {
        try_main().unwrap();
    }

### 2. The guard restores an invariant on scope exit

    extern crate scopeguard;

    use std::mem::ManuallyDrop;
    use std::ptr;

    // This function, just for this example, takes the first element
    // and inserts it into the assumed sorted tail of the vector.
    //
    // For optimization purposes we temporarily violate an invariant of the
    // Vec, that it owns all of its elements.
    //
    // The safe approach is to use swap, which means two writes to memory,
    // the optimization is to use a “hole” which uses only one write of memory
    // for each position it moves.
    //
    // We *must* use a scope guard to run this code safely. We
    // are running arbitrary user code (comparison operators) that may panic.
    // The scope guard ensures we restore the invariant after successful
    // exit or during unwinding from panic.
    fn insertion_sort_first<T>(v: &mut Vec<T>)
        where T: PartialOrd
    {
        struct Hole<'a, T: 'a> {
            v: &'a mut Vec<T>,
            index: usize,
            value: ManuallyDrop<T>,
        }

        unsafe {
            // Create a moved-from location in the vector, a “hole”.
            let value = ptr::read(&v[0]);
            let mut hole = Hole { v: v, index: 0, value: ManuallyDrop::new(value) };

            // Use a scope guard with a value.
            // At scope exit, plug the hole so that the vector is fully
            // initialized again.
            // The scope guard owns the hole, but we can access it through the guard.
            let mut hole_guard = scopeguard::guard(hole, |hole| {
                // plug the hole in the vector with the value that was // taken out
                let index = hole.index;
                ptr::copy_nonoverlapping(&*hole.value, &mut hole.v[index], 1);
            });

            // run algorithm that moves the hole in the vector here
            // move the hole until it's in a sorted position
            for i in 1..hole_guard.v.len() {
                if *hole_guard.value >= hole_guard.v[i] {
                    // move the element back and the hole forward
                    let index = hole_guard.index;
                    ptr::copy_nonoverlapping(&hole_guard.v[index + 1], &mut hole_guard.v[index], 1);
                    hole_guard.index += 1;
                } else {
                    break;
                }
            }

            // When the scope exits here, the Vec becomes whole again!
        }
    }

    fn main() {
        let string = String::from;
        let mut data = vec![string("c"), string("a"), string("b"), string("d")];
        insertion_sort_first(&mut data);
        assert_eq!(data, vec!["a", "b", "c", "d"]);
    }

# Crate features:

- `use_std`
  - Enabled by default. Enables the `OnUnwind` strategy.
  - Disable to use `no_std`.

## Macros

defer | Macro to create a `ScopeGuard` (always run).
defer_on_unwind | Macro to create a `ScopeGuard` (run on unwinding from panic).

## Structs

ScopeGuard | `ScopeGuard` is a scope guard that may own a protected value.

## Enums

Always | Always run on scope exit.

## Traits

Strategy |

## Functions

guard | Create a new `ScopeGuard` owning `v` and with deferred closure `dropfn`.

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g., `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g., `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g., `str,u8` or `String,struct:Vec,test`)