1#![cfg_attr(not(test), no_std)]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5#![warn(missing_docs)]
6#![warn(clippy::print_stderr)]
7#![warn(clippy::print_stdout)]
8
9use core::sync::atomic::{AtomicUsize, Ordering};
10
11#[allow(clippy::exhaustive_enums)]
13#[derive(#[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::marker::Copy for ColorChoice { }Copy, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::clone::Clone for ColorChoice {
#[inline]
fn clone(&self) -> ColorChoice { *self }
}Clone, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::fmt::Debug for ColorChoice {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
ColorChoice::Auto => "Auto",
ColorChoice::AlwaysAnsi => "AlwaysAnsi",
ColorChoice::Always => "Always",
ColorChoice::Never => "Never",
})
}
}Debug, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::cmp::PartialEq for ColorChoice {
#[inline]
fn eq(&self, other: &ColorChoice) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::cmp::Eq for ColorChoice {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
#[allow(clippy::exhaustive_enums)]
impl ::core::default::Default for ColorChoice {
#[inline]
fn default() -> ColorChoice { Self::Auto }
}Default)]
14pub enum ColorChoice {
15 #[default]
17 Auto,
18 AlwaysAnsi,
21 Always,
25 Never,
27}
28
29impl ColorChoice {
30 pub fn global() -> Self {
32 USER.get()
33 }
34
35 pub fn write_global(self) {
37 USER.set(self);
38 }
39}
40
41static USER: AtomicChoice = AtomicChoice::new();
42
43#[derive(#[automatically_derived]
impl ::core::fmt::Debug for AtomicChoice {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "AtomicChoice",
&&self.0)
}
}Debug)]
44pub(crate) struct AtomicChoice(AtomicUsize);
45
46impl AtomicChoice {
47 pub(crate) const fn new() -> Self {
48 Self(AtomicUsize::new(Self::from_choice(ColorChoice::Auto)))
49 }
50
51 pub(crate) fn get(&self) -> ColorChoice {
52 let choice = self.0.load(Ordering::SeqCst);
53 Self::to_choice(choice).expect("Only `ColorChoice` values can be `set`")
54 }
55
56 pub(crate) fn set(&self, choice: ColorChoice) {
57 let choice = Self::from_choice(choice);
58 self.0.store(choice, Ordering::SeqCst);
59 }
60
61 const fn from_choice(choice: ColorChoice) -> usize {
62 match choice {
63 ColorChoice::Auto => 0,
64 ColorChoice::AlwaysAnsi => 1,
65 ColorChoice::Always => 2,
66 ColorChoice::Never => 3,
67 }
68 }
69
70 const fn to_choice(choice: usize) -> Option<ColorChoice> {
71 match choice {
72 0 => Some(ColorChoice::Auto),
73 1 => Some(ColorChoice::AlwaysAnsi),
74 2 => Some(ColorChoice::Always),
75 3 => Some(ColorChoice::Never),
76 _ => None,
77 }
78 }
79}
80
81impl Default for AtomicChoice {
82 fn default() -> Self {
83 Self::new()
84 }
85}
86
87#[cfg(test)]
88mod test {
89 use super::*;
90
91 #[test]
92 fn choice_serialization() {
93 let expected = vec![
94 ColorChoice::Auto,
95 ColorChoice::AlwaysAnsi,
96 ColorChoice::Always,
97 ColorChoice::Never,
98 ];
99 let values: Vec<_> = expected
100 .iter()
101 .cloned()
102 .map(AtomicChoice::from_choice)
103 .collect();
104 let actual: Vec<_> = values
105 .iter()
106 .cloned()
107 .filter_map(AtomicChoice::to_choice)
108 .collect();
109 assert_eq!(expected, actual);
110 }
111}
112
113#[doc = include_str!("../README.md")]
114#[cfg(doctest)]
115pub struct ReadmeDoctests;