From 73f0c112aa351537b3787ecc3d6eba0e061b3144 Mon Sep 17 00:00:00 2001 From: Jean-Pierre De Jesus DIAZ Date: Mon, 13 Mar 2023 11:51:29 +0100 Subject: [PATCH 1/2] Add words and deprecate word_iter method To follow the convention for Rust iterators, for example, in `str` the method for a char iterator is `chars` not `char_iter`. Signed-off-by: Jean-Pierre De Jesus DIAZ --- src/lib.rs | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ae96644..811b274 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -309,12 +309,31 @@ impl Mnemonic { self.lang } - /// Get an iterator over the words. - pub fn word_iter(&self) -> impl Iterator + Clone + '_ { + /// Returns an iterator over the words of the [`Mnemonic`]. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bip39::Mnemonic; + /// + /// let mnemonic = Mnemonic::from_entropy(&[0; 32]).unwrap(); + /// for (i, word) in mnemonic.words().enumerate() { + /// println!("{}. {}", i, word); + /// } + /// ``` + pub fn words(&self) -> impl Iterator + Clone + '_ { let list = self.lang.word_list(); self.words.iter().take_while(|w| **w != EOF).map(move |w| list[*w as usize]) } + /// Returns an iterator over the words of the [`Mnemonic`]. + #[deprecated(note = "Use Mnemonic::words instead")] + pub fn word_iter(&self) -> impl Iterator + Clone + '_ { + self.words() + } + /// Determine the language of the mnemonic as a word iterator. /// See documentation on [Mnemonic::language_of] for more info. fn language_of_iter<'a, W: Iterator>(words: W) -> Result { @@ -505,7 +524,7 @@ impl Mnemonic { let mut seed = [0u8; PBKDF2_BYTES]; pbkdf2::pbkdf2( - self.word_iter(), + self.words(), normalized_passphrase.as_bytes(), PBKDF2_ROUNDS, &mut seed, @@ -531,7 +550,7 @@ impl Mnemonic { // We unwrap errors here because this method can only be called on // values that were already previously validated. - let language = Mnemonic::language_of_iter(self.word_iter()).unwrap(); + let language = Mnemonic::language_of_iter(self.words()).unwrap(); // Preallocate enough space for the longest possible word list let mut entropy = [0; 33]; @@ -540,7 +559,7 @@ impl Mnemonic { let mut remainder = 0; let nb_words = self.word_count(); - for word in self.word_iter() { + for word in self.words() { let idx = language.find_word(word).expect("invalid mnemonic"); remainder |= ((idx as u32) << (32 - 11)) >> offset; @@ -572,7 +591,7 @@ impl Mnemonic { impl fmt::Display for Mnemonic { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for (i, word) in self.word_iter().enumerate() { + for (i, word) in self.words().enumerate() { if i > 0 { f.write_str(" ")?; } @@ -612,7 +631,7 @@ mod tests { fn test_language_of() { for lang in Language::all() { let m = Mnemonic::generate_in(*lang, 24).unwrap(); - assert_eq!(*lang, Mnemonic::language_of_iter(m.word_iter()).unwrap()); + assert_eq!(*lang, Mnemonic::language_of_iter(m.words()).unwrap()); assert_eq!( *lang, Mnemonic::language_of_iter(m.to_string().split_whitespace()).unwrap() From 0b92d8db6ce72d6d94577f0a643464a35d4e02cc Mon Sep 17 00:00:00 2001 From: Jean-Pierre De Jesus DIAZ Date: Mon, 13 Mar 2023 11:56:53 +0100 Subject: [PATCH 2/2] Add iterator over word indices. Signed-off-by: Jean-Pierre De Jesus DIAZ --- src/lib.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 811b274..4f7b915 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -309,7 +309,7 @@ impl Mnemonic { self.lang } - /// Returns an iterator over the words of the [`Mnemonic`]. + /// Returns an iterator over the words of the [Mnemonic]. /// /// # Examples /// @@ -325,15 +325,34 @@ impl Mnemonic { /// ``` pub fn words(&self) -> impl Iterator + Clone + '_ { let list = self.lang.word_list(); - self.words.iter().take_while(|w| **w != EOF).map(move |w| list[*w as usize]) + self.word_indices().map(move |i| list[i]) } - /// Returns an iterator over the words of the [`Mnemonic`]. + /// Returns an iterator over the words of the [Mnemonic]. #[deprecated(note = "Use Mnemonic::words instead")] pub fn word_iter(&self) -> impl Iterator + Clone + '_ { self.words() } + /// Returns an iterator over [Mnemonic] word indices. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use bip39::{Language, Mnemonic}; + /// + /// let list = Language::English.word_list(); + /// let mnemonic = Mnemonic::from_entropy(&[0; 32]).unwrap(); + /// for i in mnemonic.word_indices() { + /// println!("{} ({})", list[i], i); + /// } + /// ``` + pub fn word_indices(&self) -> impl Iterator + Clone + '_ { + self.words.iter().take_while(|&&w| w != EOF).map(|w| *w as usize) + } + /// Determine the language of the mnemonic as a word iterator. /// See documentation on [Mnemonic::language_of] for more info. fn language_of_iter<'a, W: Iterator>(words: W) -> Result { @@ -514,7 +533,7 @@ impl Mnemonic { /// Get the number of words in the mnemonic. pub fn word_count(&self) -> usize { - self.words.iter().take_while(|w| **w != EOF).count() + self.word_indices().count() } /// Convert to seed bytes with a passphrase in normalized UTF8.