summaryrefslogtreecommitdiff
path: root/vendor/anstream/src/macros.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/anstream/src/macros.rs')
-rw-r--r--vendor/anstream/src/macros.rs389
1 files changed, 389 insertions, 0 deletions
diff --git a/vendor/anstream/src/macros.rs b/vendor/anstream/src/macros.rs
new file mode 100644
index 0000000..bd1accb
--- /dev/null
+++ b/vendor/anstream/src/macros.rs
@@ -0,0 +1,389 @@
+/// 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)
+ }};
+}