1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//! Formatting and output helpers.
//!
//! We try to handle both textual output and interactive output (output to a
//! "TTY"). In the case of interactive output, we render with prettier non-ASCII
//! characters and with colors, using shell-specific escape codes.

/// Pluralize a quantity, as appropriate. Example:
///
/// ```
/// # use branchless::core::formatting::Pluralize;
/// let p = Pluralize { amount: 1, singular: "thing", plural: "things"};
/// assert_eq!(p.to_string(), "1 thing");
///
/// let p = Pluralize { amount: 2, singular: "thing", plural: "things"};
/// assert_eq!(p.to_string(), "2 things");
/// ```
pub struct Pluralize<'a> {
    /// The amount of the quantity.
    pub amount: isize,

    /// The string to render if the amount is singular.
    pub singular: &'a str,

    /// The string to render if the amount is plural.uee
    pub plural: &'a str,
}

impl<'a> ToString for Pluralize<'a> {
    fn to_string(&self) -> String {
        match self.amount {
            1 => format!("{} {}", self.amount, self.singular),
            _ => format!("{} {}", self.amount, self.plural),
        }
    }
}

/// Glyphs to use for rendering the smartlog.
pub struct Glyphs {
    /// Line connecting a parent commit to its single child commit.
    pub line: &'static str,

    /// Line connecting a parent commit with two or more child commits.
    pub line_with_offshoot: &'static str,

    /// Denotes an omitted sequence of commits.
    pub vertical_ellipsis: &'static str,

    /// Line used to connect a parent commit to its non-first child commit.
    pub slash: &'static str,

    /// Cursor for a visible commit which is not currently checked out.
    pub commit_visible: &'static str,

    /// Cursor for the visible commit which is currently checked out.
    pub commit_visible_head: &'static str,

    /// Cursor for a hidden commit.
    pub commit_hidden: &'static str,

    /// Cursor for the hidden commit which is currently checked out.
    pub commit_hidden_head: &'static str,

    /// Cursor for a commit belonging to the main branch, which is not currently
    /// checked out.
    pub commit_main: &'static str,

    /// Cursor for a commit belonging to the main branch, which is currently
    /// checked out.
    pub commit_main_head: &'static str,

    /// Cursor for a hidden commit belonging to the main branch. (This is an
    /// unusual situation.)
    pub commit_main_hidden: &'static str,

    /// Cursor for a hidden commit belonging to the main branch, which is
    /// currently checked out. (This is an unusual situation.)
    pub commit_main_hidden_head: &'static str,

    /// Bullet-point character for a list of newline-separated items.
    pub bullet_point: &'static str,
}

impl Glyphs {
    /// Make the `Glyphs` object appropriate for `stdout`.
    pub fn detect() -> Self {
        if console::user_attended() {
            Glyphs::pretty()
        } else {
            Glyphs::text()
        }
    }

    /// Glyphs used for output to a text file or non-TTY.
    pub fn text() -> Self {
        Glyphs {
            line: "|",
            line_with_offshoot: "|",
            vertical_ellipsis: ":",
            slash: "\\",
            commit_visible: "o",
            commit_visible_head: "@",
            commit_hidden: "x",
            commit_hidden_head: "%",
            commit_main: "O",
            commit_main_head: "@",
            commit_main_hidden: "X",
            commit_main_hidden_head: "%",
            bullet_point: "-",
        }
    }

    /// Glyphs used for output to a TTY.
    fn pretty() -> Self {
        Glyphs {
            line: "┃",
            line_with_offshoot: "┣",
            vertical_ellipsis: "⋮",
            slash: "━┓",
            commit_visible: "◯",
            commit_visible_head: "●",
            commit_hidden: "✕",
            commit_hidden_head: "⦻",
            commit_main: "◇",
            commit_main_head: "◆",
            commit_main_hidden: "✕",
            commit_main_hidden_head: "❖",
            bullet_point: "•",
        }
    }
}