commit a0e2eb496e425865322875462c4cd8be5b31c0c5
parent fc7ec7a5988530b59b03d018cd2761612d651c47
Author: Yuval Langer <yuval.langer@gmail.com>
Date: Wed, 6 Nov 2024 17:45:47 +0200
Fix significance order and some typing. Add comments.
Diffstat:
M | Cargo.lock | | | 70 | ++++++++++++++++++++++++++++++++++++++++++++++++++-------------------- |
M | src/main.rs | | | 119 | ++++++++++++++++++++++++++++++++++++++++++++++--------------------------------- |
2 files changed, 119 insertions(+), 70 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -3,6 +3,12 @@
version = 3
[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -36,9 +42,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.8"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
+checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
@@ -47,30 +53,33 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.137"
+version = "0.2.161"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
+checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
[[package]]
name = "ppv-lite86"
-version = "0.2.16"
+version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
+checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
+dependencies = [
+ "zerocopy",
+]
[[package]]
name = "proc-macro2"
-version = "1.0.47"
+version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
+checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.21"
+version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
dependencies = [
"proc-macro2",
]
@@ -107,18 +116,18 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.147"
+version = "1.0.214"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
+checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.147"
+version = "1.0.214"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
+checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
dependencies = [
"proc-macro2",
"quote",
@@ -127,9 +136,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.103"
+version = "2.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
+checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
dependencies = [
"proc-macro2",
"quote",
@@ -138,18 +147,39 @@ dependencies = [
[[package]]
name = "unicode-ident"
-version = "1.0.5"
+version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "unicode-width"
-version = "0.1.10"
+version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "zerocopy"
+version = "0.7.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
+dependencies = [
+ "byteorder",
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.7.35"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/src/main.rs b/src/main.rs
@@ -78,37 +78,50 @@ fn print_words(
println!();
}
-struct ReadWords<'a, T: std::iter::Iterator> {
- bytes_iter: &'a mut std::iter::Peekable<T>,
- wordlist: &'a Vec<&'a str>
-}
-
-impl<'a, T: std::iter::Iterator> ReadWords<'a, T> {
- fn new(
- bytes_iter: &'a mut std::iter::Peekable<T>,
- wordlist: &'a Vec<&'a str>
- ) -> ReadWords<'a, T> {
- ReadWords {
- bytes_iter,
- wordlist,
- }
- }
-}
-
-impl<'a, T: std::iter::Iterator<Item = Result<u8, std::io::Error>> + std::fmt::Display> Iterator for ReadWords<'a, T> {
- type Item = String;
-
- fn next(&mut self) -> Option<<Self as Iterator>::Item> {
- return read_single_word::<T, T>(self.bytes_iter, self.wordlist);
- }
-}
-
-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>) -> Option<String> {
+// struct ReadWords<'a, T: std::iter::Iterator> {
+// bytes_iter: &'a mut std::io::Bytes<T>,
+// wordlist: &'a Vec<&'a str>
+// }
+
+// impl<'a, T: std::iter::Iterator> ReadWords<'a, T> {
+// fn new(
+// bytes_iter: &'a mut std::io::Bytes<T>,
+// wordlist: &'a Vec<&'a str>
+// ) -> ReadWords<'a, T> {
+// ReadWords {
+// bytes_iter,
+// wordlist,
+// }
+// }
+// }
+
+// impl<'a, T: std::iter::Iterator<Item = Result<u8, std::io::Error>> + std::fmt::Display + std::io::Read> Iterator for ReadWords<'a, T> {
+// type Item = String;
+
+// fn next(&mut self) -> Option<<Self as Iterator>::Item> {
+// return read_single_word::<T, T>(self.bytes_iter, self.wordlist);
+// }
+// }
+
+fn read_single_word<T>(
+ bytes_iter: &mut std::io::Bytes<T>,
+ wordlist: &Vec<&str>,
+) -> Option<String> where T: std::io::Read {
let die_cast_per_word = die_cast_per_word(wordlist.len());
let mut word_index = 0;
- for die_significance in 0..=die_cast_per_word {
- if die_significance == die_cast_per_word {
+ for die_index in 0..=die_cast_per_word {
+ // for die_cast_per_word == 5 we have:
+ //
+ // die_significance = die_cast_per_word - die_index
+ // 5 = 5 - 0 : just starting, may be an EOF, so next() == None and we then return None
+ // 4 = 5 - 1 .
+ // 3 = 5 - 2 .
+ // 2 = 5 - 3 .
+ // 1 = 5 - 4 .
+ // 0 = 5 - 5 : should be an end of line byte.
+
+ if die_index == die_cast_per_word {
let current_byte_result = match bytes_iter.next() {
Some(x) => x,
None => {
@@ -138,26 +151,27 @@ fn read_single_word<T: std::iter::Iterator<Item = Result<u8, std::io::Error>>, U
}
};
} else {
- if die_significance == 0 {
- match bytes_iter.peek() {
- None => return None,
- Some(_) => {},
- }
- }
let current_byte_result = match bytes_iter.next() {
Some(x) => {
x
},
None => {
- eprintln!("Bad number of rolls. Each word must have exactly {} die rolls.",
- die_cast_per_word);
- exit(-1);
+ if die_index == 0 {
+ // We are at a legal EOF state, right before a single word die casting sequence.
+ return None;
+ } else {
+ // We are in the middle of die casting and somehow stdin ended.
+ eprintln!("Bad number of rolls. Each word must have exactly {} die rolls.",
+ die_cast_per_word);
+ exit(-1);
+ }
},
};
+ let die_significance = die_cast_per_word - die_index - 1;
word_index += match current_byte_result {
- Ok(b'1') => 0 * 6_usize.pow(die_significance),
- Ok(b'2') => 1 * 6_usize.pow(die_significance),
+ Ok(b'1') => 0,
+ Ok(b'2') => 6_usize.pow(die_significance),
Ok(b'3') => 2 * 6_usize.pow(die_significance),
Ok(b'4') => 3 * 6_usize.pow(die_significance),
Ok(b'5') => 4 * 6_usize.pow(die_significance),
@@ -182,21 +196,18 @@ fn read_single_word<T: std::iter::Iterator<Item = Result<u8, std::io::Error>>, U
return Some(wordlist[word_index].to_string());
}
-fn read_words_from_rolls<U: std::fmt::Display + ?Sized>(wordlist: &Vec<&str>) -> Vec<String> {
+fn read_words_from_rolls(
+ wordlist: &Vec<&str>,
+) -> Vec<String> {
let stdin = std::io::stdin();
let mut words = Vec::new();
- let mut bytes_iter = stdin.bytes().peekable();
+ let mut bytes_iter = stdin.bytes();
loop {
- match read_single_word::<std::io::Bytes<std::io::Stdin>, U>(&mut bytes_iter, wordlist) {
+ match read_single_word(&mut bytes_iter, wordlist) {
Some(word) => words.push(word),
None => break,
};
-
- match bytes_iter.peek() {
- None => break,
- Some(_) => continue,
- }
};
// TODO: Maybe use an iterator?
@@ -305,7 +316,7 @@ fn main() {
};
let words = if is_physical_rolls {
- read_words_from_rolls::<dyn std::fmt::Display>(&wordlist)
+ read_words_from_rolls(&wordlist)
} else if word_num != 0 {
let mut rng = thread_rng();
read_rng_rolls(&mut rng, &wordlist, word_num)
@@ -331,7 +342,15 @@ mod tests {
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());
+ let mut reader = std::io::BufReader::with_capacity(input.len(), input).bytes();
+ assert_eq!("abacus", read_single_word(&mut reader, &wordlist).unwrap());
}
+
+ // #[test]
+ // fn test_read_words_from_rolls() {
+ // let wordlist = Wordlist::default().get_list().to_vec();
+ // let input = &b"11111\n11111\n"[..];
+ // let mut reader = std::io::BufReader::with_capacity(input.len(), input).bytes();
+ // assert_eq!("abacus", read_words_from_rolls::<std::io::Bytes<std::io::BufReader<&[u8]>>, u8>(reader, &wordlist).unwrap());
+ // }
}