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 ] |
61 | macro_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 ] |
139 | macro_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 ] |
202 | macro_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 ] |
262 | macro_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 ] |
371 | macro_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 | |