| /// Prints to [`stdout`][crate::stdout]. |
| /// |
| /// Equivalent to the [`println!`] macro except that a newline is not printed at |
| /// the end of the message. |
| /// |
| /// Note that stdout is frequently line-buffered by default so it may be |
| /// necessary to use [`std::io::Write::flush()`] to ensure the output is emitted |
| /// immediately. |
| /// |
| /// **NOTE:** The `print!` macro will lock the standard output on each call. If you call |
| /// `print!` within a hot loop, this behavior may be the bottleneck of the loop. |
| /// To avoid this, lock stdout with [`AutoStream::lock`][crate::AutoStream::lock]: |
| /// ``` |
| /// # #[cfg(feature = "auto")] { |
| /// use std::io::Write as _; |
| /// |
| /// let mut lock = anstream::stdout().lock(); |
| /// write!(lock, "hello world").unwrap(); |
| /// # } |
| /// ``` |
| /// |
| /// Use `print!` only for the primary output of your program. Use |
| /// [`eprint!`] instead to print error and progress messages. |
| /// |
| /// **NOTE:** Not all `print!` calls will be captured in tests like [`std::print!`] |
| /// - Capturing will automatically be activated in test binaries |
| /// - Otherwise, only when the `test` feature is enabled |
| /// |
| /// # Panics |
| /// |
| /// Panics if writing to `stdout` fails for any reason **except** broken pipe. |
| /// |
| /// Writing to non-blocking stdout can cause an error, which will lead |
| /// this macro to panic. |
| /// |
| /// # Examples |
| /// |
| /// ``` |
| /// # #[cfg(feature = "auto")] { |
| /// use std::io::Write as _; |
| /// use anstream::print; |
| /// use anstream::stdout; |
| /// |
| /// print!("this "); |
| /// print!("will "); |
| /// print!("be "); |
| /// print!("on "); |
| /// print!("the "); |
| /// print!("same "); |
| /// print!("line "); |
| /// |
| /// stdout().flush().unwrap(); |
| /// |
| /// print!("this string has a newline, why not choose println! instead?\n"); |
| /// |
| /// stdout().flush().unwrap(); |
| /// # } |
| /// ``` |
| #[cfg(feature = "auto")] |
| #[macro_export] |
| macro_rules! print { |
| ($($arg:tt)*) => {{ |
| if cfg!(any(feature = "test", test)) { |
| use std::io::Write as _; |
| |
| let stdio = std::io::stdout(); |
| let choice = $crate::AutoStream::choice(&stdio); |
| let buffer = Vec::new(); |
| let mut stream = $crate::AutoStream::new(buffer, choice); |
| // Ignore errors rather than panic |
| let _ = ::std::write!(&mut stream, $($arg)*); |
| let buffer = stream.into_inner(); |
| // Should be UTF-8 but not wanting to panic |
| let buffer = String::from_utf8_lossy(&buffer); |
| ::std::print!("{}", buffer) |
| } else { |
| use std::io::Write as _; |
| |
| let mut stream = $crate::stdout(); |
| match ::std::write!(&mut stream, $($arg)*) { |
| Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => { |
| ::std::panic!("failed printing to stdout: {e}"); |
| } |
| Err(_) | Ok(_) => {} |
| } |
| } |
| }}; |
| } |
| |
| /// Prints to [`stdout`][crate::stdout], with a newline. |
| /// |
| /// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone |
| /// (no additional CARRIAGE RETURN (`\r`/`U+000D`)). |
| /// |
| /// This macro uses the same syntax as [`format!`], but writes to the standard output instead. |
| /// See [`std::fmt`] for more information. |
| /// |
| /// **NOTE:** The `println!` macro will lock the standard output on each call. If you call |
| /// `println!` within a hot loop, this behavior may be the bottleneck of the loop. |
| /// To avoid this, lock stdout with [`AutoStream::lock`][crate::AutoStream::lock]: |
| /// ``` |
| /// # #[cfg(feature = "auto")] { |
| /// use std::io::Write as _; |
| /// |
| /// let mut lock = anstream::stdout().lock(); |
| /// writeln!(lock, "hello world").unwrap(); |
| /// # } |
| /// ``` |
| /// |
| /// Use `println!` only for the primary output of your program. Use |
| /// [`eprintln!`] instead to print error and progress messages. |
| /// |
| /// **NOTE:** Not all `println!` calls will be captured in tests like [`std::println!`] |
| /// - Capturing will automatically be activated in test binaries |
| /// - Otherwise, only when the `test` feature is enabled |
| /// |
| /// # Panics |
| /// |
| /// Panics if writing to `stdout` fails for any reason **except** broken pipe. |
| /// |
| /// Writing to non-blocking stdout can cause an error, which will lead |
| /// this macro to panic. |
| /// |
| /// # Examples |
| /// |
| /// ``` |
| /// # #[cfg(feature = "auto")] { |
| /// use anstream::println; |
| /// |
| /// println!(); // prints just a newline |
| /// println!("hello there!"); |
| /// println!("format {} arguments", "some"); |
| /// let local_variable = "some"; |
| /// println!("format {local_variable} arguments"); |
| /// # } |
| /// ``` |
| #[cfg(feature = "auto")] |
| #[macro_export] |
| macro_rules! println { |
| () => { |
| $crate::print!("\n") |
| }; |
| ($($arg:tt)*) => {{ |
| if cfg!(any(feature = "test", test)) { |
| use std::io::Write as _; |
| |
| let stdio = std::io::stdout(); |
| let choice = $crate::AutoStream::choice(&stdio); |
| let buffer = Vec::new(); |
| let mut stream = $crate::AutoStream::new(buffer, choice); |
| // Ignore errors rather than panic |
| let _ = ::std::write!(&mut stream, $($arg)*); |
| let buffer = stream.into_inner(); |
| // Should be UTF-8 but not wanting to panic |
| let buffer = String::from_utf8_lossy(&buffer); |
| ::std::println!("{}", buffer) |
| } else { |
| use std::io::Write as _; |
| |
| let mut stream = $crate::stdout(); |
| match ::std::writeln!(&mut stream, $($arg)*) { |
| Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => { |
| ::std::panic!("failed printing to stdout: {e}"); |
| } |
| Err(_) | Ok(_) => {} |
| } |
| } |
| }}; |
| } |
| |
| /// Prints to [`stderr`][crate::stderr]. |
| /// |
| /// Equivalent to the [`print!`] macro, except that output goes to |
| /// `stderr` instead of `stdout`. See [`print!`] for |
| /// example usage. |
| /// |
| /// Use `eprint!` only for error and progress messages. Use `print!` |
| /// instead for the primary output of your program. |
| /// |
| /// **NOTE:** Not all `eprint!` calls will be captured in tests like [`std::eprint!`] |
| /// - Capturing will automatically be activated in test binaries |
| /// - Otherwise, only when the `test` feature is enabled |
| /// |
| /// # Panics |
| /// |
| /// Panics if writing to `stderr` fails for any reason **except** broken pipe. |
| /// |
| /// Writing to non-blocking stdout can cause an error, which will lead |
| /// this macro to panic. |
| /// |
| /// # Examples |
| /// |
| /// ``` |
| /// # #[cfg(feature = "auto")] { |
| /// use anstream::eprint; |
| /// |
| /// eprint!("Error: Could not complete task"); |
| /// # } |
| /// ``` |
| #[cfg(feature = "auto")] |
| #[macro_export] |
| macro_rules! eprint { |
| ($($arg:tt)*) => {{ |
| if cfg!(any(feature = "test", test)) { |
| use std::io::Write as _; |
| |
| let stdio = std::io::stderr(); |
| let choice = $crate::AutoStream::choice(&stdio); |
| let buffer = Vec::new(); |
| let mut stream = $crate::AutoStream::new(buffer, choice); |
| // Ignore errors rather than panic |
| let _ = ::std::write!(&mut stream, $($arg)*); |
| let buffer = stream.into_inner(); |
| // Should be UTF-8 but not wanting to panic |
| let buffer = String::from_utf8_lossy(&buffer); |
| ::std::eprint!("{}", buffer) |
| } else { |
| use std::io::Write as _; |
| |
| let mut stream = $crate::stderr(); |
| match ::std::write!(&mut stream, $($arg)*) { |
| Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => { |
| ::std::panic!("failed printing to stdout: {e}"); |
| } |
| Err(_) | Ok(_) => {} |
| } |
| } |
| }}; |
| } |
| |
| /// Prints to [`stderr`][crate::stderr], with a newline. |
| /// |
| /// Equivalent to the [`println!`] macro, except that output goes to |
| /// `stderr` instead of `stdout`. See [`println!`] for |
| /// example usage. |
| /// |
| /// Use `eprintln!` only for error and progress messages. Use `println!` |
| /// instead for the primary output of your program. |
| /// |
| /// **NOTE:** Not all `eprintln!` calls will be captured in tests like [`std::eprintln!`] |
| /// - Capturing will automatically be activated in test binaries |
| /// - Otherwise, only when the `test` feature is enabled |
| /// |
| /// # Panics |
| /// |
| /// Panics if writing to `stderr` fails for any reason **except** broken pipe. |
| /// |
| /// Writing to non-blocking stdout can cause an error, which will lead |
| /// this macro to panic. |
| /// |
| /// # Examples |
| /// |
| /// ``` |
| /// # #[cfg(feature = "auto")] { |
| /// use anstream::eprintln; |
| /// |
| /// eprintln!("Error: Could not complete task"); |
| /// # } |
| /// ``` |
| #[cfg(feature = "auto")] |
| #[macro_export] |
| macro_rules! eprintln { |
| () => { |
| $crate::eprint!("\n") |
| }; |
| ($($arg:tt)*) => {{ |
| if cfg!(any(feature = "test", test)) { |
| use std::io::Write as _; |
| |
| let stdio = std::io::stderr(); |
| let choice = $crate::AutoStream::choice(&stdio); |
| let buffer = Vec::new(); |
| let mut stream = $crate::AutoStream::new(buffer, choice); |
| // Ignore errors rather than panic |
| let _ = ::std::write!(&mut stream, $($arg)*); |
| let buffer = stream.into_inner(); |
| // Should be UTF-8 but not wanting to panic |
| let buffer = String::from_utf8_lossy(&buffer); |
| ::std::eprintln!("{}", buffer) |
| } else { |
| use std::io::Write as _; |
| |
| let mut stream = $crate::stderr(); |
| match ::std::writeln!(&mut stream, $($arg)*) { |
| Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => { |
| ::std::panic!("failed printing to stdout: {e}"); |
| } |
| Err(_) | Ok(_) => {} |
| } |
| } |
| }}; |
| } |
| |
| /// Panics the current thread. |
| /// |
| /// This allows a program to terminate immediately and provide feedback |
| /// to the caller of the program. |
| /// |
| /// This macro is the perfect way to assert conditions in example code and in |
| /// tests. `panic!` is closely tied with the `unwrap` method of both |
| /// [`Option`][ounwrap] and [`Result`][runwrap] enums. Both implementations call |
| /// `panic!` when they are set to [`None`] or [`Err`] variants. |
| /// |
| /// When using `panic!()` you can specify a string payload, that is built using |
| /// the [`format!`] syntax. That payload is used when injecting the panic into |
| /// the calling Rust thread, causing the thread to panic entirely. |
| /// |
| /// The behavior of the default `std` hook, i.e. the code that runs directly |
| /// after the panic is invoked, is to print the message payload to |
| /// `stderr` along with the file/line/column information of the `panic!()` |
| /// call. You can override the panic hook using [`std::panic::set_hook()`]. |
| /// Inside the hook a panic can be accessed as a `&dyn Any + Send`, |
| /// which contains either a `&str` or `String` for regular `panic!()` invocations. |
| /// To panic with a value of another other type, [`panic_any`] can be used. |
| /// |
| /// See also the macro [`compile_error!`], for raising errors during compilation. |
| /// |
| /// # When to use `panic!` vs `Result` |
| /// |
| /// The Rust language provides two complementary systems for constructing / |
| /// representing, reporting, propagating, reacting to, and discarding errors. These |
| /// responsibilities are collectively known as "error handling." `panic!` and |
| /// `Result` are similar in that they are each the primary interface of their |
| /// respective error handling systems; however, the meaning these interfaces attach |
| /// to their errors and the responsibilities they fulfill within their respective |
| /// error handling systems differ. |
| /// |
| /// The `panic!` macro is used to construct errors that represent a bug that has |
| /// been detected in your program. With `panic!` you provide a message that |
| /// describes the bug and the language then constructs an error with that message, |
| /// reports it, and propagates it for you. |
| /// |
| /// `Result` on the other hand is used to wrap other types that represent either |
| /// the successful result of some computation, `Ok(T)`, or error types that |
| /// represent an anticipated runtime failure mode of that computation, `Err(E)`. |
| /// `Result` is used alongside user defined types which represent the various |
| /// anticipated runtime failure modes that the associated computation could |
| /// encounter. `Result` must be propagated manually, often with the the help of the |
| /// `?` operator and `Try` trait, and they must be reported manually, often with |
| /// the help of the `Error` trait. |
| /// |
| /// For more detailed information about error handling check out the [book] or the |
| /// [`std::result`] module docs. |
| /// |
| /// [ounwrap]: Option::unwrap |
| /// [runwrap]: Result::unwrap |
| /// [`std::panic::set_hook()`]: ../std/panic/fn.set_hook.html |
| /// [`panic_any`]: ../std/panic/fn.panic_any.html |
| /// [`Box`]: ../std/boxed/struct.Box.html |
| /// [`Any`]: crate::any::Any |
| /// [`format!`]: ../std/macro.format.html |
| /// [book]: ../book/ch09-00-error-handling.html |
| /// [`std::result`]: ../std/result/index.html |
| /// |
| /// # Current implementation |
| /// |
| /// If the main thread panics it will terminate all your threads and end your |
| /// program with code `101`. |
| /// |
| /// # Examples |
| /// |
| /// ```should_panic |
| /// # #![allow(unreachable_code)] |
| /// use anstream::panic; |
| /// panic!(); |
| /// panic!("this is a terrible mistake!"); |
| /// panic!("this is a {} {message}", "fancy", message = "message"); |
| /// ``` |
| #[cfg(feature = "auto")] |
| #[macro_export] |
| macro_rules! panic { |
| () => { |
| ::std::panic!() |
| }; |
| ($($arg:tt)*) => {{ |
| use std::io::Write as _; |
| |
| let panic_stream = std::io::stderr(); |
| let choice = $crate::AutoStream::choice(&panic_stream); |
| let buffer = Vec::new(); |
| let mut stream = $crate::AutoStream::new(buffer, choice); |
| // Ignore errors rather than panic |
| let _ = ::std::write!(&mut stream, $($arg)*); |
| let buffer = stream.into_inner(); |
| // Should be UTF-8 but not wanting to panic |
| let buffer = String::from_utf8_lossy(&buffer).into_owned(); |
| ::std::panic!("{}", buffer) |
| }}; |
| } |