summaryrefslogtreecommitdiffstats
path: root/src/poem/elements/rune.rs
blob: 8573583b1c3e130d0e60533651c9215e8aa4b4c7 (plain)
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
use core::fmt;

/// Describes one or two characters from the input
///
/// [Rune]s are a way to mark special characters from the input string
/// (i.e. poetry). Some [Rune]s are special--as they denote the end of a
/// [Verse][crate::poem::Verse]--and are refered to as a Meter. For
/// instance, `Addendum`, `Couplet`, `Quiet`, and `And`, are all meters.
/// Meters also determine how the [Stanza][super::stanza::Stanza] should
/// be interpreted. For instance, a [Stanza][super::stanza::Stanza] that
/// is piped needs to have its `STDOUT` captured (rather than printing
/// out to the terminal), and subsequently sent to the next
/// [Verse][crate::poem::Verse] in the [Poem][super::super::Poem].
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Rune {
    /// A shell command with no additional actions (the end of a poem)
    None,

    /// The space character, to dilineate words (`' '`)
    Pause,

    /// The backslash character, to escape special character (`\`)
    Special,

    /// The forward slash character, to dilineate paths (`/`)
    Path,

    /// Indicates a single line comment (`#`)
    Remark,

    /// Interpret all characters as one large [Word][super::word::Word]
    /// (`'` or `"`)
    String,

    /// A subcommand to run first (`\``)
    Poem,

    /// Denotes an environment variable (`=`),
    /// only if the verse is empty so far
    Notes,

    /// Read files into STDIN (`<`)
    Read,

    /// Write STDOUT to a file (`>`)
    Write,

    /// Write STDERR to a file (`2>`)
    Write2,

    /// Write both STDOUT and STDERR to a file (`&>`)
    WriteAll,

    /// Append STDOUT to a file (`>>`)
    Addendum,

    /// Append STDERR to a file (`2>>`)
    Addendum2,

    /// Append both STDOUT and STDERR to a file (`&>>`)
    AddendumAll,

    /// Pipe the output of this command into the next (`|`)
    Couplet,

    /// Fork the called process into the background (`&`)
    Quiet,

    /// Run the next command, only if this one succeeds (`&&`)
    And,

    /// Run the next command, regardless of whether or not this command
    /// succeeds (`;` or a newline in a file)
    Continue,

    /// Interpret `~` as `$HOME`
    Home,

    /// Any other character
    Else,
}

impl fmt::Display for Rune {
    /// Determine how to print out a [Rune]
    ///
    /// Each [Rune]'s symbol corresponds to its input.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let rune = match self {
            Rune::None => "",
            Rune::Pause => " ",
            Rune::Special => "\\",
            Rune::Path => "/",
            Rune::Remark => "#",
            Rune::String => "\"",
            Rune::Poem => "`",
            Rune::Notes => "=",
            Rune::Read => "<",
            Rune::Write => ">",
            Rune::Write2 => "2>",
            Rune::WriteAll => "&>",
            Rune::Addendum => ">>",
            Rune::Addendum2 => "2>>",
            Rune::AddendumAll => "&>>",
            Rune::Couplet => "|",
            Rune::Quiet => "&",
            Rune::And => "&&",
            Rune::Continue => ";",
            Rune::Home => "~",
            Rune::Else => "_",
        };

        write!(f, "{}", rune)
    }
}