# Try_v2

 Provides a derive macro for `Try` & optionally `Try_ConvertResult` for interconversion with
 `std::result::Result` and `Try_Iterator` for iterating over `IntoIterator` and collecting from
 `FromIterator` analogous to how `Result` & `Option` do this.
 See ([try_trait_v2](https://rust-lang.github.io/rfcs/3058-try-trait-v2.html)) for more details
 of the underlying trait.

## Requires

- nightly
- `#![feature(never_type)]`
- `#![feature(try_trait_v2)]`
- `#![feature(try_trait_v2_residual)]`
- optionally: `#![feature(iterator_try_collect)]` (if using Try_Iterator)

## Limitations on the annotated type

- must be an `enum`
- must have _at least one_ generic type
- the _first_ generic type must be the `Output` type (produced when not short circuiting)
- the output variant (does not short-circuit) must be the _first_ variant and store the output type as the _only unnamed_ field

See the [full documentation](https://docs.rs/try_v2/latest/try_v2/) for specifics on the generated code.

## Example Usage

```rust
#![feature(never_type)]
#![feature(try_trait_v2)]
#![feature(try_trait_v2_residual)]
use try_v2::{Try, Try_ConvertResult};

#[derive(Try, Try_ConvertResult)]
enum TestResult<T> {
    Ok(T),
    TestsFailed,
    OtherError(String)
}

// Basic short circuiting thanks to `#[derive(Try)]`
fn run_tests() -> TestResult<()> {
    TestResult::OtherError("oops!".to_string())?; // <- Function short-circuits here ...
    TestResult::TestsFailed?;
    TestResult::Ok(())
}

assert!(matches!(run_tests(), TestResult::OtherError(msg) if msg == "oops!"));


// Conversion from std::result::Result thanks to `#[derive(Try_ConvertResult)]`
struct TestFailure {}

impl<T> From<TestFailure> for TestResult<T> {
    fn from(err: TestFailure) -> Self {
        TestResult::TestsFailed
    }
}

fn run_more_tests() -> TestResult<()> {
    std::result::Result::Err(TestFailure{})?; // <- Function short-circuits here & converts to a TestResult...
    TestResult::Ok(())
}

assert!(matches!(run_more_tests(), TestResult::TestsFailed));
```

## Stability & MSRV

Given that this crate exposes an experimental API from std it makes use of experimental
features which require a nightly toolchain.

In order to use this crate you must enable the features which it exposes:

> 🔬 **Required Experimental Features**
>
> - [`#![feature(never_type)]`](https://github.com/rust-lang/rust/issues/35121)
> - [`#![feature(try_trait_v2)]`](https://github.com/rust-lang/rust/issues/84277)
> - [`#![feature(try_trait_v2_residual)]`](https://github.com/rust-lang/rust/issues/91285)
> - optionally: [`#![feature(iterator_try_collect)]`](https://github.com/rust-lang/rust/issues/94047) (if using `Try_Iterator`)

This crate makes use of the following experimental features in addition to those which it directly supports:

> 🔬 **Additional Experimental Features**
>
> - [`#![feature(if_let_guard)]`](https://github.com/rust-lang/rust/issues/51114) (stable since 1.95.0)
> - [`#![feature(let_chains)]`](https://github.com/rust-lang/rust/issues/53667) (stable since 1.88.0 on 2024 only)
>
> This list includes any unstable features used by direct & transitive dependencies (currently, none).
>
> You do not need to enable these in your own code, the list is for information only.

### Stability guarantees

 We run automated tests **every month** to ensure no fundamental changes affect this crate and
 test every PR against the current nightly, as well as the current equivalent beta & stable.
 If you find an issue before we do, please
 [raise an issue on github](https://github.com/MusicalNinjaDad/try_v2/issues).

### MSRV

 For those of you working with a pinned nightly (etc.) this crate supports every version of
 edition 2024 (rust 1.85.1 onwards, released as stable on 2025-03-18). We use
 [autocfg](https://crates.io/crates/autocfg/) to seamlessly handle features which have been
 stabilised since then.

## Currently untested (may work, may not ...)

- `where` clauses
- storing `Fn`s in variants
