68
68
//! let _ = try_match!(Var1((12, 34)), Var1((_0, _2)));
69
69
//! ```
70
70
//!
71
+ //! # Unstable Features
72
+ //!
73
+ //! *Requires `unstable` Cargo feature, exempt from semver guarantees.*
74
+ //!
75
+ //! <details><summary><h3>Partial Application</h3></summary>
76
+ //!
77
+ //! Tracking issue: [#3](https://github.com/yvt/try_match-rs/issues/3)
78
+ //!
79
+ //! Omit the scrutinee expression to produce a closure:
80
+ //!
81
+ //! ```rust
82
+ //! # {
83
+ //! #![cfg(feature = "unstable")]
84
+ //! # use try_match::try_match;
85
+ //! # #[derive(Debug, PartialEq)] enum Enum<T> { Var1(T), Var2 }
86
+ //! # use Enum::{Var1, Var2};
87
+ //! assert_eq!(try_match!(Var1(42), Var1(x)), Ok(42));
88
+ //! // ^^^^^^^^ -------
89
+ //! assert_eq!(try_match!(, Var1(x))(Var1(42)), Ok(42));
90
+ //! // ------- ^^^^^^^^
91
+ //!
92
+ //! // Equivalent to:
93
+ //! assert_eq!((|x| try_match!(x, Var1(x)))(Var1(42)), Ok(42));
94
+ //! // ------- ^^^^^^^^
95
+ //! # }
96
+ //! ```
97
+ //!
98
+ //! ```rust
99
+ //! # {
100
+ //! #![cfg(feature = "unstable")]
101
+ //! # use try_match::try_match;
102
+ //! # #[derive(Debug, PartialEq)] enum Enum<T> { Var1(T), Var2 }
103
+ //! # use Enum::{Var1, Var2};
104
+ //! let array = [Var1(42), Var2, Var1(10)];
105
+ //! let filtered: Result<Vec<_>, _> = array
106
+ //! .iter()
107
+ //! .map(try_match!(, &Var1(_0) if _0 > 20))
108
+ //! .collect();
109
+ //!
110
+ //! // `Var2` is the first value that doesn't match
111
+ //! assert_eq!(filtered, Err(&Var2));
112
+ //! # }
113
+ //! ```
114
+ //!
115
+ //! *Caveat:* Since this mode is implemented by a closure,
116
+ //! [the default binding mode][] ([RFC 2005][]), ownership, and control flow
117
+ //! may work differently:
118
+ //!
119
+ //! ```rust
120
+ //! # {
121
+ //! # #![cfg(feature = "unstable")]
122
+ //! # use try_match::try_match;
123
+ //! try_match!(&Some(42), Some(_0));
124
+ //! try_match!(&Some(42), &Some(ref _0));
125
+ //! # }
126
+ //! ```
127
+ //!
128
+ //! ```rust,compile_fail
129
+ //! # use try_match::try_match;
130
+ //! try_match!(, Some(_0))(&Some(42));
131
+ //! // ERROR: expected enum `Option`, found reference
132
+ //! ```
133
+ //!
134
+ //! ```rust
135
+ //! # {
136
+ //! # #![cfg(feature = "unstable")]
137
+ //! # use try_match::try_match;
138
+ //! use std::rc::Rc;
139
+ //!
140
+ //! // `rc2` is conditionally dropped
141
+ //! let rc1 = Rc::new(());
142
+ //! let rc2 = Rc::clone(&rc1);
143
+ //! try_match!(None::<()>, Some(_) => drop(rc2));
144
+ //! assert_eq!(Rc::strong_count(&rc1), 2);
145
+ //!
146
+ //! // `rc2` is unconditionally moved into a closure and dropped
147
+ //! let rc1 = Rc::new(());
148
+ //! let rc2 = Rc::clone(&rc1);
149
+ //! try_match!(, Some(_) => drop(rc2))(None::<()>);
150
+ //! assert_eq!(Rc::strong_count(&rc1), 1);
151
+ //! # }
152
+ //! ```
153
+ //!
154
+ //! ```rust
155
+ //! # {
156
+ //! # #![cfg(feature = "unstable")]
157
+ //! # use try_match::try_match;
158
+ //! fn func_uncurried() {
159
+ //! try_match!((), () => return);
160
+ //! unreachable!();
161
+ //! }
162
+ //!
163
+ //! fn func_curried() -> i32 {
164
+ //! try_match!(, () => return Ok(()))(());
165
+ //! 42 // reachable
166
+ //! }
167
+ //!
168
+ //! func_uncurried();
169
+ //! func_curried();
170
+ //! # }
171
+ //! ```
172
+ //!
173
+ //! [the default binding mode]: https://doc.rust-lang.org/1.69.0/reference/patterns.html#binding-modes
174
+ //! [RFC 2005]: https://rust-lang.github.io/rfcs/2005-match-ergonomics.html
175
+ //!
176
+ //! </details>
177
+ //!
71
178
//! # Quirks
72
179
//!
73
180
//! When using implicit mapping, bind variables defined inside macros are
@@ -218,6 +325,14 @@ macro_rules! try_match {
218
325
( $in: expr, $( |) ? $( $p: pat) |+ $( if $guard: expr) ?) => {
219
326
$crate:: implicit_try_match!( $in, $( $p) |+ $( if $guard) ?)
220
327
} ;
328
+
329
+ // Partial application (requires `unstable` Cargo feature)
330
+ ( , $( $pattern_and_rest: tt) * ) => {
331
+ $crate:: assert_unstable!(
332
+ [ "partial application" ]
333
+ |scrutinee| $crate:: try_match!( scrutinee, $( $pattern_and_rest) * )
334
+ )
335
+ }
221
336
}
222
337
223
338
#[ cfg( feature = "implicit_map" ) ]
@@ -241,6 +356,24 @@ macro_rules! implicit_try_match {
241
356
} ;
242
357
}
243
358
359
+ #[ cfg( feature = "unstable" ) ]
360
+ #[ macro_export]
361
+ #[ doc( hidden) ]
362
+ macro_rules! assert_unstable {
363
+ ( [ $( $msg: tt) * ] $( $tt: tt) * ) => {
364
+ $( $tt) *
365
+ }
366
+ }
367
+
368
+ #[ cfg( not( feature = "unstable" ) ) ]
369
+ #[ macro_export]
370
+ #[ doc( hidden) ]
371
+ macro_rules! assert_unstable {
372
+ ( [ $( $msg: tt) * ] $( $tt: tt) * ) => {
373
+ compile_error!( concat!( $( $msg) * , " requires `unstable` Cargo feature" ) )
374
+ }
375
+ }
376
+
244
377
/// Pattern: `$p:pat`
245
378
///
246
379
/// The produced expression evaluates to `Ok(_)` using bound variables on a
0 commit comments