22use std:: convert:: Infallible ;
33use std:: fmt:: { Debug , Display } ;
44use std:: mem;
5- use std:: ops:: Range ;
5+ use std:: ops:: { Add , AddAssign , Range } ;
66
77#[ cfg( feature = "darling" ) ]
88use darling_core:: Error as DarlingError ;
@@ -58,6 +58,20 @@ impl From<SilentError> for Error {
5858 }
5959}
6060
61+ impl < T : ToTokensError + ' static > Add < T > for Error {
62+ type Output = Error ;
63+
64+ fn add ( self , rhs : T ) -> Self :: Output {
65+ self . join ( rhs)
66+ }
67+ }
68+
69+ impl < T : ToTokensError + ' static > AddAssign < T > for Error {
70+ fn add_assign ( & mut self , rhs : T ) {
71+ self . push ( rhs) ;
72+ }
73+ }
74+
6175impl Error {
6276 /// Mimics [`From<impl ToTokensError> for Error`](From) implementation to
6377 /// not conflict std's `From<T> for T`
@@ -66,6 +80,17 @@ impl Error {
6680 }
6781
6882 /// Pushes an additional `Error`
83+ ///
84+ /// Alternatively errors can also be "added":
85+ ///
86+ /// ```
87+ /// use manyhow::{Error, error_message};
88+ /// let mut error = Error::from(error_message!("Hello Rust!"));
89+ /// error += error_message!("Hello 🦀!");
90+ /// # use manyhow::ToTokensError;
91+ /// # proc_macro_utils::assert_tokens!(error.into_token_stream(),
92+ /// # { ::core::compile_error!{"Hello Rust!"} ::core::compile_error!{"Hello 🦀!"} });
93+ /// ```
6994 pub fn push ( & mut self , error : impl ToTokensError + ' static ) {
7095 self . 0 . push ( Box :: new ( error) ) ;
7196 }
@@ -139,6 +164,14 @@ impl From<ErrorMessage> for Syn2Error {
139164 }
140165}
141166
167+ impl < T : ToTokensError + ' static > Add < T > for ErrorMessage {
168+ type Output = Error ;
169+
170+ fn add ( self , rhs : T ) -> Self :: Output {
171+ self . join ( rhs)
172+ }
173+ }
174+
142175impl ErrorMessage {
143176 /// Creates a new error message at the specified span
144177 ///
@@ -222,6 +255,12 @@ impl Attachment for ErrorMessage {
222255#[ derive( Default , Debug ) ]
223256pub struct Emitter ( Vec < Box < dyn ToTokensError > > ) ;
224257
258+ impl < T : ToTokensError + ' static > AddAssign < T > for Emitter {
259+ fn add_assign ( & mut self , rhs : T ) {
260+ self . emit ( rhs) ;
261+ }
262+ }
263+
225264impl Emitter {
226265 /// Creates an `Emitter`, this can be used to collect errors than can later
227266 /// be converted with [`Emitter::into_result()`].
@@ -236,7 +275,16 @@ impl Emitter {
236275 }
237276 }
238277
239- /// Emitts an error
278+ /// Emits an error
279+ ///
280+ /// Alternatively errors can also be "added":
281+ ///
282+ /// ```
283+ /// let mut emitter = manyhow::Emitter::new();
284+ /// emitter += manyhow::error_message!("Hello World!");
285+ /// # use manyhow::ToTokensError;
286+ /// # proc_macro_utils::assert_tokens!(emitter.into_result().unwrap_err().into_token_stream(), { ::core::compile_error!{"Hello World!"} });
287+ /// ```
240288 pub fn emit ( & mut self , error : impl ToTokensError + ' static ) {
241289 self . 0 . push ( Box :: new ( error) ) ;
242290 }
@@ -307,6 +355,20 @@ pub trait JoinToTokensError {
307355 ///
308356 /// error_message!("test").join(error_message!("another"));
309357 /// ```
358+ ///
359+ /// Some errors like [`manyhow::Error`] and [`manyhow::ErrorMessage`] can
360+ /// also be "added":
361+ ///
362+ /// ```
363+ /// # use manyhow::ToTokensError;
364+ /// use manyhow::{error_message, Error};
365+ /// # proc_macro_utils::assert_tokens!((
366+ /// error_message!("Hello Rust!") + error_message!("Hello 🦀!")
367+ /// # ).into_token_stream(), { ::core::compile_error!{"Hello Rust!"} ::core::compile_error!{"Hello 🦀!"} });
368+ /// # proc_macro_utils::assert_tokens!((
369+ /// Error::from(error_message!("Hello Rust!")) + error_message!("Hello 🦀!")
370+ /// # ).into_token_stream(), { ::core::compile_error!{"Hello Rust!"} ::core::compile_error!{"Hello 🦀!"} });
371+ /// ```
310372 fn join ( self , error : impl ToTokensError + ' static ) -> Error ;
311373}
312374
0 commit comments