-
Notifications
You must be signed in to change notification settings - Fork 160
Description
Is there documentation on the idiomatic way to specify the length of an arbitrary vector?
My specific example is this:
I have a struct with fields containing various data types (like max 64-bytes, max 255-bytes, exactly 32-bytes, etc.) that I need to implement Arbitrary for. As an example, I will use one field in the Foo struct that represents a vector of 255 bytes.
struct Foo {
bar: B0255
}
Where
struct B0255<'b>(Inner<'b>);
enum Inner<'a> {
Ref(&'a [u8]),
Owned(Vec<u8>),
}
To test this struct, I have created a new struct and implemented Arbitrary, which calls a function from_random which is implemented for Foo. from_random is needed because Arbitrary needs to be implemented in another crate.
struct RandomFoo(Foo);
impl Arbitrary from RandomFoo {
fn arbitrary(g: &mut Gen) -> Self {
RandomFoo(Foo::from_random(g))
}
}
Currently, I am passing in the generator to the from_random function and generating the 255 byte vectors as:
impl Foo {
fn from_random(g: &mut Gen) -> Self {
let mut bar = Vec<u8>::arbitrary(g);
bar.truncate(255);
let bar: B0255 = bar.try_into().unwrap();
Foo { bar }
}
}
Here I am truncating the vector to avoid a panic caused by a vector that is too big. Was thinking that the best approach may be having the try_into return the right error when called with a value that is too big, but I am not sure if this is possible as Arbitrary needs to return Self?
Additionally, when from_random is implemented for fixed size primitives (eg U256) should resize(255, 0) be used instead of truncate?
Alternatively, I can implement from_random as:
impl Foo {
fn from_random(g: &mut Gen) -> Self {
let mut bar: B0255 = Gen::new(255);
bar: B0255 = Vec::<u8>::arbitrary(&mut bar).try_into().unwrap();
Foo { bar }
}
}
Which, if either, from_random implementation is the idiomatic way to generate a vector of a specific size?