commit 3b3649c7c38e680335af1f3f190bbdd309701b3f
parent 5e124728c690569cf45213179d8cdf6a29dd9890
Author: Yuval Langer <yuval.langer@gmail.com>
Date: Mon, 4 Nov 2024 19:58:06 +0200
Add generic type definitions and a test.
Diffstat:
M | src/main.rs | | | 43 | ++++++++++++++++++++++--------------------- |
1 file changed, 22 insertions(+), 21 deletions(-)
diff --git a/src/main.rs b/src/main.rs
@@ -27,7 +27,6 @@ use std::str::FromStr;
use diceware_wordlists::Wordlist;
use getopts::Options;
-// use rand::prelude::SliceRandom;
use rand::rngs::ThreadRng;
use rand::thread_rng;
use crate::rand::Rng;
@@ -79,12 +78,10 @@ fn print_words(
println!();
}
-fn read_single_word(bytes_iter: &mut std::iter::Peekable<std::io::Bytes<std::io::Stdin>>, wordlist: &Vec<&str>) -> Option<String> {
- eprintln!("##### wordlist length: {}", wordlist.len());
+fn read_single_word<T: std::iter::Iterator<Item = Result<u8, std::io::Error>>, U: std::fmt::Display + ?Sized>(bytes_iter: &mut std::iter::Peekable<T>, wordlist: &Vec<&str>) -> Result<String, Error> {
let die_cast_per_word = die_cast_per_word(wordlist.len());
- eprintln!("##### die cast per word: {}", die_cast_per_word);
let mut word_index = 0;
-
+
for die_significance in 0..=die_cast_per_word {
if die_significance == die_cast_per_word {
let current_byte_result = match bytes_iter.next() {
@@ -118,7 +115,6 @@ fn read_single_word(bytes_iter: &mut std::iter::Peekable<std::io::Bytes<std::io:
} else {
let current_byte_result = match bytes_iter.next() {
Some(x) => {
- eprintln!("##### {:?}", x);
x
},
None => {
@@ -151,17 +147,17 @@ fn read_single_word(bytes_iter: &mut std::iter::Peekable<std::io::Bytes<std::io:
};
};
};
-
+
return Some(wordlist[word_index].to_string());
}
-fn read_words_from_rolls(wordlist: &Vec<&str>) -> Vec<String> {
+fn read_words_from_rolls<U: std::fmt::Display + ?Sized>(wordlist: &Vec<&str>) -> Vec<String> {
let stdin = std::io::stdin();
let mut words: Vec<String> = Vec::new();
let mut bytes_iter = stdin.bytes().peekable();
loop {
- match read_single_word(&mut bytes_iter, wordlist) {
+ match read_single_word::<std::io::Bytes<std::io::Stdin>, U>(&mut bytes_iter, wordlist) {
Some(word) => words.push(word),
None => break,
};
@@ -188,23 +184,18 @@ fn read_rng_rolls(
wordlist: &Vec<&str>,
word_num: u64,
) -> Vec<String> {
- let die_cast_per_word = die_cast_per_word(wordlist.len());
-
/*
From base 6 conversion:
(0..6).pow(1) = (0, 1, ..6)
(0..6).pow(2) = (0, 6, ..36)
(0..6).pow(3) = (0, 36, ..216)
*/
+
return (0..word_num)
.collect::<Vec<_>>()
- .iter().map(|_| {
- let current_word_index: usize = (0..die_cast_per_word).collect::<Vec<_>>()
- .into_iter()
- .map(|die_significance| (rng.gen_range(0..6_usize)) * ((6_usize).pow(die_significance)))
- .sum();
- wordlist[current_word_index].to_string()
- }).collect();
+ .iter()
+ .map(|_| wordlist[rng.gen_range(0..wordlist.len())].to_string())
+ .collect();
}
fn load_wordlist_file(filepath: &str) -> String {
@@ -265,7 +256,7 @@ fn main() {
};
let wordlist_string;
-
+
let wordlist = if let Some(wordlist_filepath) = matches.opt_str("f") {
wordlist_string = load_wordlist_file(&wordlist_filepath);
wordlist_string
@@ -278,7 +269,7 @@ fn main() {
};
let words = if is_physical_rolls {
- read_words_from_rolls(&wordlist)
+ read_words_from_rolls::<dyn std::fmt::Display>(&wordlist)
} else if word_num != 0 {
let mut rng = thread_rng();
read_rng_rolls(&mut rng, &wordlist, word_num)
@@ -290,7 +281,7 @@ fn main() {
if words.len() > 0 {
print_words(&words, delimiter);
}
-
+
if is_entropy_printed {
println!("{}", entropyn(wordlist, words.len() as u64));
}
@@ -300,9 +291,19 @@ fn main() {
mod tests {
use super::*;
+ /*
#[test]
fn test_rolls_to_word_index_01() {
assert_eq!(0, rolls_to_word_index(3, &[1, 1, 1]));
assert_eq!(1, rolls_to_word_index(3, &[1, 1, 2]));
}
+ */
+
+ #[test]
+ fn test_read_single_word() {
+ let wordlist = Wordlist::default().get_list().to_vec();
+ let input = &b"11111\n"[..];
+ let mut reader = std::io::BufReader::with_capacity(input.len(), input).bytes().peekable();
+ assert_eq!("abacus", read_single_word::<std::io::Bytes<std::io::BufReader<&[u8]>>, u8>(&mut reader, &wordlist).unwrap());
+ }
}