unwind_context/
set_colors.rs1use core::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
2
3#[cfg(feature = "custom-default-colors")]
4use atomic_ref::AtomicRef;
5
6use crate::{AnsiColorScheme, DEFAULT_DEFAULT_COLOR_SCHEME};
7
8static SHOULD_COLORIZE: AtomicBool = AtomicBool::new(false);
9
10#[cfg(feature = "custom-default-colors")]
11#[cfg_attr(docsrs, doc(cfg(feature = "custom-default-colors")))]
12static DEFAULT_COLOR_SCHEME: AtomicRef<'_, AnsiColorScheme> = AtomicRef::new(None);
13
14#[inline]
55pub fn set_colors_enabled(enabled: bool) {
56 SHOULD_COLORIZE.store(enabled, AtomicOrdering::Relaxed);
57}
58
59#[doc(hidden)]
60#[deprecated(since = "0.2.0", note = "renamed to `set_colors_enabled`.")]
61pub use set_colors_enabled as set_ansi_colors_enabled;
62
63#[inline]
77pub fn are_colors_enabled() -> bool {
78 SHOULD_COLORIZE.load(AtomicOrdering::Relaxed)
79}
80
81#[doc(hidden)]
82#[deprecated(since = "0.2.0", note = "renamed to `are_colors_enabled`.")]
83pub use are_colors_enabled as are_ansi_colors_enabled;
84
85#[cfg(feature = "detect-color-support")]
86#[cfg_attr(docsrs, doc(cfg(feature = "detect-color-support")))]
87#[inline]
134pub fn enable_colors_if_supported() {
135 use supports_color::Stream;
136 if supports_color::on(Stream::Stderr).is_some() {
137 set_colors_enabled(true);
138 }
139}
140
141#[cfg(feature = "detect-color-support")]
142#[doc(hidden)]
143#[deprecated(since = "0.2.0", note = "renamed to `enable_colors_if_supported`.")]
144pub use enable_colors_if_supported as enable_ansi_colors_if_supported;
145
146#[cfg(feature = "custom-default-colors")]
147#[cfg_attr(docsrs, doc(cfg(feature = "custom-default-colors")))]
148#[inline]
174pub fn set_default_color_scheme(color_scheme: &'static AnsiColorScheme) {
175 DEFAULT_COLOR_SCHEME.store(Some(color_scheme), AtomicOrdering::Release);
176}
177
178#[cfg(feature = "custom-default-colors")]
179#[doc(hidden)]
180#[deprecated(since = "0.2.0", note = "renamed to `set_default_color_scheme`.")]
181pub use set_default_color_scheme as set_ansi_color_scheme;
182
183#[inline]
198#[must_use]
199pub fn get_default_color_scheme() -> &'static AnsiColorScheme {
200 get_default_ansi_color_scheme_impl()
201}
202
203#[doc(hidden)]
204#[deprecated(since = "0.2.0", note = "renamed to `get_default_color_scheme`.")]
205pub use get_default_color_scheme as get_ansi_color_scheme;
206
207#[cfg(feature = "custom-default-colors")]
208#[inline]
209fn get_default_ansi_color_scheme_impl() -> &'static AnsiColorScheme {
210 DEFAULT_COLOR_SCHEME
211 .load(AtomicOrdering::Acquire)
212 .unwrap_or(&DEFAULT_DEFAULT_COLOR_SCHEME)
213}
214
215#[cfg(not(feature = "custom-default-colors"))]
216#[inline]
217fn get_default_ansi_color_scheme_impl() -> &'static AnsiColorScheme {
218 &DEFAULT_DEFAULT_COLOR_SCHEME
219}
220
221#[inline]
237#[must_use]
238pub fn get_default_color_scheme_if_enabled() -> Option<&'static AnsiColorScheme> {
239 are_colors_enabled().then(get_default_color_scheme)
240}
241
242#[doc(hidden)]
243#[deprecated(
244 since = "0.2.0",
245 note = "renamed to `get_default_color_scheme_if_enabled`."
246)]
247pub use get_default_color_scheme_if_enabled as get_ansi_color_scheme_if_colors_enabled;
248
249#[cfg(all(test, feature = "std"))]
250mod tests {
251 #[cfg(all(feature = "std", feature = "detect-color-support"))]
252 use crate::enable_colors_if_supported;
253 use crate::test_common::{SERIAL_TEST, TEST_COLOR_SCHEME};
254 use crate::test_util::FixedBufWriter;
255 use crate::{
256 are_colors_enabled, set_colors_enabled, unwind_context_with_fmt, StdPanicDetector,
257 };
258 #[cfg(feature = "custom-default-colors")]
259 use crate::{set_default_color_scheme, DEFAULT_DEFAULT_COLOR_SCHEME};
260
261 #[test]
262 fn test_set_ansi_colors_enabled() {
263 let _guard = SERIAL_TEST.lock().unwrap();
264
265 let mut buffer = [0; 128];
266 let foo = 123;
267 let bar = "BAR";
268
269 assert!(!are_colors_enabled());
270
271 let mut writer = FixedBufWriter::new(&mut buffer);
273 let mut ctx = unwind_context_with_fmt!(
274 (foo, bar),
275 writer = &mut writer,
276 panic_detector = StdPanicDetector
277 );
278 ctx.print();
279 drop(ctx);
280 assert!(writer
281 .into_str()
282 .starts_with("foo: 123, bar: \"BAR\"\n at "));
283
284 let mut writer = FixedBufWriter::new(&mut buffer);
286 let mut ctx = unwind_context_with_fmt!(
287 (foo, bar),
288 writer = &mut writer,
289 panic_detector = StdPanicDetector,
290 color_scheme = Some(&TEST_COLOR_SCHEME)
291 );
292 ctx.print();
293 drop(ctx);
294 assert!(writer
295 .into_str()
296 .starts_with("foo: {NUM}123{DEF}, bar: {QUOT}\"BAR\"{DEF}\n at {LOC}"));
297
298 set_colors_enabled(true);
299 assert!(are_colors_enabled());
300
301 let mut writer = FixedBufWriter::new(&mut buffer);
303 let mut ctx = unwind_context_with_fmt!(
304 (foo, bar),
305 writer = &mut writer,
306 panic_detector = StdPanicDetector,
307 );
308 ctx.print();
309 drop(ctx);
310 assert!(writer.into_str().starts_with(
311 "foo: \u{1b}[0;96m123\u{1b}[0m, bar: \u{1b}[0;32m\"BAR\"\u{1b}[0m\n at \u{1b}[94m"
312 ));
313
314 let mut writer = FixedBufWriter::new(&mut buffer);
316 assert!(are_colors_enabled());
317 let mut ctx = unwind_context_with_fmt!(
318 (foo, bar),
319 writer = &mut writer,
320 panic_detector = StdPanicDetector,
321 color_scheme = Some(&TEST_COLOR_SCHEME)
322 );
323 ctx.print();
324 drop(ctx);
325 assert!(writer
326 .into_str()
327 .starts_with("foo: {NUM}123{DEF}, bar: {QUOT}\"BAR\"{DEF}\n at {LOC}"));
328
329 set_colors_enabled(false);
330 assert!(!are_colors_enabled());
331
332 let mut writer = FixedBufWriter::new(&mut buffer);
334 let mut ctx = unwind_context_with_fmt!(
335 (foo, bar),
336 writer = &mut writer,
337 panic_detector = StdPanicDetector
338 );
339 ctx.print();
340 drop(ctx);
341 assert!(writer
342 .into_str()
343 .starts_with("foo: 123, bar: \"BAR\"\n at "));
344 }
345
346 #[cfg(all(feature = "std", feature = "detect-color-support"))]
347 #[test]
348 fn test_enable_ansi_colors_if_supported() {
349 let _guard = SERIAL_TEST.lock().unwrap();
350
351 assert!(!are_colors_enabled());
352
353 std::env::remove_var("FORCE_COLOR");
354 std::env::remove_var("NO_COLOR");
355 std::env::set_var("IGNORE_IS_TERMINAL", "true");
356 std::env::set_var("TERM", "dumb");
357 enable_colors_if_supported();
358 assert!(!are_colors_enabled());
359
360 std::env::set_var("TERM", "xterm-256color");
361 std::env::set_var("COLORTERM", "truecolor");
362 enable_colors_if_supported();
363 assert!(are_colors_enabled());
364 set_colors_enabled(false);
365
366 std::env::set_var("NO_COLOR", "true");
367 enable_colors_if_supported();
368 assert!(!are_colors_enabled());
369
370 std::env::remove_var("NO_COLOR");
371 std::env::set_var("FORCE_COLOR", "true");
372 enable_colors_if_supported();
373 assert!(are_colors_enabled());
374 set_colors_enabled(false);
375
376 set_colors_enabled(false);
377 assert!(!are_colors_enabled());
378 }
379
380 #[cfg(feature = "custom-default-colors")]
381 #[test]
382 fn test_set_default_ansi_color_scheme() {
383 let _guard = SERIAL_TEST.lock().unwrap();
384
385 let mut buffer = [0; 128];
386 let foo = 123;
387 let bar = "BAR";
388
389 set_colors_enabled(true);
390 assert!(are_colors_enabled());
391
392 let mut writer = FixedBufWriter::new(&mut buffer);
394 let mut ctx = unwind_context_with_fmt!(
395 (foo, bar),
396 writer = &mut writer,
397 panic_detector = StdPanicDetector,
398 );
399 ctx.print();
400 drop(ctx);
401 assert!(writer.into_str().starts_with(concat!(
402 "foo: \u{1b}[0;96m123",
403 "\u{1b}[0m, bar: \u{1b}[0;32m\"BAR\"",
404 "\u{1b}[0m\n at \u{1b}[94m"
405 )));
406
407 set_default_color_scheme(&TEST_COLOR_SCHEME);
408
409 let mut writer = FixedBufWriter::new(&mut buffer);
411 assert!(are_colors_enabled());
412 let mut ctx = unwind_context_with_fmt!(
413 (foo, bar),
414 writer = &mut writer,
415 panic_detector = StdPanicDetector,
416 );
417 ctx.print();
418 drop(ctx);
419 assert!(writer
420 .into_str()
421 .starts_with("foo: {NUM}123{DEF}, bar: {QUOT}\"BAR\"{DEF}\n at {LOC}"));
422
423 set_default_color_scheme(&DEFAULT_DEFAULT_COLOR_SCHEME);
424
425 let mut writer = FixedBufWriter::new(&mut buffer);
427 assert!(are_colors_enabled());
428 let mut ctx = unwind_context_with_fmt!(
429 (foo, bar),
430 writer = &mut writer,
431 panic_detector = StdPanicDetector,
432 );
433 ctx.print();
434 drop(ctx);
435 assert!(writer.into_str().starts_with(concat!(
436 "foo: \u{1b}[0;96m123",
437 "\u{1b}[0m, bar: \u{1b}[0;32m\"BAR\"",
438 "\u{1b}[0m\n at \u{1b}[94m"
439 )));
440
441 set_colors_enabled(false);
442 assert!(!are_colors_enabled());
443 }
444}