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};