diff --git a/.github/workflows/rust-publish.yml b/.github/workflows/rust-publish.yml index dfe502d..f578fa4 100644 --- a/.github/workflows/rust-publish.yml +++ b/.github/workflows/rust-publish.yml @@ -21,10 +21,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - - uses: rust-lang/crates-io-auth-action@bbd81622f20ce9e2dd9622e3218b975523e45bbe #v1.0.4 - id: auth + # - uses: rust-lang/crates-io-auth-action@bbd81622f20ce9e2dd9622e3218b975523e45bbe #v1.0.4 + # id: auth - name: Publish env: - CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} + # CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} run: cargo publish diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 3815669..a67f6c7 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -63,6 +63,13 @@ jobs: if: needs.skip_check.outputs.should_skip != 'true' runs-on: ubuntu-latest + strategy: + matrix: + crate: ["try_v2", "try_v2_derive"] + + defaults: + run: + working-directory: crates/${{ matrix.crate }} env: RUSTC_BOOTSTRAP: 1 diff --git a/CHANGELOG.md b/CHANGELOG.md index f8b9ce5..955d0ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog try_v2 +## [v0.5.0] + +### New features + +- Add `trait Transform` (Forces move of derive macros to own crate & re-export) + +### Breaking changes + +- Removed derive `Try_Methods` in favour of trait-based implementation + ## [v0.4.2] ### Bugfixes diff --git a/Cargo.toml b/Cargo.toml index a79dab7..35f9420 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,36 +1,7 @@ -[package] -name = "try_v2" -version = "0.4.2" -edition = "2024" -readme = "README.md" -description = "Provides a derive macro for `Try` ([try_trait_v2](https://rust-lang.github.io/rfcs/3058-try-trait-v2.html))" -authors = ["Mike Foster "] -keywords = ["derive", "Try", "try_trait_v2"] -homepage = "https://github.com/MusicalNinjaDad/try_v2" -repository = "https://github.com/MusicalNinjaDad/try_v2" -categories = ["development-tools"] -license = "MIT" -rust-version = "1.85.1" -exclude = [".github", ".devcontainer"] - -[lib] -proc-macro = true - -[dependencies] -syn = {version = "2.0.117", features = ["full","extra-traits"]} -proc-macro2 = "1.0.106" -proc_macro2_diagnostic = "0.3.0" -quote = "1.0.45" - -[dev-dependencies] -log = "0.4.29" -trybuild = "1.0.116" - -[build-dependencies] -autocfg = "1.5.1" - [workspace] -members = ["tests/compilation"] +edition = "2024" +resolver = "3" +members = ["crates/*"] [workspace.dependencies] -try_v2 = { path = "."} +try_v2_derive = { path = "crates/try_v2_derive", version = "0.5.0" } diff --git a/README.md b/README.md index 5032102..8c78cd3 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,13 @@ # 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. + Provides: + +- a derive macro for `Try` +- traits with standard methods to make TryTypes usable (e.g. `trait Transform` provides `.map()`) +- derive `Try_ConvertResult` for interconversion with `std::result::Result` +- derive `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 diff --git a/crates/try_v2/Cargo.toml b/crates/try_v2/Cargo.toml new file mode 100644 index 0000000..675a5c8 --- /dev/null +++ b/crates/try_v2/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "try_v2" +version = "0.5.0" +edition = "2024" +readme = "README.md" +description = "Provides a derive macro & helper traits for `Try`" +authors = ["Mike Foster "] +keywords = ["derive", "Try", "try_trait_v2"] +homepage = "https://github.com/MusicalNinjaDad/try_v2" +repository = "https://github.com/MusicalNinjaDad/try_v2" +categories = ["development-tools"] +license = "MIT" +rust-version = "1.85.1" +exclude = [".github", ".devcontainer"] + +[lib] + +[dependencies] +try_v2_derive = { workspace = true } + +[dev-dependencies] + +[build-dependencies] diff --git a/crates/try_v2/src/lib.rs b/crates/try_v2/src/lib.rs new file mode 100644 index 0000000..fe0c88f --- /dev/null +++ b/crates/try_v2/src/lib.rs @@ -0,0 +1,123 @@ +#![feature(try_trait_v2)] +#![feature(try_trait_v2_residual)] +#![cfg_attr(test, feature(option_zip))] + +//! 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` analog 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 +//! - no other variant can store the Output type (TODO #72 add a nice error message) +//! +//! See the individual documentation for [Try], [Try_ConvertResult] and [Try_Iterator] 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 { +//! 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 From for TestResult { +//! 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/139951) (stable since 1.88.0) +//! > +//! > 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 + +#[doc(inline)] +pub use try_v2_derive::*; + +mod transform; +#[doc(inline)] +pub use transform::Transform; diff --git a/crates/try_v2/src/transform.rs b/crates/try_v2/src/transform.rs new file mode 100644 index 0000000..8baa0d0 --- /dev/null +++ b/crates/try_v2/src/transform.rs @@ -0,0 +1,323 @@ +use std::ops::{ControlFlow, FromResidual, Residual, Try}; + +/// Methods for transforming TryTypes. Inspired by the methods provided on `Option` & `Result` +/// +/// ## Note +/// +/// - Methods which act on the contained value are only available for the *Output* case. TryTypes +/// are recommended to directly implement equivalent methods for *Residual* cases with suitable +/// naming. E.g. we provide a `.map()` but not a `.map_err()` equivalent as multiple such +/// methods may be needed and no standardised naming makes sense. +/// - Methods which act on the contained value will extract a value of type `Output` and return the +/// *canonical TryType* for the new Output. This is identifiable by the generic type `X` in the +/// method signature. This is usually the expected behaviour but can lead to a different value +/// type or resulting TryType where `Try` is not implemented symmetrically. +/// - Generic type conventions used in signatures (in standard order): +/// - `X` the *canonical TryType* returned +/// - `Y` the other TryType +/// - `T` the `Output` type for `Self` +/// - `U` the other `Output` type +/// - `F` a function/closure passed as a parameter +/// - `G` the return type of `F` +/// - `R` *never used* to avoid confusion with "Residual". +pub trait Transform +where + Self: Try + Sized, +{ + /// Removes one level of nesting, converting `Foo>` to `Foo` + /// or from `Foo>` to `Bar` if suitable residual interconversion is implemented. + fn flatten(self) -> Y + where + Self: Try, + Y: FromResidual, + { + self? + } + + /// Calls a function with a reference to the contained value. Returns the original `Self` + fn inspect(self, f: F) -> Self + where + F: FnOnce(&Self::Output), + { + let val = self?; + f(&val); + Try::from_output(val) + } + + /// Extracts the contained value `v` returning `Some(v)`, or `None` in the case of a Residual + fn output(self) -> Option + where + Self: Try, + { + match self.branch() { + ControlFlow::Continue(val) => Some(val), + ControlFlow::Break(_) => None, + } + } + + /// Applies a function to the contained value converting `T` -> `U` then + /// returns the canonical TryType for `Self` with Output `U` + fn map(self, f: F) -> X + where + F: FnOnce(Self::Output) -> U, + X: Try + FromResidual, + Self::Residual: Residual, + { + let val = self?; + let mapped = f(val); + Try::from_output(mapped) + } + + fn map_or(self, default: U, f: F) -> U + where + F: FnOnce(Self::Output) -> U, + { + match self.branch() { + ControlFlow::Continue(val) => f(val), + ControlFlow::Break(_) => default, + } + } + + fn map_or_else(self, default: D, f: F) -> U + where + D: FnOnce() -> U, + F: FnOnce(Self::Output) -> U, + { + match self.branch() { + ControlFlow::Continue(val) => f(val), + ControlFlow::Break(_) => default(), + } + } + + /// Converts from a `Foo>` to a `Bar>` where both `Foo` & `Bar` are `Try`. + /// + /// # Note + /// + /// - Return types are *canonical TryTypes*, for asymetrical cases this may not be `Bar` & `Foo` + fn transpose(self) -> X + where + // Foo> + Self: Try, + // Bar + Y: Try, + // Bar> + X: Try + FromResidual<::Residual>, + // Foo: Try + FromResidual> + X::Output: Try + FromResidual, + // X *is* the canonical TryType for `Bar>` + Y::Residual: Residual, + // X *wraps* the canonical TryType for `Foo` + Self::Residual: Residual, + { + match self.branch() { + ControlFlow::Continue(inner_u) => match inner_u.branch() { + ControlFlow::Continue(val) => { + let inner_t = Try::from_output(val); + Try::from_output(inner_t) + } + ControlFlow::Break(u_residual) => FromResidual::from_residual(u_residual), + }, + ControlFlow::Break(t_residual) => { + let inner_t = FromResidual::from_residual(t_residual); + Try::from_output(inner_t) + } + } + } + + /// Combines a `Foo` with a `Bar` into a `Foo<(T,U)>` where residual interconversion + /// is available from `Bar->Foo`. Returns the *canonical TryType* based upon `Foo`. + fn zip(self, other: Y) -> X + where + Y: Try, + X: Try + + FromResidual + + FromResidual, + Self::Residual: Residual, + { + let v1 = self?; + let v2 = other?; + Try::from_output((v1, v2)) + } + + /// Applies function `f` to the values inside `Foo` & `Bar` where residual interconversion + /// is available from `Bar->Foo`. Returns the *canonical TryType* based upon `Foo`. + /// + /// TODO: #[unstable(feature = "option_zip", issue = "70086")] + fn zip_with(self, other: Y, f: F) -> X + where + Y: Try, + F: FnOnce(Self::Output, Y::Output) -> G, + X: Try + FromResidual + FromResidual, + Self::Residual: Residual, + { + let v1 = self?; + let v2 = other?; + Try::from_output(f(v1, v2)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + impl Transform for Option {} + impl Transform for Result {} + + mod flatten { + use super::*; + + #[test] + fn some_some() { + let some_5 = Some(Some(5)); + let stdlib = some_5.flatten(); + let custom = Transform::flatten(some_5); + assert_eq!(stdlib, custom) + } + } + + mod inspect { + use super::*; + use std::fmt::Write; + + #[test] + fn some_5() { + let some_5 = Some(5); + let mut text = String::new(); + some_5.inspect(|x| write!(text, "{x}").expect("failed to write {x} to text")); + assert_eq!(text, "5"); + Transform::inspect(some_5, |x| { + write!(text, "{x}").expect("failed to write {x} to text") + }); + assert_eq!(text, "55"); + } + } + + mod output { + use super::*; + + #[test] + fn ok() { + let ok_5: Result<_, ()> = Ok(5); + let stdlib = ok_5.ok(); + let custom = ok_5.output(); + assert_eq!(stdlib, custom); + } + } + + mod map { + use super::*; + + #[test] + fn map() { + let some_5 = Some(5); + let stdlib = some_5.map(|x| x + 1); + let custom = Transform::map(some_5, |x| x + 1); + assert_eq!(stdlib, custom); + } + + #[test] + fn map_or_some() { + let some_5 = Some(5); + let stdlib = some_5.map_or(0, |x| x + 1); + let custom = Transform::map_or(some_5, 0, |x| x + 1); + assert_eq!(stdlib, custom); + } + + #[test] + fn map_or_none() { + let some_5: Option = None; + let stdlib = some_5.map_or(0, |x| x + 1); + let custom = Transform::map_or(some_5, 0, |x| x + 1); + assert_eq!(stdlib, custom); + } + + #[test] + fn map_or_else_some() { + let some_5 = Some(5); + let stdlib = some_5.map_or_else(|| 1 + 1, |x| x + 1); + let custom = Transform::map_or_else(some_5, || 1 + 1, |x| x + 1); + assert_eq!(stdlib, custom); + } + + #[test] + fn map_or_else_none() { + let some_5: Option = None; + let stdlib = some_5.map_or_else(|| 1 + 1, |x| x + 1); + let custom = Transform::map_or_else(some_5, || 1 + 1, |x| x + 1); + assert_eq!(stdlib, custom); + } + } + + mod transpose { + use super::*; + #[test] + fn ok_some() { + let ok_some: Result, String> = Ok(Some(5)); + let stdlib: Option> = ok_some.clone().transpose(); + let custom: Option> = Transform::transpose(ok_some); + assert_eq!(stdlib, custom) + } + + #[test] + fn ok_none() { + let ok_none: Result, String> = Ok(None); + let stdlib = ok_none.clone().transpose(); + let custom = Transform::transpose(ok_none); + assert_eq!(stdlib, custom) + } + + #[test] + fn err() { + let err: Result, String> = Err("Oops".to_string()); + let stdlib = err.clone().transpose(); + let custom = Transform::transpose(err); + assert_eq!(stdlib, custom) + } + + #[test] + fn some_ok() { + let some_ok: Option> = Some(Ok(5)); + let stdlib: Result, String> = some_ok.clone().transpose(); + let custom: Result, String> = Transform::transpose(some_ok); + assert_eq!(stdlib, custom) + } + + #[test] + fn some_err() { + let some_err: Option> = Some(Err("Oops".to_string())); + let stdlib = some_err.clone().transpose(); + let custom = Transform::transpose(some_err); + assert_eq!(stdlib, custom) + } + + #[test] + fn none() { + let none: Option> = None; + let stdlib = none.clone().transpose(); + let custom = Transform::transpose(none); + assert_eq!(stdlib, custom) + } + } + + mod zip { + use super::*; + + #[test] + fn some_some() { + let some_1 = Some(1); + let some_x = Some("x"); + let stdlib = some_1.zip(some_x); + let custom = Transform::zip(some_1, some_x); + assert_eq!(stdlib, custom); + } + + #[test] + fn some_some_with() { + let some_1 = Some(-1_i32); + let some_2 = Some(2_u16); + let stdlib = some_1.zip_with(some_2, |x, y| x + i32::from(y)); + let custom = Transform::zip_with(some_1, some_2, |x, y| x + i32::from(y)); + assert_eq!(stdlib, custom); + } + } +} diff --git a/crates/try_v2_derive/Cargo.toml b/crates/try_v2_derive/Cargo.toml new file mode 100644 index 0000000..86b38e7 --- /dev/null +++ b/crates/try_v2_derive/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "try_v2_derive" +version = "0.5.0" +edition = "2024" +readme = "README.md" +description = "Provides a derive macro for `Try`. Part of crate `try_v2`." +authors = ["Mike Foster "] +keywords = ["derive", "Try", "try_trait_v2"] +homepage = "https://github.com/MusicalNinjaDad/try_v2" +repository = "https://github.com/MusicalNinjaDad/try_v2" +categories = ["development-tools"] +license = "MIT" +rust-version = "1.85.1" +exclude = [".github", ".devcontainer"] + +[lib] +proc-macro = true + +[dependencies] +syn = {version = "2.0.117", features = ["full","extra-traits"]} +proc-macro2 = "1.0.106" +proc_macro2_diagnostic = "0.3.0" +quote = "1.0.45" + +[dev-dependencies] +log = "0.4.29" +trybuild = "1.0.116" + +[build-dependencies] +autocfg = "1.5.1" diff --git a/build.rs b/crates/try_v2_derive/build.rs similarity index 100% rename from build.rs rename to crates/try_v2_derive/build.rs diff --git a/examples/BangMatching.rs b/crates/try_v2_derive/examples/BangMatching.rs similarity index 100% rename from examples/BangMatching.rs rename to crates/try_v2_derive/examples/BangMatching.rs diff --git a/examples/Nested_NoTry.rs b/crates/try_v2_derive/examples/Nested_NoTry.rs similarity index 100% rename from examples/Nested_NoTry.rs rename to crates/try_v2_derive/examples/Nested_NoTry.rs diff --git a/examples/Nested_Try.rs b/crates/try_v2_derive/examples/Nested_Try.rs similarity index 96% rename from examples/Nested_Try.rs rename to crates/try_v2_derive/examples/Nested_Try.rs index f728927..10cf14a 100644 --- a/examples/Nested_Try.rs +++ b/crates/try_v2_derive/examples/Nested_Try.rs @@ -5,7 +5,7 @@ use std::{error::Error, io}; -use try_v2::Try; +use try_v2_derive::Try; use DuplicateData::Duplicate; diff --git a/examples/TraitExt_NoTry.rs b/crates/try_v2_derive/examples/TraitExt_NoTry.rs similarity index 100% rename from examples/TraitExt_NoTry.rs rename to crates/try_v2_derive/examples/TraitExt_NoTry.rs diff --git a/examples/TraitExt_Try.rs b/crates/try_v2_derive/examples/TraitExt_Try.rs similarity index 97% rename from examples/TraitExt_Try.rs rename to crates/try_v2_derive/examples/TraitExt_Try.rs index d1387a6..f2b5d49 100644 --- a/examples/TraitExt_Try.rs +++ b/crates/try_v2_derive/examples/TraitExt_Try.rs @@ -6,7 +6,7 @@ use log::info; use std::{fmt::Display, ops::Add}; -use try_v2::Try; +use try_v2_derive::Try; use Counter::Count; diff --git a/examples/Transpose.rs b/crates/try_v2_derive/examples/Transpose.rs similarity index 100% rename from examples/Transpose.rs rename to crates/try_v2_derive/examples/Transpose.rs diff --git a/examples/TryFrom2.rs b/crates/try_v2_derive/examples/TryFrom2.rs similarity index 98% rename from examples/TryFrom2.rs rename to crates/try_v2_derive/examples/TryFrom2.rs index f15bbfc..ae9c2b8 100644 --- a/examples/TryFrom2.rs +++ b/crates/try_v2_derive/examples/TryFrom2.rs @@ -3,7 +3,7 @@ #![feature(try_trait_v2_residual)] #![feature(associated_type_defaults)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; /// Make TryFrom able to return arbitrary Try types trait TryFrom2: std::marker::Sized { diff --git a/examples/Unwrap.rs b/crates/try_v2_derive/examples/Unwrap.rs similarity index 100% rename from examples/Unwrap.rs rename to crates/try_v2_derive/examples/Unwrap.rs diff --git a/examples/signatures.rs b/crates/try_v2_derive/examples/signatures.rs similarity index 100% rename from examples/signatures.rs rename to crates/try_v2_derive/examples/signatures.rs diff --git a/src/lib.rs b/crates/try_v2_derive/src/lib.rs similarity index 74% rename from src/lib.rs rename to crates/try_v2_derive/src/lib.rs index fae8116..8e3726e 100644 --- a/src/lib.rs +++ b/crates/try_v2_derive/src/lib.rs @@ -2,124 +2,11 @@ #![cfg_attr(unstable_let_chains, feature(let_chains))] #![feature(never_type)] -//! 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` analog 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 -//! - no other variant can store the Output type (TODO #72 add a nice error message) -//! -//! See the individual documentation for [Try], [Try_ConvertResult] and [Try_Iterator] 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 { -//! 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 From for TestResult { -//! 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/139951) (stable since 1.88.0) -//! > -//! > 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 - use proc_macro::TokenStream as TokenStream1; use proc_macro2::TokenStream as TokenStream2; use proc_macro2_diagnostic::prelude::*; use quote::{format_ident, quote}; -use syn::{DeriveInput, GenericParam, TypeParamBound, parse_quote, spanned::Spanned}; +use syn::{DeriveInput, GenericParam, parse_quote, spanned::Spanned}; mod parse; use parse::TryEnum; @@ -127,14 +14,21 @@ use parse::TryEnum; #[proc_macro_derive(Try)] /// Derives [try_trait_v2](https://rust-lang.github.io/rfcs/3058-try-trait-v2.html) /// -/// See the [crate level documentation](crate) for restrictions and detailed examples +/// ## 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 +/// - no other variant can store the Output type (TODO #72 add a nice error message) /// /// ## Derived code /// ``` /// # #![feature(never_type)] /// # #![feature(try_trait_v2)] /// # #![feature(try_trait_v2_residual)] -/// # use try_v2::Try; +/// # use try_v2_derive::Try; /// #[derive(Try)] /// enum TestResult { /// Ok(T), @@ -201,7 +95,7 @@ use parse::TryEnum; /// # #![feature(never_type)] /// # #![feature(try_trait_v2)] /// # #![feature(try_trait_v2_residual)] -/// # use try_v2::Try; +/// # use try_v2_derive::Try; /// #[derive(Try)] /// enum TestResult<'t, 'e, T, E> { /// Ok(&'t T), @@ -318,7 +212,7 @@ fn impl_derive(input: TokenStream2) -> DiagnosticStream { /// # #![feature(never_type)] /// # #![feature(try_trait_v2)] /// # #![feature(try_trait_v2_residual)] -/// # use try_v2::{Try, Try_ConvertResult}; +/// # use try_v2_derive::{Try, Try_ConvertResult}; /// #[derive(Try, Try_ConvertResult)] /// #[must_use] /// enum TestResult { @@ -355,7 +249,7 @@ fn impl_derive(input: TokenStream2) -> DiagnosticStream { /// #![feature(try_trait_v2)] /// #![feature(try_trait_v2_residual)] /// -/// use try_v2::{Try, Try_ConvertResult}; +/// # use try_v2_derive::{Try, Try_ConvertResult}; /// /// #[derive(Try, Try_ConvertResult)] /// #[must_use] @@ -450,57 +344,6 @@ fn impl_convert_result(input: TokenStream2) -> DiagnosticStream { Ok(impl_convert) } -#[proc_macro_derive(Try_Methods)] -/// Derives std methods: -/// -/// ## Extracting the contained value -/// - `unwrap()` return the value contained in the Output variant - or *panics* with a generic message -pub fn try_methods(input: TokenStream1) -> TokenStream1 { - impl_try_methods(input.into()).into() -} - -fn impl_try_methods(input: TokenStream2) -> DiagnosticStream { - let ast: DeriveInput = syn::parse2(input).expect("derive macro"); - - let tryenum = TryEnum::parse(&ast)?; - #[allow(unused_variables)] - let ( - name, - output_variant_name, - output_type, - residual_type_name, - residual_type, - impl_generics, - ty_generics, - where_clause, - ) = tryenum.split_for_impl(); - - //let (debug_impl_generics, debug_ty_generics, debug_where_clause) - let debug: TypeParamBound = parse_quote!(std::fmt::Debug); - let debug_generics = tryenum.generics(|g| { - for param in g.type_params_mut() { - if param.bounds.iter().find(|b| b == &&debug).is_none() { - param.bounds.push(debug.clone()); - } - } - }); - let (debug_impl_generics, debug_ty_generics, debug_where_clause) = - debug_generics.split_for_impl(); - - let impl_extraction = quote! { - impl #debug_impl_generics #name #debug_ty_generics #debug_where_clause { - pub fn unwrap(self) -> #output_type { - let #name::#output_variant_name(val) = self else { - panic!("called `unwrap()` on a short-circuiting value: {:?}", self); - }; - val - } - } - }; - - Ok(impl_extraction) -} - #[proc_macro_derive(Try_Iterator)] /// Derives `IntoIterator` and `FromIterator` analog to `Result` & `Option`. /// @@ -513,7 +356,7 @@ fn impl_try_methods(input: TokenStream2) -> DiagnosticStream { /// # #![feature(try_trait_v2)] /// # #![feature(try_trait_v2_residual)] /// # #![feature(iterator_try_collect)] -/// # use try_v2::{Try, Try_Iterator}; +/// # use try_v2_derive::{Try, Try_Iterator}; /// # use TestResult::{Ok, TestsFailed, OtherError}; /// #[derive(Try, Try_Iterator)] /// #[must_use] diff --git a/src/parse.rs b/crates/try_v2_derive/src/parse.rs similarity index 100% rename from src/parse.rs rename to crates/try_v2_derive/src/parse.rs diff --git a/tests/compilation/Cargo.toml b/crates/try_v2_derive/tests/compilation/Cargo.toml similarity index 53% rename from tests/compilation/Cargo.toml rename to crates/try_v2_derive/tests/compilation/Cargo.toml index 5e9dfd2..a21bc69 100644 --- a/tests/compilation/Cargo.toml +++ b/crates/try_v2_derive/tests/compilation/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "try_v2_compilation_tests" +name = "try_v2_derive_compilation_tests" version = "0.4.0" edition = "2024" publish = false @@ -7,4 +7,4 @@ publish = false [lib] [dev-dependencies] -try_v2 = { workspace = true} +try_v2_derive = { workspace = true} diff --git a/tests/compilation/examples/fail_FirstGenericNotOutput.rs b/crates/try_v2_derive/tests/compilation/examples/fail_FirstGenericNotOutput.rs similarity index 90% rename from tests/compilation/examples/fail_FirstGenericNotOutput.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_FirstGenericNotOutput.rs index 7d869b4..88c4354 100644 --- a/tests/compilation/examples/fail_FirstGenericNotOutput.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_FirstGenericNotOutput.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/fail_FirstGenericNotOutput.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_FirstGenericNotOutput.stderr similarity index 100% rename from tests/compilation/examples/fail_FirstGenericNotOutput.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_FirstGenericNotOutput.stderr diff --git a/tests/compilation/examples/fail_MustUse.rs b/crates/try_v2_derive/tests/compilation/examples/fail_MustUse.rs similarity index 83% rename from tests/compilation/examples/fail_MustUse.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_MustUse.rs index 98bcbb8..ec46c0e 100644 --- a/tests/compilation/examples/fail_MustUse.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_MustUse.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Debug, Try, Try_ConvertResult)] enum ExitE { diff --git a/tests/compilation/examples/fail_MustUse.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_MustUse.stderr similarity index 100% rename from tests/compilation/examples/fail_MustUse.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_MustUse.stderr diff --git a/tests/compilation/examples/fail_NoGenerics.rs b/crates/try_v2_derive/tests/compilation/examples/fail_NoGenerics.rs similarity index 82% rename from tests/compilation/examples/fail_NoGenerics.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_NoGenerics.rs index dc09ff7..d723716 100644 --- a/tests/compilation/examples/fail_NoGenerics.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_NoGenerics.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/fail_NoGenerics.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_NoGenerics.stderr similarity index 100% rename from tests/compilation/examples/fail_NoGenerics.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_NoGenerics.stderr diff --git a/tests/compilation/examples/fail_OutputNamedFields.rs b/crates/try_v2_derive/tests/compilation/examples/fail_OutputNamedFields.rs similarity index 89% rename from tests/compilation/examples/fail_OutputNamedFields.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_OutputNamedFields.rs index db01796..763dae4 100644 --- a/tests/compilation/examples/fail_OutputNamedFields.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_OutputNamedFields.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/fail_OutputNamedFields.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_OutputNamedFields.stderr similarity index 100% rename from tests/compilation/examples/fail_OutputNamedFields.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_OutputNamedFields.stderr diff --git a/tests/compilation/examples/fail_OutputTypeKind.rs b/crates/try_v2_derive/tests/compilation/examples/fail_OutputTypeKind.rs similarity index 92% rename from tests/compilation/examples/fail_OutputTypeKind.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_OutputTypeKind.rs index 0efc5b8..ed6b358 100644 --- a/tests/compilation/examples/fail_OutputTypeKind.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_OutputTypeKind.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/fail_OutputTypeKind.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_OutputTypeKind.stderr similarity index 100% rename from tests/compilation/examples/fail_OutputTypeKind.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_OutputTypeKind.stderr diff --git a/tests/compilation/examples/fail_OutputUnitType.rs b/crates/try_v2_derive/tests/compilation/examples/fail_OutputUnitType.rs similarity index 83% rename from tests/compilation/examples/fail_OutputUnitType.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_OutputUnitType.rs index b624ab9..771b8ef 100644 --- a/tests/compilation/examples/fail_OutputUnitType.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_OutputUnitType.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/fail_OutputUnitType.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_OutputUnitType.stderr similarity index 100% rename from tests/compilation/examples/fail_OutputUnitType.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_OutputUnitType.stderr diff --git a/tests/compilation/examples/fail_Struct.rs b/crates/try_v2_derive/tests/compilation/examples/fail_Struct.rs similarity index 78% rename from tests/compilation/examples/fail_Struct.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_Struct.rs index a018045..5db7af9 100644 --- a/tests/compilation/examples/fail_Struct.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_Struct.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/fail_Struct.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_Struct.stderr similarity index 100% rename from tests/compilation/examples/fail_Struct.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_Struct.stderr diff --git a/tests/compilation/examples/fail_TooManyOutputs.rs b/crates/try_v2_derive/tests/compilation/examples/fail_TooManyOutputs.rs similarity index 91% rename from tests/compilation/examples/fail_TooManyOutputs.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_TooManyOutputs.rs index 5d9798d..ca209bd 100644 --- a/tests/compilation/examples/fail_TooManyOutputs.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_TooManyOutputs.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/fail_TooManyOutputs.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_TooManyOutputs.stderr similarity index 100% rename from tests/compilation/examples/fail_TooManyOutputs.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_TooManyOutputs.stderr diff --git a/tests/compilation/examples/fail_Union.rs b/crates/try_v2_derive/tests/compilation/examples/fail_Union.rs similarity index 80% rename from tests/compilation/examples/fail_Union.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_Union.rs index 8273c24..d7d4885 100644 --- a/tests/compilation/examples/fail_Union.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_Union.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/fail_Union.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_Union.stderr similarity index 100% rename from tests/compilation/examples/fail_Union.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_Union.stderr diff --git a/tests/compilation/examples/fail_ZeroFieldEnum.rs b/crates/try_v2_derive/tests/compilation/examples/fail_ZeroFieldEnum.rs similarity index 79% rename from tests/compilation/examples/fail_ZeroFieldEnum.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_ZeroFieldEnum.rs index a735d42..76655b6 100644 --- a/tests/compilation/examples/fail_ZeroFieldEnum.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_ZeroFieldEnum.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/fail_ZeroFieldEnum.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_ZeroFieldEnum.stderr similarity index 100% rename from tests/compilation/examples/fail_ZeroFieldEnum.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_ZeroFieldEnum.stderr diff --git a/tests/compilation/examples/fail_lifetime_conversion.rs b/crates/try_v2_derive/tests/compilation/examples/fail_lifetime_conversion.rs similarity index 98% rename from tests/compilation/examples/fail_lifetime_conversion.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_lifetime_conversion.rs index 4ec5f31..2fd9db4 100644 --- a/tests/compilation/examples/fail_lifetime_conversion.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_lifetime_conversion.rs @@ -4,7 +4,7 @@ //! Tests that conversion between custom enum and std::result::Result requires correct lifetime bounds. -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Debug, Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/fail_lifetime_conversion.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_lifetime_conversion.stderr similarity index 100% rename from tests/compilation/examples/fail_lifetime_conversion.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_lifetime_conversion.stderr diff --git a/tests/compilation/examples/fail_lifetime_duration.rs b/crates/try_v2_derive/tests/compilation/examples/fail_lifetime_duration.rs similarity index 96% rename from tests/compilation/examples/fail_lifetime_duration.rs rename to crates/try_v2_derive/tests/compilation/examples/fail_lifetime_duration.rs index d07a04c..56d419c 100644 --- a/tests/compilation/examples/fail_lifetime_duration.rs +++ b/crates/try_v2_derive/tests/compilation/examples/fail_lifetime_duration.rs @@ -4,7 +4,7 @@ //! Tests to ensure that lifetimes are correctly passed through and live as long as expected. -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; // Basic result with T & E borrowed #[must_use] diff --git a/tests/compilation/examples/fail_lifetime_duration.stderr b/crates/try_v2_derive/tests/compilation/examples/fail_lifetime_duration.stderr similarity index 100% rename from tests/compilation/examples/fail_lifetime_duration.stderr rename to crates/try_v2_derive/tests/compilation/examples/fail_lifetime_duration.stderr diff --git a/tests/compilation/examples/pass_GenericE.rs b/crates/try_v2_derive/tests/compilation/examples/pass_GenericE.rs similarity index 83% rename from tests/compilation/examples/pass_GenericE.rs rename to crates/try_v2_derive/tests/compilation/examples/pass_GenericE.rs index 06c712d..7845e20 100644 --- a/tests/compilation/examples/pass_GenericE.rs +++ b/crates/try_v2_derive/tests/compilation/examples/pass_GenericE.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Debug, Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/pass_MultipleFields.rs b/crates/try_v2_derive/tests/compilation/examples/pass_MultipleFields.rs similarity index 84% rename from tests/compilation/examples/pass_MultipleFields.rs rename to crates/try_v2_derive/tests/compilation/examples/pass_MultipleFields.rs index 05b4eb7..6d9af9d 100644 --- a/tests/compilation/examples/pass_MultipleFields.rs +++ b/crates/try_v2_derive/tests/compilation/examples/pass_MultipleFields.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Debug, Try, Try_ConvertResult)] #[allow(unused)] diff --git a/tests/compilation/examples/pass_MultipleGenerics.rs b/crates/try_v2_derive/tests/compilation/examples/pass_MultipleGenerics.rs similarity index 83% rename from tests/compilation/examples/pass_MultipleGenerics.rs rename to crates/try_v2_derive/tests/compilation/examples/pass_MultipleGenerics.rs index 5bfcbda..2ff632f 100644 --- a/tests/compilation/examples/pass_MultipleGenerics.rs +++ b/crates/try_v2_derive/tests/compilation/examples/pass_MultipleGenerics.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Debug, Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/pass_NoFieldResiduals.rs b/crates/try_v2_derive/tests/compilation/examples/pass_NoFieldResiduals.rs similarity index 87% rename from tests/compilation/examples/pass_NoFieldResiduals.rs rename to crates/try_v2_derive/tests/compilation/examples/pass_NoFieldResiduals.rs index 6a31649..ab60fe7 100644 --- a/tests/compilation/examples/pass_NoFieldResiduals.rs +++ b/crates/try_v2_derive/tests/compilation/examples/pass_NoFieldResiduals.rs @@ -4,7 +4,7 @@ use std::process::Termination; -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Debug, Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/pass_NoUnitResidual.rs b/crates/try_v2_derive/tests/compilation/examples/pass_NoUnitResidual.rs similarity index 87% rename from tests/compilation/examples/pass_NoUnitResidual.rs rename to crates/try_v2_derive/tests/compilation/examples/pass_NoUnitResidual.rs index 742b634..6f42e71 100644 --- a/tests/compilation/examples/pass_NoUnitResidual.rs +++ b/crates/try_v2_derive/tests/compilation/examples/pass_NoUnitResidual.rs @@ -4,7 +4,7 @@ use std::process::Termination; -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Debug, Try, Try_ConvertResult)] #[allow(unused)] // If it compiles then it already passes diff --git a/tests/compilation/examples/pass_ResultMeBang.rs b/crates/try_v2_derive/tests/compilation/examples/pass_ResultMeBang.rs similarity index 93% rename from tests/compilation/examples/pass_ResultMeBang.rs rename to crates/try_v2_derive/tests/compilation/examples/pass_ResultMeBang.rs index 518de7c..6b96698 100644 --- a/tests/compilation/examples/pass_ResultMeBang.rs +++ b/crates/try_v2_derive/tests/compilation/examples/pass_ResultMeBang.rs @@ -2,7 +2,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/examples/wip_ShortCircuitT.rs b/crates/try_v2_derive/tests/compilation/examples/wip_ShortCircuitT.rs similarity index 85% rename from tests/compilation/examples/wip_ShortCircuitT.rs rename to crates/try_v2_derive/tests/compilation/examples/wip_ShortCircuitT.rs index dbb00b6..5f4cea1 100644 --- a/tests/compilation/examples/wip_ShortCircuitT.rs +++ b/crates/try_v2_derive/tests/compilation/examples/wip_ShortCircuitT.rs @@ -4,7 +4,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult}; +use try_v2_derive::{Try, Try_ConvertResult}; #[derive(Debug, Try, Try_ConvertResult)] #[must_use] diff --git a/tests/compilation/src/lib.rs b/crates/try_v2_derive/tests/compilation/src/lib.rs similarity index 100% rename from tests/compilation/src/lib.rs rename to crates/try_v2_derive/tests/compilation/src/lib.rs diff --git a/tests/test_compilation.rs b/crates/try_v2_derive/tests/test_compilation.rs similarity index 100% rename from tests/test_compilation.rs rename to crates/try_v2_derive/tests/test_compilation.rs diff --git a/tests/test_usage.rs b/crates/try_v2_derive/tests/test_usage.rs similarity index 92% rename from tests/test_usage.rs rename to crates/try_v2_derive/tests/test_usage.rs index 6d2b97c..40c1409 100644 --- a/tests/test_usage.rs +++ b/crates/try_v2_derive/tests/test_usage.rs @@ -4,7 +4,7 @@ #![feature(try_trait_v2)] #![feature(try_trait_v2_residual)] -use try_v2::{Try, Try_ConvertResult, Try_Methods}; +use try_v2_derive::{Try, Try_ConvertResult}; #[cfg(assert_matches_in_module)] use std::assert_matches::assert_matches; @@ -141,7 +141,7 @@ mod multiple_generics { } mod iter { - use try_v2::Try_Iterator; + use try_v2_derive::Try_Iterator; use super::*; @@ -431,37 +431,3 @@ mod lifetime_duration { assert_matches!(restricted_lifetimes(&0, &7), BorrowedResult::Err(&7)); } } - -/// Validate that the derived methods work -mod methods { - - use super::*; - - #[derive(Debug, Try, Try_Methods)] - #[must_use] - enum Validated { - Valid(T), - Invalid, - ValidationFailed(E), - } - - #[test] - fn unwrap() { - let x: Validated<_, String> = Validated::Valid(2); - assert_eq!(x.unwrap(), 2); - } - - #[test] - #[should_panic(expected = "called `unwrap()` on a short-circuiting value: ValidationFailed(2)")] - fn unwrap_panic_fields() { - let x: Validated = Validated::ValidationFailed(2); - assert_eq!(x.unwrap(), 2); - } - - #[test] - #[should_panic(expected = "called `unwrap()` on a short-circuiting value: Invalid")] - fn unwrap_panic_unit() { - let y: Validated = Validated::Invalid; - y.unwrap(); - } -} diff --git a/tests/compilation/examples/pass_EDebug.rs b/tests/compilation/examples/pass_EDebug.rs deleted file mode 100644 index 6b6477d..0000000 --- a/tests/compilation/examples/pass_EDebug.rs +++ /dev/null @@ -1,18 +0,0 @@ -#![feature(never_type)] -#![feature(try_trait_v2)] -#![feature(try_trait_v2_residual)] -#![allow(dead_code)] - -use std::fmt::Debug; - -use try_v2::{Try, Try_Methods}; - -#[derive(Debug, Try, Try_Methods)] -#[must_use] -enum ExitE { - Ok(T), - TestsFailed(F), - OtherError(E), -} - -fn main() {}