@@ -65,98 +65,108 @@ macro_rules! bail {
6565 } ;
6666}
6767
68- /// Return early with an error if a condition is not satisfied.
69- ///
70- /// This macro is equivalent to `if !$cond { return
71- /// Err(`[`anyhow!($args...)`][anyhow!]`); }`.
72- ///
73- /// The surrounding function's or closure's return value is required to be
74- /// `Result<_,`[`anyhow::Error`][crate::Error]`>`.
75- ///
76- /// Analogously to `assert!`, `ensure!` takes a condition and exits the function
77- /// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
78- /// rather than panicking.
79- ///
80- /// [anyhow!]: crate::anyhow
81- ///
82- /// # Example
83- ///
84- /// ```
85- /// # use anyhow::{ensure, Result};
86- /// #
87- /// # fn main() -> Result<()> {
88- /// # let user = 0;
89- /// #
90- /// ensure!(user == 0, "only user 0 is allowed");
91- /// # Ok(())
92- /// # }
93- /// ```
94- ///
95- /// ```
96- /// # use anyhow::{ensure, Result};
97- /// # use thiserror::Error;
98- /// #
99- /// # const MAX_DEPTH: usize = 1;
100- /// #
101- /// #[derive(Error, Debug)]
102- /// enum ScienceError {
103- /// #[error("recursion limit exceeded")]
104- /// RecursionLimitExceeded,
105- /// # #[error("...")]
106- /// # More = (stringify! {
107- /// ...
108- /// # }, 1).1,
109- /// }
110- ///
111- /// # fn main() -> Result<()> {
112- /// # let depth = 0;
113- /// #
114- /// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
115- /// # Ok(())
116- /// # }
117- /// ```
118- #[ cfg( doc) ]
119- #[ macro_export]
120- macro_rules! ensure {
121- ( $cond: expr $( , ) ?) => {
122- if !$cond {
123- return $crate:: __private:: Err ( $crate:: Error :: msg(
124- $crate:: __private:: concat!( "Condition failed: `" , $crate:: __private:: stringify!( $cond) , "`" )
125- ) ) ;
126- }
127- } ;
128- ( $cond: expr, $msg: literal $( , ) ?) => {
129- if !$cond {
130- return $crate:: __private:: Err ( $crate:: __anyhow!( $msg) ) ;
131- }
132- } ;
133- ( $cond: expr, $err: expr $( , ) ?) => {
134- if !$cond {
135- return $crate:: __private:: Err ( $crate:: __anyhow!( $err) ) ;
136- }
137- } ;
138- ( $cond: expr, $fmt: expr, $( $arg: tt) * ) => {
139- if !$cond {
140- return $crate:: __private:: Err ( $crate:: __anyhow!( $fmt, $( $arg) * ) ) ;
141- }
68+ macro_rules! __ensure {
69+ ( $ensure: item) => {
70+ /// Return early with an error if a condition is not satisfied.
71+ ///
72+ /// This macro is equivalent to `if !$cond { return
73+ /// Err(`[`anyhow!($args...)`][anyhow!]`); }`.
74+ ///
75+ /// The surrounding function's or closure's return value is required to be
76+ /// `Result<_,`[`anyhow::Error`][crate::Error]`>`.
77+ ///
78+ /// Analogously to `assert!`, `ensure!` takes a condition and exits the function
79+ /// if the condition fails. Unlike `assert!`, `ensure!` returns an `Error`
80+ /// rather than panicking.
81+ ///
82+ /// [anyhow!]: crate::anyhow
83+ ///
84+ /// # Example
85+ ///
86+ /// ```
87+ /// # use anyhow::{ensure, Result};
88+ /// #
89+ /// # fn main() -> Result<()> {
90+ /// # let user = 0;
91+ /// #
92+ /// ensure!(user == 0, "only user 0 is allowed");
93+ /// # Ok(())
94+ /// # }
95+ /// ```
96+ ///
97+ /// ```
98+ /// # use anyhow::{ensure, Result};
99+ /// # use thiserror::Error;
100+ /// #
101+ /// # const MAX_DEPTH: usize = 1;
102+ /// #
103+ /// #[derive(Error, Debug)]
104+ /// enum ScienceError {
105+ /// #[error("recursion limit exceeded")]
106+ /// RecursionLimitExceeded,
107+ /// # #[error("...")]
108+ /// # More = (stringify! {
109+ /// ...
110+ /// # }, 1).1,
111+ /// }
112+ ///
113+ /// # fn main() -> Result<()> {
114+ /// # let depth = 0;
115+ /// #
116+ /// ensure!(depth <= MAX_DEPTH, ScienceError::RecursionLimitExceeded);
117+ /// # Ok(())
118+ /// # }
119+ /// ```
120+ $ensure
142121 } ;
143122}
144123
124+ #[ cfg( doc) ]
125+ __ensure ! [
126+ #[ macro_export]
127+ macro_rules! ensure {
128+ ( $cond: expr $( , ) ?) => {
129+ if !$cond {
130+ return $crate :: __private:: Err ( $crate :: Error :: msg(
131+ $crate :: __private:: concat!( "Condition failed: `" , $crate :: __private:: stringify!( $cond) , "`" )
132+ ) ) ;
133+ }
134+ } ;
135+ ( $cond: expr, $msg: literal $( , ) ?) => {
136+ if !$cond {
137+ return $crate :: __private:: Err ( $crate :: __anyhow!( $msg) ) ;
138+ }
139+ } ;
140+ ( $cond: expr, $err: expr $( , ) ?) => {
141+ if !$cond {
142+ return $crate :: __private:: Err ( $crate :: __anyhow!( $err) ) ;
143+ }
144+ } ;
145+ ( $cond: expr, $fmt: expr, $( $arg: tt) * ) => {
146+ if !$cond {
147+ return $crate :: __private:: Err ( $crate :: __anyhow!( $fmt, $( $arg) * ) ) ;
148+ }
149+ } ;
150+ }
151+ ] ;
152+
145153#[ cfg( not( doc) ) ]
146- #[ macro_export]
147- macro_rules! ensure {
148- ( $( $tt: tt) * ) => {
149- $crate:: __parse_ensure!(
150- /* state */ 0
151- /* stack */ ( )
152- /* bail */ ( $( $tt) * )
153- /* fuel */ ( ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~)
154- /* parse */ { ( ) }
155- /* dup */ ( $( $tt) * )
156- /* rest */ $( $tt) *
157- )
158- } ;
159- }
154+ __ensure ! [
155+ #[ macro_export]
156+ macro_rules! ensure {
157+ ( $( $tt: tt) * ) => {
158+ $crate :: __parse_ensure!(
159+ /* state */ 0
160+ /* stack */ ( )
161+ /* bail */ ( $( $tt) * )
162+ /* fuel */ ( ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~)
163+ /* parse */ { ( ) }
164+ /* dup */ ( $( $tt) * )
165+ /* rest */ $( $tt) *
166+ )
167+ } ;
168+ }
169+ ] ;
160170
161171/// Construct an ad-hoc error from a string or existing non-`anyhow` error
162172/// value.
0 commit comments