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 pointer: '❯',
95 arrow: '›',
96 completed: '✔',
97 middle_dot: '·',
98 cross: '✖',
99 box_top_right: '┐',
100 box_top_left: '┌',
101 box_bottom_right: '┘',
102 box_bottom_left: '└',
103 box_horizontal: '─',
104 box_vertical: '│',
105};
106
107/// A [`SymbolSet`] based exclusively on ASCII characters.
108///
109/// Since it contains only ASCII, it will be supported by all terminal emulators but may not look as
110/// good.
111pub const ASCII: SymbolSet = SymbolSet {
112 pointer: '>',
113 arrow: '>',
114 completed: '?',
115 middle_dot: '~',
116 cross: 'x',
117 box_top_right: '.',
118 box_top_left: '.',
119 box_bottom_right: '\'',
120 box_bottom_left: '\'',
121 box_horizontal: '-',
122 box_vertical: '|',
123};