aboutsummaryrefslogtreecommitdiff
path: root/src/lex.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lex.rs')
-rw-r--r--src/lex.rs80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/lex.rs b/src/lex.rs
new file mode 100644
index 0000000..0f9a535
--- /dev/null
+++ b/src/lex.rs
@@ -0,0 +1,80 @@
1use crate::utils::FromStaticStr;
2
3pub enum Stanza {
4 Entry(&'static str),
5 Defn(&'static str),
6 Note(&'static str),
7 Synonym(&'static str),
8 Bullet(&'static str),
9 SubBullet(&'static str),
10}
11
12impl Stanza {
13 fn is_entry(s: &str) -> bool {
14 s.chars().all(|c| c.is_uppercase() || c.is_ascii_whitespace() || "-;'.".contains(c))
15 }
16
17 fn is_defn(s: &str) -> bool {
18 s.starts_with("Defn")
19 }
20
21 fn is_note(s: &str) -> bool {
22 s.starts_with("Note")
23 }
24
25 fn is_synonym(s: &str) -> bool {
26 s.starts_with("Syn")
27 }
28
29 fn is_bullet(s: &str) -> bool {
30 s.find('.').map(|idx| s[..idx].chars().all(char::is_numeric)).unwrap_or_default()
31 }
32
33 fn is_sub_bullet(s: &str) -> bool {
34 let mut chars = s.chars();
35 chars.next().map(|c| c == '(').unwrap_or_default()
36 && chars.next().map(char::is_alphabetic).unwrap_or_default()
37 && chars.next().map(|c| c == ')').unwrap_or_default()
38 }
39}
40
41pub struct StanzaLexError {
42 pub data: String,
43}
44
45impl FromStaticStr for Stanza {
46 type Err = StanzaLexError;
47 fn from_str(s: &'static str) -> Result<Self, Self::Err> {
48 let mut lines = s.split("\n");
49 if let Some(first_line) = lines.next() {
50 if !first_line.is_empty() {
51 if Stanza::is_entry(first_line) {
52 Ok(Self::Entry(s))
53 } else if Stanza::is_defn(first_line) {
54 Ok(Self::Defn(s))
55 } else if Stanza::is_note(first_line) {
56 Ok(Self::Note(s))
57 } else if Stanza::is_synonym(first_line) {
58 Ok(Self::Synonym(s))
59 } else if Stanza::is_bullet(first_line) {
60 Ok(Self::Bullet(s))
61 } else if Stanza::is_sub_bullet(first_line) {
62 Ok(Self::SubBullet(s))
63 } else {
64 Err(Self::Err {
65 data: format!("weird stanza: {}", s),
66 })
67 }
68 } else {
69 Err(Self::Err {
70 data: format!("empty first line: {}", s),
71 })
72 }
73 } else {
74 Err(Self::Err {
75 data: format!("empty stanza: {}", s),
76 })
77 }
78 }
79}
80