summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/animalia.rs55
-rw-r--r--src/main.rs3
2 files changed, 55 insertions, 3 deletions
diff --git a/src/animalia.rs b/src/animalia.rs
index f3b3261..e1ec8eb 100644
--- a/src/animalia.rs
+++ b/src/animalia.rs
@@ -1,9 +1,60 @@
use std::error::Error;
-
+use std::io::{self, prelude::*};
+use std::collections::HashSet;
pub fn main(args: Vec<String>) -> Result<(), Box<dyn Error>> {
if !args.is_empty() {
Err("No arguments expected to 'animalia' command")?;
}
-
+ let defs_path = "en-definitions.txt";
+ let taxa_path = "taxa.txt";
+ let taxa_file = std::fs::File::open(taxa_path)
+ .map_err(|e| format!("couldn't open {taxa_path}: {e}"))?;
+ let mut species: HashSet<String> = HashSet::new();
+ let mut taxa: HashSet<String> = HashSet::new();
+ for line in io::BufReader::new(taxa_file).lines() {
+ let line = line.map_err(|e| format!("couldn't read {taxa_path}: {e}"))?;
+ let line = line.trim_end_matches(['\r', '\n']);
+ if line.contains(' ') {
+ species.insert(line.into());
+ } else {
+ taxa.insert(line.into());
+ }
+ }
+ let definitions = std::fs::File::open(defs_path)
+ .map_err(|e| format!("couldn't open {defs_path}: {e}"))?;
+ let levels: HashSet<&str> = [
+ "kingdom",
+ "phylum",
+ "class",
+ "order",
+ "family",
+ "genus",
+ ].into_iter().collect();
+ let mut animalia = vec![];
+ for line in io::BufReader::new(definitions).lines() {
+ let line = line.map_err(|e| format!("error reading {defs_path}: {e}"))?;
+ let line = line.trim_end_matches(['\r', '\n']);
+ let (word, rest) = line.split_once(" ").expect("bad format for definitions file");
+ let (_class, definition) = rest.split_once(' ').expect("bad format for definitions file");
+// println!("{word} {definition}");
+ let parts: Vec<&str> = definition.split(|c: char| !c.is_alphabetic()).collect();
+ for ws in parts.windows(2) {
+ if species.contains(&format!("{} {}",ws[0],ws[1])) ||
+ // handles {{taxfmt|Felidae|family}} &c.
+ levels.contains(ws[1]) && taxa.contains(ws[0]) {
+ animalia.push(word.to_owned());
+ }
+ }
+ }
+ animalia.sort_unstable();
+ animalia.dedup();
+ let output_path = "animalia.txt";
+ let mut s = String::new();
+ for animal in &animalia {
+ s.push_str(animal);
+ s.push('\n');
+ }
+ std::fs::write(output_path, s)
+ .map_err(|e| format!("couldn't write {output_path}: {e}"))?;
Ok(())
}
diff --git a/src/main.rs b/src/main.rs
index 0fcc3d6..8ca45fb 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -25,7 +25,8 @@ fn try_main() -> Result<(), Box<dyn Error>> {
let mut args = std::env::args_os().skip(1);
let command = args.next();
let no_command = "No command specified. Commands available:
-- definitions";
+- definitions
+- animalia";
let Some(command) = command else {
return Err(no_command.into());
};