diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 107 |
1 files changed, 10 insertions, 97 deletions
diff --git a/src/main.rs b/src/main.rs index e6d997d..9def90c 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -1,101 +1,14 @@ | |||
1 | mod consts; | 1 | use dict::{consts::SRC, lex, parse::ParseState}; |
2 | mod utils; | ||
3 | mod lex; | ||
4 | |||
5 | use consts::SRC; | ||
6 | use lex::{Stanza, StanzaLexError}; | ||
7 | use utils::FromStaticStr; | ||
8 | 2 | ||
9 | fn main() { | 3 | fn main() { |
10 | let mut count = 0; | 4 | let Some(search_term) = std::env::args().skip(1).next() else { |
11 | let mut parse_state = ParseState::Ready; | 5 | eprintln!("usage: dict <search-term>"); |
12 | let mut current_entry = EntryBuilder::new(); | 6 | return; |
13 | let mut dict = Dictionary { | ||
14 | entries: vec![], | ||
15 | }; | 7 | }; |
16 | 8 | lex::lex(SRC) | |
17 | for l in SRC.split("\n\n") { | 9 | .filter_map(Result::ok) |
18 | count += 1; | 10 | .fold(ParseState::new(), ParseState::advance) |
19 | let stanza = match Stanza::from_str(l) { | 11 | .finish() |
20 | Ok(s) => { | 12 | .search(search_term.to_ascii_uppercase().as_str()) |
21 | println!("{count} ok"); | 13 | .print() |
22 | s | ||
23 | }, | ||
24 | Err(StanzaLexError { data }) => { | ||
25 | eprintln!("stanza err: {data}\n\n"); | ||
26 | continue; | ||
27 | }, | ||
28 | }; | ||
29 | match stanza { | ||
30 | Stanza::Entry(s) if parse_state == ParseState::Ready => { | ||
31 | current_entry.set_name(s); | ||
32 | parse_state = ParseState::InEntry; | ||
33 | } | ||
34 | Stanza::Defn(d) if parse_state == ParseState::InEntry => { | ||
35 | current_entry.set_defn(d); | ||
36 | |||
37 | match current_entry.build() { | ||
38 | Ok(e) => dict.entries.push(e), | ||
39 | Err(_) => eprintln!("failed to build entry"), | ||
40 | } | ||
41 | |||
42 | parse_state = ParseState::Ready; | ||
43 | } | ||
44 | _ => () | ||
45 | } | ||
46 | } | ||
47 | dbg!(dict.entries.iter().find(|entry| entry.name.to_ascii_lowercase().starts_with("discursive"))); | ||
48 | } | ||
49 | |||
50 | #[derive(PartialEq, Eq, PartialOrd, Ord)] | ||
51 | enum ParseState { | ||
52 | Ready, | ||
53 | InEntry | ||
54 | } | ||
55 | |||
56 | struct Dictionary { | ||
57 | entries: Vec<Entry> | ||
58 | } | ||
59 | |||
60 | #[derive(Debug)] | ||
61 | struct Entry { | ||
62 | name: &'static str, | ||
63 | defn: Option<&'static str>, | ||
64 | note: Option<&'static str>, | ||
65 | synonym: Option<&'static str>, | ||
66 | } | ||
67 | |||
68 | #[derive(Default)] | ||
69 | struct EntryBuilder { | ||
70 | name: Option<&'static str>, | ||
71 | defn: Option<&'static str>, | ||
72 | note: Option<&'static str>, | ||
73 | synonym: Option<&'static str>, | ||
74 | } | ||
75 | |||
76 | enum EntryBuilderError { | ||
77 | MissingField(&'static str) | ||
78 | } | ||
79 | |||
80 | impl EntryBuilder { | ||
81 | fn new() -> Self { | ||
82 | Self::default() | ||
83 | } | ||
84 | |||
85 | fn set_name(&mut self, name: &'static str) { | ||
86 | self.name = Some(name); | ||
87 | } | ||
88 | |||
89 | fn set_defn(&mut self, defn: &'static str) { | ||
90 | self.defn = Some(defn); | ||
91 | } | ||
92 | |||
93 | fn build(&self) -> Result<Entry, EntryBuilderError> { | ||
94 | Ok(Entry { | ||
95 | name: self.name.ok_or(EntryBuilderError::MissingField("name"))?, | ||
96 | defn: self.defn, | ||
97 | note: self.note, | ||
98 | synonym: self.synonym, | ||
99 | }) | ||
100 | } | ||
101 | } | 14 | } |