mvp
This commit is contained in:
39
src/main.rs
Normal file
39
src/main.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
use inline_colorization::*;
|
||||
use std::{env, io::{self, Write}};
|
||||
|
||||
mod strong;
|
||||
|
||||
fn main() {
|
||||
|
||||
let arg = env::args().collect::<Vec<String>>();
|
||||
if let Some(query) = arg.get(1) {
|
||||
if query.starts_with("H") | query.starts_with("h") {
|
||||
if let Some(found) = strong::get(query) {
|
||||
print!("{found}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No input args, go into interactive mode
|
||||
let stdin = io::stdin();
|
||||
let mut stdout = io::stdout();
|
||||
loop {
|
||||
print!("{color_bright_white}{style_bold}Search>{style_reset} ");
|
||||
let _ = stdout.flush();
|
||||
|
||||
let mut buf = String::new();
|
||||
stdin.read_line(&mut buf).unwrap();
|
||||
let search = buf.trim().to_string();
|
||||
|
||||
if search.starts_with("H") {
|
||||
if let Some(entry) = strong::get(&search) {
|
||||
println!("");
|
||||
print!("{}", entry);
|
||||
println!("");
|
||||
}
|
||||
} else {
|
||||
println!("Not sure what you're looking for...");
|
||||
}
|
||||
}
|
||||
}
|
200
src/strong.rs
Normal file
200
src/strong.rs
Normal file
@@ -0,0 +1,200 @@
|
||||
use std::{fmt::Display, fs::read_to_string};
|
||||
use inline_colorization::*;
|
||||
|
||||
use quick_xml::de::from_str;
|
||||
use serde::Deserialize;
|
||||
|
||||
pub fn get(query: &str) -> Option<Entry> {
|
||||
// TODO Put this in a singleton
|
||||
let file = read_to_string("./HebrewLexicon/HebrewStrong.xml").unwrap();
|
||||
let obj: HebrewStrong = from_str(&file).unwrap();
|
||||
|
||||
// Yes, dumb search is ok. Searching for the last element took 2ms
|
||||
obj.entries.into_iter().find(|entry| entry.number.eq(&query))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct HebrewStrong {
|
||||
#[serde(rename = "$value")]
|
||||
pub entries: Vec<Entry>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct Entry {
|
||||
#[serde(rename = "@id")]
|
||||
pub number: String,
|
||||
w: Word,
|
||||
// TODO find who has multiple notes
|
||||
note: Option<Vec<Note>>,
|
||||
source: Option<Source>,
|
||||
meaning: Option<Meaning>,
|
||||
usage: Option<Usage>,
|
||||
}
|
||||
impl Display for Entry {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
writeln!(f, "{color_red}Strong's ID{style_reset}: {}", self.number)?;
|
||||
|
||||
if let Some(notes) = &self.note {
|
||||
write!(f, "Notes:")?;
|
||||
for note in notes {
|
||||
writeln!(f, "{}", note)?;
|
||||
}
|
||||
}
|
||||
|
||||
write!(f, "{}", self.w)?;
|
||||
|
||||
if let Some(i) = &self.source {
|
||||
writeln!(f, "{}", i)?;
|
||||
}
|
||||
|
||||
if let Some(i) = &self.meaning {
|
||||
writeln!(f, "{}", i)?;
|
||||
}
|
||||
|
||||
if let Some(i) = &self.usage {
|
||||
writeln!(f, "{}", i)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Word {
|
||||
#[serde(rename = "@pos")]
|
||||
// TODO this is actaully a link to PartsOfSpeech.xml
|
||||
part_of_speech: Option<String>,
|
||||
|
||||
#[serde(rename = "@pron")]
|
||||
pronunciation: Option<String>,
|
||||
|
||||
#[serde(rename = "@xlit")]
|
||||
transliteration: Option<String>,
|
||||
|
||||
#[serde(rename = "@xlm:lang")]
|
||||
lang: Option<String>,
|
||||
|
||||
#[serde(rename = "$value")]
|
||||
inner: String,
|
||||
|
||||
#[serde(rename = "@src")]
|
||||
links_to: Option<String>,
|
||||
}
|
||||
impl Display for Word {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if let Some(part_of_speech) = &self.part_of_speech {
|
||||
writeln!(f, "{color_magenta}Part of speech{style_reset}: {}", part_of_speech)?;
|
||||
}
|
||||
|
||||
if let Some(i) = &self.transliteration {
|
||||
writeln!(f, "{color_green}Transliteration{style_reset}: {}", i)?;
|
||||
}
|
||||
|
||||
if let Some(i) = &self.lang {
|
||||
writeln!(f, "{color_red}Language{style_reset}: {}", i)?;
|
||||
}
|
||||
|
||||
writeln!(f, "{color_bright_cyan}Writen{style_reset}: {}", self.inner)?;
|
||||
|
||||
if let Some(pron) = &self.pronunciation {
|
||||
writeln!(f, "{color_yellow}Pronounciation{style_reset}: {}", pron)?;
|
||||
}
|
||||
|
||||
if let Some(i) = &self.links_to {
|
||||
writeln!(f, "{color_bright_green}Also see{style_reset}: {}", i)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Note {
|
||||
#[serde(rename = "$value")]
|
||||
inner: String,
|
||||
}
|
||||
impl Display for Note {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.inner)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Source {
|
||||
#[serde(rename = "$value")]
|
||||
// Text vs Words make this a vec
|
||||
inner: Option<Vec<MixedText>>,
|
||||
}
|
||||
impl Display for Source {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
if let Some(inner) = &self.inner {
|
||||
// WE ARE LOOPING
|
||||
// !! Don't use writeln
|
||||
write!(f, "{color_bright_green}Source{style_reset}: ")?;
|
||||
for i in inner {
|
||||
match i {
|
||||
MixedText::Word(word) => {
|
||||
if let Some(i) = &word.links_to {
|
||||
write!(f, "{style_bold} (See: {}){style_reset}", i)?;
|
||||
}
|
||||
write!(f, "{color_bright_white} {} {style_reset}", word.inner)?;
|
||||
},
|
||||
_ => write!(f, "{}", i)?,
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Meaning {
|
||||
#[serde(rename = "$value")]
|
||||
inner: Vec<MixedText>,
|
||||
}
|
||||
impl Display for Meaning {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{color_cyan}Meaning:{style_reset}")?;
|
||||
for i in &self.inner {
|
||||
write!(f, "{}", i)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
struct Usage {
|
||||
#[serde(rename = "$value")]
|
||||
inner: Vec<String>,
|
||||
}
|
||||
impl Display for Usage {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let new = self.inner.join(" ");
|
||||
write!(f, "{color_bright_magenta}Usage{style_reset}: {new}")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
enum MixedText {
|
||||
#[serde(rename = "w")]
|
||||
Word(Word),
|
||||
#[serde(rename = "$text")]
|
||||
Text(String),
|
||||
#[serde(rename = "def")]
|
||||
/// The actual definition, as opposed to the supporting `MixedText::Text`, which is just
|
||||
/// supporting text elements.
|
||||
Definition(String),
|
||||
#[serde(rename = "note")]
|
||||
Note(Note),
|
||||
}
|
||||
impl Display for MixedText {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
MixedText::Word(word) => write!(f, "{}", word),
|
||||
MixedText::Text(text) => write!(f, "{}", text),
|
||||
MixedText::Definition(def) => write!(f, " {style_bold}{}{style_reset} ", def),
|
||||
MixedText::Note(note) => write!(f, "{}", note),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user