Skip to content

Commit

Permalink
alloc feature added for unicode_normalization
Browse files Browse the repository at this point in the history
This commit introduces the `alloc` feature. It is enabled by default by `std`.

The alloc is intended to use in no-std environments which are allowed to
use alloc. New feature enables:

- the unicode-normalization, and all related methods (parse_in,normalize_utf8_cow,parse,to_seed)
- to_entropy() method as Vec is available in alloc,
  • Loading branch information
michalkucharczyk committed Nov 15, 2023
1 parent c208e2e commit c62f91b
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 15 deletions.
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ edition = "2018"

[features]
default = [ "std" ]
std = [ "unicode-normalization", "serde/std" ]
std = [ "serde/std", "unicode-normalization/std" ]
rand = [ "crate_rand", "rand_core" ]
alloc = [ "unicode-normalization" ]

# Note: English is the standard for bip39 so always included
chinese-simplified = []
Expand Down Expand Up @@ -49,7 +50,7 @@ zeroize = { version = "1.5", features = ["zeroize_derive"], optional = true }

# Unexported dependnecies
bitcoin_hashes = { version = "0.11.0", default-features = false }
unicode-normalization = { version = "=0.1.22", optional = true }
unicode-normalization = { version = "=0.1.22", default-features = false, optional = true }

[dev-dependencies]
# Enabling the "rand" feature by default to run the benches
Expand Down
28 changes: 15 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ extern crate alloc;

extern crate bitcoin_hashes;

#[cfg(feature = "std")]
#[cfg(feature = "unicode-normalization")]
extern crate unicode_normalization;

#[cfg(feature = "rand")]
Expand All @@ -43,16 +43,18 @@ pub extern crate rand_core;
#[cfg(feature = "serde")]
pub extern crate serde;

#[cfg(all(feature = "alloc"))]
use alloc::{borrow::Cow, string::ToString, vec::Vec};
use core::{fmt, str};
#[cfg(all(feature = "std", not(feature = "alloc")))]
use std::{borrow::Cow, string::ToString, vec::Vec};

#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(feature = "std")]
use std::error;

use bitcoin_hashes::{sha256, Hash};

#[cfg(feature = "std")]
#[cfg(feature = "unicode-normalization")]
use unicode_normalization::UnicodeNormalization;

#[cfg(feature = "zeroize")]
Expand Down Expand Up @@ -95,7 +97,7 @@ impl AmbiguousLanguages {
}

/// Returns a vector of the possible languages.
#[cfg(feature = "std")]
#[cfg(any(feature = "alloc", feature = "std"))]
pub fn to_vec(&self) -> Vec<Language> {
self.iter().collect()
}
Expand Down Expand Up @@ -183,7 +185,7 @@ impl Mnemonic {
/// Performing this on a [Cow] means that all allocations for normalization
/// can be avoided for languages without special UTF8 characters.
#[inline]
#[cfg(feature = "std")]
#[cfg(feature = "unicode-normalization")]
pub fn normalize_utf8_cow<'a>(cow: &mut Cow<'a, str>) {
let is_nfkd = unicode_normalization::is_nfkd_quick(cow.as_ref().chars());
if is_nfkd != unicode_normalization::IsNormalized::Yes {
Expand Down Expand Up @@ -506,7 +508,7 @@ impl Mnemonic {
}

/// Parse a mnemonic in the given language.
#[cfg(feature = "std")]
#[cfg(feature = "unicode-normalization")]
pub fn parse_in<'a, S: Into<Cow<'a, str>>>(
language: Language,
s: S,
Expand All @@ -517,7 +519,7 @@ impl Mnemonic {
}

/// Parse a mnemonic and detect the language from the enabled languages.
#[cfg(feature = "std")]
#[cfg(feature = "unicode-normalization")]
pub fn parse<'a, S: Into<Cow<'a, str>>>(s: S) -> Result<Mnemonic, Error> {
let mut cow = s.into();
Mnemonic::normalize_utf8_cow(&mut cow);
Expand Down Expand Up @@ -547,7 +549,7 @@ impl Mnemonic {
}

/// Convert to seed bytes.
#[cfg(feature = "std")]
#[cfg(feature = "unicode-normalization")]
pub fn to_seed<'a, P: Into<Cow<'a, str>>>(&self, passphrase: P) -> [u8; 64] {
let normalized_passphrase = {
let mut cow = passphrase.into();
Expand Down Expand Up @@ -596,7 +598,7 @@ impl Mnemonic {
}

/// Convert the mnemonic back to the entropy used to generate it.
#[cfg(feature = "std")]
#[cfg(any(feature = "alloc", feature = "std"))]
pub fn to_entropy(&self) -> Vec<u8> {
let (arr, len) = self.to_entropy_array();
arr[0..len].to_vec()
Expand All @@ -619,11 +621,11 @@ impl str::FromStr for Mnemonic {
type Err = Error;

fn from_str(s: &str) -> Result<Mnemonic, Error> {
#[cfg(feature = "std")]
#[cfg(feature = "unicode-normalization")]
{
Mnemonic::parse(s)
}
#[cfg(not(feature = "std"))]
#[cfg(not(feature = "unicode-normalization"))]
{
Mnemonic::parse_normalized(s)
}
Expand Down Expand Up @@ -842,7 +844,7 @@ mod tests {
mnemonic_str
);

#[cfg(features = "std")]
#[cfg(feature = "unicode-normalization")]
{
assert_eq!(&mnemonic.to_string(), mnemonic_str, "failed vector: {}", mnemonic_str);
assert_eq!(
Expand Down

0 comments on commit c62f91b

Please sign in to comment.