aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJJ2023-06-17 21:23:06 +0000
committerJJ2023-06-17 21:23:06 +0000
commit4d7f63203724d246d5b58a50a57b6e7d42ab7951 (patch)
tree8eee87e17cea85f030c0f0d033328f630d23e2b1
parentc1c5c3257b91f54d240b0fe3d6a844ce48ef6556 (diff)
minor idiomatic changes
-rw-r--r--LICENSE2
-rw-r--r--parse_wiki_text/src/display.rs4
-rw-r--r--src/lib.rs64
-rw-r--r--src/main.rs27
4 files changed, 53 insertions, 44 deletions
diff --git a/LICENSE b/LICENSE
index 90f2d3c..d4d246a 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
- Copyright (C) 2022 JJ <https://j-james.me>
+ Copyright (C) 2023 JJ <https://apropos.codes>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
diff --git a/parse_wiki_text/src/display.rs b/parse_wiki_text/src/display.rs
index cc2b258..4c1f03a 100644
--- a/parse_wiki_text/src/display.rs
+++ b/parse_wiki_text/src/display.rs
@@ -6,8 +6,8 @@
use crate::{Node, Parameter};
use std::fmt::Error;
-// why is std::other::Result not usable when i import std::fmt::Result?
+// why is core::result::Result not usable when i import std::fmt::Result?
impl std::fmt::Display for Node<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return match self {
@@ -186,7 +186,7 @@ fn get<'a>(parameters: &'a Vec<Parameter>, index: usize) -> Result<&'a str, Erro
}
-fn get_language<'a>(country_code: &'a str) -> &'a str {
+fn get_language(country_code: &str) -> &'static str {
return "English";
// todo: implement necessary parts of isolang
// if country_code.len() == 3 {
diff --git a/src/lib.rs b/src/lib.rs
index afcf8e8..cf2249c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,8 +2,7 @@
#![allow(unused_variables)]
#![feature(let_chains)]
-use std::io::*;
-use std::fs::File;
+use std::{io::*, fs::File};
// note that bufread::MultiBzDecoder is _distinct_ from read::MultiBzDecoder
use bzip2::bufread::*;
use parse_wiki_text::*;
@@ -13,13 +12,13 @@ const version: &str = env!("CARGO_PKG_VERSION");
const index_path: &str = env!("index_path");
const dictionary_path: &str = env!("dictionary_path");
-pub fn handle(word: String, state: &State) {
+pub fn handle_word(word: String, state: &State) {
// if lets are kinda clunky
- if let Some(definition) = lookup(&word) {
+ if let Some(definition) = lookup(&word).unwrap() {
display(definition, &state);
} else if let Some(corrected) = correct(&word) {
println!("Could not find word {}, continuing with {}...", word, corrected);
- if let Some(definition) = lookup(&corrected) {
+ if let Some(definition) = lookup(&corrected).unwrap() {
display(definition, &state);
} else {
println!("Could not find corrected word {}.", corrected);
@@ -29,10 +28,22 @@ pub fn handle(word: String, state: &State) {
}
}
+// i don't like that there are multiple result types
+// that seems Bad
+// also having to explicitly box dyn Error sucks, fine fuck you it's the rust way
+type Lookup = std::result::Result<Option<String>, Box<dyn std::error::Error>>;
+
// WHY can you not implement traits on external types, like what??
// fortunately we needed to copy-paste the parse_wiki_text library to fix some bugs anyhow
-fn lookup(word: &str) -> Option<String> {
- let file = File::open(index_path).expect("Failed to open index file");
+fn lookup(word: &str) -> Lookup {
+ if let Ok(file) = File::open(index_path) {
+ return lookup_local(word, file);
+ } else {
+ return lookup_online(word);
+ }
+}
+
+fn lookup_local(word: &str, file: File) -> Lookup {
let reader = BufReader::new(MultiBzDecoder::new(BufReader::new(file)));
for line in reader.lines() {
let line = line.expect("Failed to read line");
@@ -41,15 +52,12 @@ fn lookup(word: &str) -> Option<String> {
let line = line.splitn(3, ":").collect::<Vec<&str>>();
assert!(line.len() == 3, "Failed to parse line. Is your index file valid?");
- let offset = line.get(0).unwrap().parse::<u64>()
- .expect("Failed to parse offset. Is your index file valid?");
- let id = line.get(1).unwrap().parse::<u64>()
- .expect("Failed to parse id. Is your index file valid?");
+ let offset = line.get(0).unwrap().parse::<u64>()?;
+ let id = line.get(1).unwrap().parse::<u64>()?;
let title = *line.get(2).unwrap(); // this dereference now makes sense
if title == word {
- let file = File::open(dictionary_path)
- .expect("Failed to open dictionary file");
+ let file = File::open(dictionary_path)?;
let mut reader = BufReader::new(file);
// note: our chunk contains multiple pages
@@ -74,16 +82,19 @@ fn lookup(word: &str) -> Option<String> {
}
}
}
- return Some(buffer);
+ return Ok(Some(buffer));
}
}
- return None;
+ return Ok(None);
+}
+
+fn lookup_online(word: &str) -> Lookup {
+ todo!();
}
// http://norvig.com/spell-correct.html
fn correct(word: &str) -> Option<&str> {
- // todo: implement
- return None;
+ todo!();
}
// now we do somewhat inefficient string manipulation
@@ -92,8 +103,8 @@ fn display(definition: String, state: &State) {
let definition = Configuration::default().parse(&definition);
// this is really quite terrible code
- if !display_ii(&definition, |value| value == &state.lang) {
- display_ii(&definition, |value| true);
+ if !display_language(&definition, &state.lang) {
+ display_language(&definition, "");
}
}
@@ -106,7 +117,8 @@ const skippable_headers: &[&str; 15] =
// no overloading?? O_O
// matching on an enum of structs SUCKS
-fn display_ii<F: Fn(&str) -> bool>(definition: &Output, f: F) -> bool {
+// functions as parameters is too hard
+fn display_language(definition: &Output, lang: &str) -> bool {
let mut inside_heading = false;
let mut correct_language = false;
let mut skipping_heading = false;
@@ -125,7 +137,7 @@ fn display_ii<F: Fn(&str) -> bool>(definition: &Output, f: F) -> bool {
}
print!("\n{}\n", node);
}
- } else if *level == 2 && f(*value) {
+ } else if *level == 2 && *value == lang {
inside_heading = true;
correct_language = true;
print!("{}", node);
@@ -160,16 +172,12 @@ impl State {
}
// mut state: State, yet state: &mut State?? huh??
-pub fn param(word: String, state: &mut State) {
- match word.as_str() { // curious about this
+pub fn handle_parameter(word: &str, state: &mut State) {
+ match word { // todo: extend
"--help" => {
- println!("dictionarium {}", version);
- println!("");
+ println!("dictionarium {}\n", version);
println!("Usage: dictionarium <word>");
},
- "--full" => { // set some global variable
- state.full = true;
- },
_ => {
println!("Unknown flag \"{}\".", word);
}
diff --git a/src/main.rs b/src/main.rs
index a64aec8..e31b384 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6,20 +6,21 @@ fn main() {
let args: Vec<String> = env::args().skip(1).collect();
if args.len() == 0 {
- dictionarium::param(String::from("--help"), &mut state);
- } else {
- let mut words = Vec::<String>::new();
- for word in args {
- if word.len() > 2 && word.get(0..2).unwrap_or_default() == "--" {
- dictionarium::param(word, &mut state);
- } else {
- words.push(word);
- }
- }
+ dictionarium::handle_parameter("--help", &mut state);
+ std::process::exit(0);
+ }
- // we accept multiple words gladly
- for word in words {
- dictionarium::handle(word, &state);
+ let mut words = Vec::<String>::new();
+ for word in args {
+ if word.get(0..2) == Some("--") {
+ dictionarium::handle_parameter(&word, &mut state);
+ } else {
+ words.push(word);
}
}
+
+ // we accept multiple words gladly
+ for word in words {
+ dictionarium::handle_word(word, &state);
+ }
}