requestty_ui/
symbols.rs

1//! Special characters used for prompts/widgets.
2//!
3//! There are 2 default [`SymbolSet`]s -- [`UNICODE`] and [`ASCII`]. If a particular [`SymbolSet`]
4//! is not set, [`UNICODE`] is used. The [`ASCII`] symbol set exists if you want to have larger
5//! compatibility with terminal emulators (such as Windows' `cmd.exe`) which do not support unicode
6//! characters.
7
8use std::sync::Mutex;
9
10use once_cell::sync::Lazy;
11
12static SET: Lazy<Mutex<SymbolSet>> = Lazy::new(|| Mutex::new(UNICODE));
13
14/// Get the current [`SymbolSet`]
15///
16/// If not set, it defaults to the [`UNICODE`] symbol set.
17///
18/// Also see [`symbols::set`](set).
19///
20/// # Example
21///
22/// ```no_run
23/// # #[cfg(feature = "ignore this line for doc test as requestty_ui should be used")]
24/// use requestty::symbols;
25/// # use requestty_ui::symbols;
26///
27/// let symbol_set = symbols::current();
28/// println!("{}", symbol_set.pointer);
29/// ```
30pub fn current() -> SymbolSet {
31    SET.lock().expect("symbol set poisoned").clone()
32}
33
34/// Set the current [`SymbolSet`]
35///
36/// Also see [`symbols::current`](current).
37///
38/// # Example
39///
40/// ```
41/// # #[cfg(feature = "ignore this line for doc test as requestty_ui should be used")]
42/// use requestty::symbols;
43/// # use requestty_ui::symbols;
44///
45/// symbols::set(symbols::ASCII);
46/// assert_eq!(symbols::current(), symbols::ASCII);
47/// ```
48pub fn set(new: SymbolSet) {
49    *SET.lock().expect("symbol set poisoned") = new;
50}
51
52#[derive(Debug, Clone, PartialEq, Eq)]
53/// The various special symbols used by the prompts during rendering.
54pub struct SymbolSet {
55    /// Used to point to a special item.
56    ///
57    /// For example, this is used in the various list prompts to show the currently hovered item.
58    pub pointer: char,
59    /// Generic decoration mark which points to the right.
60    ///
61    /// For example, this is used in the prompts when there is no hint between the question and the
62    /// answer.
63    pub arrow: char,
64    /// Decoration to show when a question is completed.
65    ///
66    /// For example, this is replaces the question mark when the question is answered.
67    pub completed: char,
68    /// Decoration to add some spacing without leaving it empty.
69    ///
70    /// For example, this is used by prompts to separate an answered question from its answer.
71    pub middle_dot: char,
72    /// A symbol to indicate something being wrong.
73    ///
74    /// For example, this is used by prompts if validation fails.
75    pub cross: char,
76    /// Character for the top right corner of a box.
77    pub box_top_right: char,
78    /// Character for the top left corner of a box.
79    pub box_top_left: char,
80    /// Character for the bottom right corner of a box.
81    pub box_bottom_right: char,
82    /// Character for the bottom left corner of a box.
83    pub box_bottom_left: char,
84    /// Character for the horizontal edge of a box.
85    pub box_horizontal: char,
86    /// Character for the vertical edge of a box.
87    pub box_vertical: char,
88}
89
90/// The default [`SymbolSet`].
91///
92/// It is composed of unicode characters and so may not be supported by all terminal emulators.
93pub const UNICODE: SymbolSet = SymbolSet {
94    /// `'❯' U+276F`
95    pointer: '❯',
96    /// `'›' U+203A`
97    arrow: '›',
98    /// `'✔' U+2714`
99    completed: '✔',
100    /// `'·' U+00B7`
101    middle_dot: '·',
102    /// `'✖' U+2716`
103    cross: '✖',
104    /// `'┐' U+2510`
105    box_top_right: '┐',
106    /// `'┌' U+250C`
107    box_top_left: '┌',
108    /// `'┘' U+2518`
109    box_bottom_right: '┘',
110    /// `'└' U+2514`
111    box_bottom_left: '└',
112    /// `'─' U+2500`
113    box_horizontal: '─',
114    /// `'│' U+2502`
115    box_vertical: '│',
116};
117
118/// A [`SymbolSet`] based exclusively on ASCII characters.
119///
120/// Since it contains only ASCII, it will be supported by all terminal emulators but may not look as
121/// good.
122pub const ASCII: SymbolSet = SymbolSet {
123    pointer: '>',
124    arrow: '>',
125    completed: '?',
126    middle_dot: '~',
127    cross: 'x',
128    box_top_right: '.',
129    box_top_left: '.',
130    box_bottom_right: '\'',
131    box_bottom_left: '\'',
132    box_horizontal: '-',
133    box_vertical: '|',
134};