BurntSushi / BurntSushi/quickcheck

Q: Idiomatic way to specify the length of an arbitrary vector

Open
#297 7 comments 1 reaction 0 assignees View on GitHub
Dominant language
Rust
Stars
2.8k
Forks
165
PR merge metrics
No merged PRs in 30d

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),
}
```

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::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::::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?

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reviewing the existing Arbitrary and Gen APIs, including Vec::arbitrary and the two from_random approaches shown in the issue. Determine which pattern is intended for bounded and fixed-size vectors, then document the recommended usage and how oversize values should be handled. Done means the guidance is clear enough to answer the original question.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
testing-qa
Issue type
Documentation
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.