Only load the radkfile once per execution.
Before this, Yakudatsu would load and parse the whole file everytime you used the kanji search.
This commit is contained in:
parent
0070579f79
commit
a475790e63
2 changed files with 89 additions and 76 deletions
|
@ -1,26 +1,23 @@
|
||||||
use std::{
|
use std::{
|
||||||
io::{stdin, stdout, Write},
|
io::{stdin, stdout, Write},
|
||||||
path::PathBuf,
|
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
};
|
};
|
||||||
|
|
||||||
use colored::*;
|
use colored::*;
|
||||||
use kradical_parsing::radk;
|
use kradical_parsing::radk;
|
||||||
|
|
||||||
pub fn search_by_radical(query: &mut String) -> Option<()> {
|
pub fn search_by_radical(query: &mut String, radk_list: &[radk::Membership]) -> Option<()> {
|
||||||
let mut result: HashSet<_> = HashSet::new();
|
let mut result: HashSet<_> = HashSet::new();
|
||||||
let mut aux: HashSet<_> = HashSet::new();
|
let mut aux: HashSet<_> = HashSet::new();
|
||||||
let path = get_radkfile_path();
|
|
||||||
|
|
||||||
match radk::parse_file(path.unwrap()) { /* if path doesn't exist, just panic */
|
if !radk_list.is_empty() {
|
||||||
Ok(radk_list) => {
|
|
||||||
result.clear();
|
result.clear();
|
||||||
|
|
||||||
/* First iteration: get the baseline for the results */
|
/* First iteration: get the baseline for the results */
|
||||||
let mut rad = query.chars().nth(1).unwrap();
|
let mut rad = query.chars().nth(1).unwrap();
|
||||||
if rad == '*' || rad == '*' {
|
if rad == '*' || rad == '*' {
|
||||||
/* if search_by_strokes failed, then something is very wrong */
|
/* if search_by_strokes failed, then something is very wrong */
|
||||||
rad = search_by_strokes(query, &radk_list, 1)?;
|
rad = search_by_strokes(query, radk_list, 1)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for k in radk_list.iter() {
|
for k in radk_list.iter() {
|
||||||
|
@ -36,7 +33,7 @@ pub fn search_by_radical(query: &mut String) -> Option<()> {
|
||||||
for (i, mut rad) in query.clone().chars().skip(2).enumerate() {
|
for (i, mut rad) in query.clone().chars().skip(2).enumerate() {
|
||||||
if rad == '*' || rad == '*' {
|
if rad == '*' || rad == '*' {
|
||||||
/* if search_by_strokes failed, then something is very wrong */
|
/* if search_by_strokes failed, then something is very wrong */
|
||||||
rad = search_by_strokes(query, &radk_list, i+2)?;
|
rad = search_by_strokes(query, radk_list, i+2)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for k in radk_list.iter() {
|
for k in radk_list.iter() {
|
||||||
|
@ -54,10 +51,10 @@ pub fn search_by_radical(query: &mut String) -> Option<()> {
|
||||||
print!("{r} ");
|
print!("{r} ");
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
}
|
} else {
|
||||||
Err(_e) => eprintln!("Error while reading radkfile\nIf you don't have the radkfile, download it from\n\
|
eprintln!("Error while reading radkfile\nIf you don't have the radkfile, download it from\n\
|
||||||
https://www.edrdg.org/krad/kradinf.html and place it in \"~/.local/share/\" on Linux or \"~\\AppData\\Local\\\" on Windows.\n\
|
https://www.edrdg.org/krad/kradinf.html and place it in \"~/.local/share/\" on Linux or \"~\\AppData\\Local\\\" on Windows.\n\
|
||||||
This file is needed to search radicals by strokes."),
|
This file is needed to search radicals by strokes.");
|
||||||
}
|
}
|
||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
@ -121,43 +118,3 @@ fn search_by_strokes(query: &mut String, radk_list: &[radk::Membership], n: usiz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(unix)]
|
|
||||||
fn get_radkfile_path() -> Option<PathBuf> {
|
|
||||||
#[allow(deprecated)] /* obviously no windows problem here */
|
|
||||||
std::env::home_dir()
|
|
||||||
.map(|path| path.join(".local/share/radkfile"))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
/* Nicked this section straight from https://github.com/rust-lang/cargo/blob/master/crates/home/src/windows.rs */
|
|
||||||
extern "C" {
|
|
||||||
fn wcslen(buf: *const u16) -> usize;
|
|
||||||
}
|
|
||||||
#[cfg(windows)]
|
|
||||||
fn get_radkfile_path() -> Option<PathBuf> {
|
|
||||||
use std::ffi::OsString;
|
|
||||||
use std::os::windows::ffi::OsStringExt;
|
|
||||||
use windows_sys::Win32::Foundation::{MAX_PATH, S_OK};
|
|
||||||
use windows_sys::Win32::UI::Shell::{SHGetFolderPathW, CSIDL_PROFILE};
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
match env::var_os("USERPROFILE").filter(|s| !s.is_empty()).map(PathBuf::from) {
|
|
||||||
Some(path) => {
|
|
||||||
Some(path.join("Appdata\\Local\\radkfile"))
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
unsafe {
|
|
||||||
let mut path: Vec<u16> = Vec::with_capacity(MAX_PATH as usize);
|
|
||||||
match SHGetFolderPathW(0, CSIDL_PROFILE as i32, 0, 0, path.as_mut_ptr()) {
|
|
||||||
S_OK => {
|
|
||||||
let len = wcslen(path.as_ptr());
|
|
||||||
path.set_len(len);
|
|
||||||
let s = OsString::from_wide(&path);
|
|
||||||
Some(PathBuf::from(s).join("Appdata\\Local\\radkfile"))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
58
src/main.rs
58
src/main.rs
|
@ -4,6 +4,7 @@ mod sentence_search;
|
||||||
mod util;
|
mod util;
|
||||||
use std::{
|
use std::{
|
||||||
io::{stdin, stdout, Write},
|
io::{stdin, stdout, Write},
|
||||||
|
path::PathBuf,
|
||||||
process::{Command, Stdio},
|
process::{Command, Stdio},
|
||||||
env,
|
env,
|
||||||
};
|
};
|
||||||
|
@ -16,6 +17,7 @@ use sentence_search::sentence_search;
|
||||||
use argparse::{ArgumentParser, List, Print, Store, StoreTrue};
|
use argparse::{ArgumentParser, List, Print, Store, StoreTrue};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use atty::Stream;
|
use atty::Stream;
|
||||||
|
use kradical_parsing::radk;
|
||||||
|
|
||||||
macro_rules! JISHO_URL {
|
macro_rules! JISHO_URL {
|
||||||
() => {
|
() => {
|
||||||
|
@ -39,6 +41,11 @@ fn main() -> Result<(), ureq::Error> {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let path = get_radkfile_path().unwrap();
|
||||||
|
let mut radk_list = Vec::new();
|
||||||
|
let mut try_load = true;
|
||||||
|
|
||||||
|
|
||||||
let options = parse_args();
|
let options = parse_args();
|
||||||
|
|
||||||
let mut output = String::with_capacity(51200); /* Give output 50KiB of buffer; Should be enough to avoid reallocs*/
|
let mut output = String::with_capacity(51200); /* Give output 50KiB of buffer; Should be enough to avoid reallocs*/
|
||||||
|
@ -64,8 +71,16 @@ fn main() -> Result<(), ureq::Error> {
|
||||||
output.clear();
|
output.clear();
|
||||||
|
|
||||||
if query.starts_with(':') || query.starts_with(':') { /* Kanji search */
|
if query.starts_with(':') || query.starts_with(':') { /* Kanji search */
|
||||||
|
if try_load == true {
|
||||||
|
radk_list = { match radk::parse_file(&path) {
|
||||||
|
Ok(radk_list) => radk_list,
|
||||||
|
Err(_e) => radk_list,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try_load = false;
|
||||||
|
}
|
||||||
/* if search_by_radical failed, then something is very wrong */
|
/* if search_by_radical failed, then something is very wrong */
|
||||||
if search_by_radical(&mut query).is_none() {
|
if search_by_radical(&mut query, &radk_list).is_none() {
|
||||||
eprintln!("Couldn't parse input");
|
eprintln!("Couldn't parse input");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,3 +248,44 @@ fn terminal_size() -> Result<usize, i16> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn get_radkfile_path() -> Option<PathBuf> {
|
||||||
|
#[allow(deprecated)] /* obviously no windows problem here */
|
||||||
|
std::env::home_dir()
|
||||||
|
.map(|path| path.join(".local/share/radkfile"))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
/* Nicked this section straight from https://github.com/rust-lang/cargo/blob/master/crates/home/src/windows.rs */
|
||||||
|
extern "C" {
|
||||||
|
fn wcslen(buf: *const u16) -> usize;
|
||||||
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn get_radkfile_path() -> Option<PathBuf> {
|
||||||
|
use std::ffi::OsString;
|
||||||
|
use std::os::windows::ffi::OsStringExt;
|
||||||
|
use windows_sys::Win32::Foundation::{MAX_PATH, S_OK};
|
||||||
|
use windows_sys::Win32::UI::Shell::{SHGetFolderPathW, CSIDL_PROFILE};
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
match env::var_os("USERPROFILE").filter(|s| !s.is_empty()).map(PathBuf::from) {
|
||||||
|
Some(path) => {
|
||||||
|
Some(path.join("Appdata\\Local\\radkfile"))
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
unsafe {
|
||||||
|
let mut path: Vec<u16> = Vec::with_capacity(MAX_PATH as usize);
|
||||||
|
match SHGetFolderPathW(0, CSIDL_PROFILE as i32, 0, 0, path.as_mut_ptr()) {
|
||||||
|
S_OK => {
|
||||||
|
let len = wcslen(path.as_ptr());
|
||||||
|
path.set_len(len);
|
||||||
|
let s = OsString::from_wide(&path);
|
||||||
|
Some(PathBuf::from(s).join("Appdata\\Local\\radkfile"))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue