-
-
Notifications
You must be signed in to change notification settings - Fork 436
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Alphanumeric::gen_string
#1128
Comments
Yes, it seems desirable to do something to solve this. Perhaps we should put impl Rng {
fn gen_string(&mut self, len: usize) -> String;
} Options (ii) and (iii) might be more flexible, but all of these are easy to implement and from what I understand the issue here is just to make generating a |
Option iii can still be more performant than The problem with At the very least, maybe pub fn random_alphanumeric_string(len: usize) -> String { ... } In addition, for a more flexible API, I'm thinking: pub trait Distribution {
// ...
pub fn gen_string(&self, rng: impl Rng, string: &mut String, len: usize) where Self: CharDistribution + Sized;
}
// new marker trait makes this a backwards-compatible addition as well?
pub trait CharDistribution {}
impl CharDistribution for Alphanumeric {}
impl CharDistribution for Uniform<char> {}
impl CharDistribution for Standard<char> {}
impl Distribution<u8> for Alphanumeric {
pub fn gen_string(&self, rng: impl Rng, string: &mut String, len: usize) where Self: CharDistribution + Sized {
// SAFETY: `Alphanumeric` is guaranteed to sample valid single-byte UTF-8
unsafe { string.as_mut_vec().extend(self.sample_iter(rng).take(len)) }
}
}
impl Distribution<char> for Standard<char> {
pub fn gen_string(&self, rng: impl Rng, string: &mut String, len: usize) where Self: CharDistribution + Sized {
// guarantee at most one allocation by reserving for the absolute worst-case
string.reserve(len * 4);
string.extend(self.sample_iter(rng).take(len));
string.shrink_to_fit();
}
}
impl Distribution<char> for Uniform<char> {
pub fn gen_string(&self, rng: impl Rng, string: &mut String, len: usize) where Self: CharDistribution + Sized {
// same as `Standard<char>`
// although this could instead reserve based on the `char::utf8_len()` of the upper bound
}
} Alternatively instead of a new marker trait this could be a provided method for In this case I don't think there's a need for a separate |
Is this important? The advantage over So the question is: how many people will use this, and which API will most of those want? BTW if we support (iii) it should probably be called
Good point. So it's either that or
Sorry, I don't like that. Why are we adding a new trait, and if so why modify This is a significant expansion of scope with unclear demand, plus it loses some of the original rationale: you don't need (Also I don't get why you use |
The If the idea is to keep to a limited scope then |
Background
Some people wonder how to use
Alphanumeric
to generate a string (see #935). While we give an example in the documentation, it might be more obvious to provide a method for this, especially because the efficient implementation requires unsafe code.Applications are the generation of unique IDs and nonces for APIs such as OAuth.
Feature request
Provide a method of
Alphanumeric
for generating strings.Open questions:
gen_string
supporting onlyCryptoRng
s andgen_string_insecure
supporting any RNG?fn gen_string(&self, &mut Rng, usize) -> String
),fn gen_string(&self, &mut Rng, &mut str)
) orfn gen_string(&self, &mut Rng, &mut String, usize)
)?i. is probably most efficient, because we can call
String::from_utf8_unchecked
, but it cannot reuse an existing buffer.ii. is more flexible in that regard, but it requires an initialized buffer.
iii. is the most flexible, but offers little over converting to
char
and collecting.The text was updated successfully, but these errors were encountered: