1/// Prints to [`stdout`][crate::stdout].
2///
3/// Equivalent to the [`println!`] macro except that a newline is not printed at
4/// the end of the message.
5///
6/// Note that stdout is frequently line-buffered by default so it may be
7/// necessary to use [`std::io::Write::flush()`] to ensure the output is emitted
8/// immediately.
9///
10/// **NOTE:** The `print!` macro will lock the standard output on each call. If you call
11/// `print!` within a hot loop, this behavior may be the bottleneck of the loop.
12/// To avoid this, lock stdout with [`AutoStream::lock`][crate::AutoStream::lock]:
13/// ```
14/// # #[cfg(feature = "auto")] {
15/// use std::io::Write as _;
16///
17/// let mut lock = anstream::stdout().lock();
18/// write!(lock, "hello world").unwrap();
19/// # }
20/// ```
21///
22/// Use `print!` only for the primary output of your program. Use
23/// [`eprint!`] instead to print error and progress messages.
24///
25/// # Panics
26///
27/// Panics if writing to `stdout` fails for any reason **except** broken pipe.
28///
29/// Writing to non-blocking stdout can cause an error, which will lead
30/// this macro to panic.
31///
32/// # Examples
33///
34/// ```
35/// # #[cfg(feature = "auto")] {
36/// use std::io::Write as _;
37/// use anstream::print;
38/// use anstream::stdout;
39///
40/// print!("this ");
41/// print!("will ");
42/// print!("be ");
43/// print!("on ");
44/// print!("the ");
45/// print!("same ");
46/// print!("line ");
47///
48/// stdout().flush().unwrap();
49///
50/// print!("this string has a newline, why not choose println! instead?\n");
51///
52/// stdout().flush().unwrap();
53/// # }
54/// ```
55#[cfg(feature = "auto")]
56#[macro_export]
57macro_rules! print {
58 ($($arg:tt)*) => {{
59 use std::io::Write as _;
60
61 let mut stream = $crate::stdout();
62 match ::std::write!(&mut stream, $($arg)*) {
63 Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
64 ::std::panic!("failed printing to stdout: {e}");
65 }
66 Err(_) | Ok(_) => {}
67 }
68 }};
69}
70
71/// Prints to [`stdout`][crate::stdout], with a newline.
72///
73/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
74/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)).
75///
76/// This macro uses the same syntax as [`format!`], but writes to the standard output instead.
77/// See [`std::fmt`] for more information.
78///
79/// **NOTE:** The `println!` macro will lock the standard output on each call. If you call
80/// `println!` within a hot loop, this behavior may be the bottleneck of the loop.
81/// To avoid this, lock stdout with [`AutoStream::lock`][crate::AutoStream::lock]:
82/// ```
83/// # #[cfg(feature = "auto")] {
84/// use std::io::Write as _;
85///
86/// let mut lock = anstream::stdout().lock();
87/// writeln!(lock, "hello world").unwrap();
88/// # }
89/// ```
90///
91/// Use `println!` only for the primary output of your program. Use
92/// [`eprintln!`] instead to print error and progress messages.
93///
94/// # Panics
95///
96/// Panics if writing to `stdout` fails for any reason **except** broken pipe.
97///
98/// Writing to non-blocking stdout can cause an error, which will lead
99/// this macro to panic.
100///
101/// # Examples
102///
103/// ```
104/// # #[cfg(feature = "auto")] {
105/// use anstream::println;
106///
107/// println!(); // prints just a newline
108/// println!("hello there!");
109/// println!("format {} arguments", "some");
110/// let local_variable = "some";
111/// println!("format {local_variable} arguments");
112/// # }
113/// ```
114#[cfg(feature = "auto")]
115#[macro_export]
116macro_rules! println {
117 () => {
118 $crate::print!("\n")
119 };
120 ($($arg:tt)*) => {{
121 use std::io::Write as _;
122
123 let mut stream = $crate::stdout();
124 match ::std::writeln!(&mut stream, $($arg)*) {
125 Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
126 ::std::panic!("failed printing to stdout: {e}");
127 }
128 Err(_) | Ok(_) => {}
129 }
130 }};
131}
132
133/// Prints to [`stderr`][crate::stderr].
134///
135/// Equivalent to the [`print!`] macro, except that output goes to
136/// `stderr` instead of `stdout`. See [`print!`] for
137/// example usage.
138///
139/// Use `eprint!` only for error and progress messages. Use `print!`
140/// instead for the primary output of your program.
141///
142/// # Panics
143///
144/// Panics if writing to `stderr` fails for any reason **except** broken pipe.
145///
146/// Writing to non-blocking stdout can cause an error, which will lead
147/// this macro to panic.
148///
149/// # Examples
150///
151/// ```
152/// # #[cfg(feature = "auto")] {
153/// use anstream::eprint;
154///
155/// eprint!("Error: Could not complete task");
156/// # }
157/// ```
158#[cfg(feature = "auto")]
159#[macro_export]
160macro_rules! eprint {
161 ($($arg:tt)*) => {{
162 use std::io::Write as _;
163
164 let mut stream = $crate::stderr();
165 match ::std::write!(&mut stream, $($arg)*) {
166 Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
167 ::std::panic!("failed printing to stdout: {e}");
168 }
169 Err(_) | Ok(_) => {}
170 }
171 }};
172}
173
174/// Prints to [`stderr`][crate::stderr], with a newline.
175///
176/// Equivalent to the [`println!`] macro, except that output goes to
177/// `stderr` instead of `stdout`. See [`println!`] for
178/// example usage.
179///
180/// Use `eprintln!` only for error and progress messages. Use `println!`
181/// instead for the primary output of your program.
182///
183/// # Panics
184///
185/// Panics if writing to `stderr` fails for any reason **except** broken pipe.
186///
187/// Writing to non-blocking stdout can cause an error, which will lead
188/// this macro to panic.
189///
190/// # Examples
191///
192/// ```
193/// # #[cfg(feature = "auto")] {
194/// use anstream::eprintln;
195///
196/// eprintln!("Error: Could not complete task");
197/// # }
198/// ```
199#[cfg(feature = "auto")]
200#[macro_export]
201macro_rules! eprintln {
202 () => {
203 $crate::eprint!("\n")
204 };
205 ($($arg:tt)*) => {{
206 use std::io::Write as _;
207
208 let mut stream = $crate::stderr();
209 match ::std::writeln!(&mut stream, $($arg)*) {
210 Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
211 ::std::panic!("failed printing to stdout: {e}");
212 }
213 Err(_) | Ok(_) => {}
214 }
215 }};
216}
217
218/// Panics the current thread.
219///
220/// This allows a program to terminate immediately and provide feedback
221/// to the caller of the program.
222///
223/// This macro is the perfect way to assert conditions in example code and in
224/// tests. `panic!` is closely tied with the `unwrap` method of both
225/// [`Option`][ounwrap] and [`Result`][runwrap] enums. Both implementations call
226/// `panic!` when they are set to [`None`] or [`Err`] variants.
227///
228/// When using `panic!()` you can specify a string payload, that is built using
229/// the [`format!`] syntax. That payload is used when injecting the panic into
230/// the calling Rust thread, causing the thread to panic entirely.
231///
232/// The behavior of the default `std` hook, i.e. the code that runs directly
233/// after the panic is invoked, is to print the message payload to
234/// `stderr` along with the file/line/column information of the `panic!()`
235/// call. You can override the panic hook using [`std::panic::set_hook()`].
236/// Inside the hook a panic can be accessed as a `&dyn Any + Send`,
237/// which contains either a `&str` or `String` for regular `panic!()` invocations.
238/// To panic with a value of another other type, [`panic_any`] can be used.
239///
240/// See also the macro [`compile_error!`], for raising errors during compilation.
241///
242/// # When to use `panic!` vs `Result`
243///
244/// The Rust language provides two complementary systems for constructing /
245/// representing, reporting, propagating, reacting to, and discarding errors. These
246/// responsibilities are collectively known as "error handling." `panic!` and
247/// `Result` are similar in that they are each the primary interface of their
248/// respective error handling systems; however, the meaning these interfaces attach
249/// to their errors and the responsibilities they fulfill within their respective
250/// error handling systems differ.
251///
252/// The `panic!` macro is used to construct errors that represent a bug that has
253/// been detected in your program. With `panic!` you provide a message that
254/// describes the bug and the language then constructs an error with that message,
255/// reports it, and propagates it for you.
256///
257/// `Result` on the other hand is used to wrap other types that represent either
258/// the successful result of some computation, `Ok(T)`, or error types that
259/// represent an anticipated runtime failure mode of that computation, `Err(E)`.
260/// `Result` is used alongside user defined types which represent the various
261/// anticipated runtime failure modes that the associated computation could
262/// encounter. `Result` must be propagated manually, often with the the help of the
263/// `?` operator and `Try` trait, and they must be reported manually, often with
264/// the help of the `Error` trait.
265///
266/// For more detailed information about error handling check out the [book] or the
267/// [`std::result`] module docs.
268///
269/// [ounwrap]: Option::unwrap
270/// [runwrap]: Result::unwrap
271/// [`std::panic::set_hook()`]: ../std/panic/fn.set_hook.html
272/// [`panic_any`]: ../std/panic/fn.panic_any.html
273/// [`Box`]: ../std/boxed/struct.Box.html
274/// [`Any`]: crate::any::Any
275/// [`format!`]: ../std/macro.format.html
276/// [book]: ../book/ch09-00-error-handling.html
277/// [`std::result`]: ../std/result/index.html
278///
279/// # Current implementation
280///
281/// If the main thread panics it will terminate all your threads and end your
282/// program with code `101`.
283///
284/// # Examples
285///
286/// ```should_panic
287/// # #![allow(unreachable_code)]
288/// use anstream::panic;
289/// panic!();
290/// panic!("this is a terrible mistake!");
291/// panic!("this is a {} {message}", "fancy", message = "message");
292/// ```
293#[cfg(feature = "auto")]
294#[macro_export]
295macro_rules! panic {
296 () => {
297 ::std::panic!()
298 };
299 ($($arg:tt)*) => {{
300 use std::io::Write as _;
301
302 let panic_stream = std::io::stderr();
303 let choice = $crate::AutoStream::choice(&panic_stream);
304 let buffer = $crate::Buffer::new();
305 let mut stream = $crate::AutoStream::new(buffer, choice);
306 // Ignore errors rather than panic
307 let _ = ::std::write!(&mut stream, $($arg)*);
308 let buffer = stream.into_inner();
309 // Should be UTF-8 but not wanting to panic
310 let buffer = String::from_utf8_lossy(buffer.as_bytes()).into_owned();
311 ::std::panic!("{}", buffer)
312 }};
313}
314