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