feat(german): allow loading any wordlist file, bundle english and german
cargo devel CI / cargo CI (push) Successful in 1m56s Details

This commit is contained in:
Christoph J. Scherr 2024-07-25 17:02:09 +02:00
parent d651756265
commit 9ea3577a3b
2 changed files with 71 additions and 4 deletions

View File

@ -13,6 +13,11 @@ pub enum Error {
#[from] #[from]
source: GameError, source: GameError,
}, },
#[error("Wordlist Error")]
WordlistError {
#[from]
source: WordlistError,
},
#[error("Solver Error")] #[error("Solver Error")]
SolverError { SolverError {
#[from] #[from]
@ -68,3 +73,17 @@ pub enum SolverError {
#[error("Wordlist has no matches for the gamestate")] #[error("Wordlist has no matches for the gamestate")]
NoMatches, NoMatches,
} }
#[derive(Debug, Error)]
pub enum WordlistError {
#[error("Wordlist has no matches for the gamestate")]
BadFormat {
#[from]
source: serde_json::Error,
},
#[error("I/O error (probably filesystem related)")]
IO {
#[from]
source: std::io::Error,
},
}

View File

@ -1,16 +1,66 @@
use std::fmt::{write, Debug, Display}; use std::fmt::{write, Debug, Display};
use std::path::{Path, PathBuf};
use serde_json; use serde_json;
use crate::error::{WResult, WordlistError};
use super::{Word, WordList}; use super::{Word, WordList};
const RAW_WORDLIST_FILE: &str = include_str!("../../data/wordlists/en_US_3b1b_freq_map.json"); pub const RAW_WORDLIST_BUNDLED_ENGLISH: &str =
include_str!("../../data/wordlists/en_US_3b1b_freq_map.json");
pub const RAW_WORDLIST_BUNDLED_GERMAN_SMALL: &str =
include_str!("../../data/wordlists/german_SUBTLEX-DE_small.json");
pub const RAW_WORDLIST_PATH_ENGLISH: &str = "../../data/wordlists/en_US_3b1b_freq_map.json";
pub const RAW_WORDLIST_PATH_GERMAN_FULL: &str = "../../data/wordlists/german_SUBTLEX-DE_full.json";
pub const RAW_WORDLIST_PATH_GERMAN_SMALL: &str = "../../data/wordlists/german_SUBTLEX-DE_full.json";
#[derive(Clone)] #[derive(Clone)]
pub struct BuiltinWList { pub struct BuiltinWList {
words: super::WordMap, words: super::WordMap,
} }
impl BuiltinWList {
/// load a wordlist from file
///
/// Wordlist files are expected to have the following format:
///
/// ```json
/// {
/// "word": 0.001
/// }
/// ```
///
/// Where the number is the frequency. Higher/Lower case is ignored.
///
/// ## Errors
///
/// Will fail if the file path cannot be read or the format is wrong.
pub fn load<P: AsRef<std::path::Path>>(wl_path: P) -> Result<Self, WordlistError> {
let path: &Path = wl_path.as_ref();
let file = std::fs::File::open(path)?;
// don't load the whole string into memory
let reader = std::io::BufReader::new(file);
let words: super::WordMap = serde_json::from_reader(reader)?;
Ok(Self { words })
}
pub fn english() -> Self {
let words: super::WordMap = serde_json::from_str(RAW_WORDLIST_BUNDLED_ENGLISH).unwrap();
Self { words }
}
pub fn german() -> Self {
let words: super::WordMap =
serde_json::from_str(RAW_WORDLIST_BUNDLED_GERMAN_SMALL).unwrap();
Self { words }
}
}
impl super::WordList for BuiltinWList { impl super::WordList for BuiltinWList {
fn length_range(&self) -> impl std::ops::RangeBounds<usize> { fn length_range(&self) -> impl std::ops::RangeBounds<usize> {
5..5 5..5
@ -25,9 +75,7 @@ impl super::WordList for BuiltinWList {
impl Default for BuiltinWList { impl Default for BuiltinWList {
fn default() -> Self { fn default() -> Self {
let words: super::WordMap = serde_json::from_str(RAW_WORDLIST_FILE).unwrap(); Self::english()
Self { words }
} }
} }