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 ] |
57 | macro_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 ] |
116 | macro_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 ] |
160 | macro_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 ] |
201 | macro_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 ] |
295 | macro_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 | |