diff options
Diffstat (limited to 'src/lex.rs')
-rw-r--r-- | src/lex.rs | 80 |
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 @@ | |||
1 | use crate::utils::FromStaticStr; | ||
2 | |||
3 | pub 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 | |||
12 | impl 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 | |||
41 | pub struct StanzaLexError { | ||
42 | pub data: String, | ||
43 | } | ||
44 | |||
45 | impl 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 | |||