WIP: Add `dearbitrary` functionality to turn an instance into its arbitrary byte sequence
This PR solves issue #44 by implementing a dearbitrary function to create a byte buf, which can be used again with arbitrary to recreate the struct. It is not a one to one mapping, as e.g. bools only use the last bit of a byte value.
What works:
- [x] derive
- [x] integer/float/char/bools primitive types
- [x] tuples
- [x]
() - [ ] AtomicBool
- [ ] AtomicIsize
- [ ] AtomicUsize
- [ ] Ranges
- [ ] Duration
- [ ] Option<A>
- [ ] Result
- [ ] [T; N]
- [x] &'a [u8]
- [x] Vec
- [ ] BTreeMap
- [ ] BTreeSet
- [ ] BinaryHeap
- [ ] HashMap
- [ ] HashSet
- [ ] ... everything which uses an iterator
- [ ] &'a str
- [ ] String
- [x] Box<A>
- [x] Box<[A]>
- [ ] ... many other things missing
Many parts are missing, as I do not need them at the moment and have no time to implement them...
Remark: commits are prone to change/squashing/reordering!!
From a maintenance pov i strongly agree that this should be a separate trait. I'm also wary but I'm happy to defer to fitzgen's judgement on this and agree with his assessment of the steps that should happen first.
@fitzgen The seperate trait idea is appropiate, as not everything can be "dearbitraryed" e.g. Atomics In general, this was just a quick n dirty hack for myself, to create seeding input for a fuzzer. Poking bytes via hexedit and checking the result is quite time consuming :D
A fuzz target that checks that we can take an arbitary instance of a type, call dearbitrary on it, call arbitrary on the resulting bytes, and then assert that the initial arbitrary instance and the new arbitrary instance are the same. The type should be an enum that contains all the major different kinds of types that this crate implements Arbitrary for
Maybe we can use here something like a QuickCheck implementation for Rust
Maybe we can use here something like a QuickCheck implementation for Rust
I would prefer to use libfuzzer in this case, something like:
fuzz_target!(|expected: MyEnum| {
let bytes = expected.dearbitrary();
let actual = MyEnum::arbitrary_take_rest(Unstructured::new(bytes)).unwrap();
assert_eq!(expected, actual);
});
Which also makes me realize that we need not just dearbitrary but also dearbitrary_as_rest or something to be the dual of arbitrary_take_rest.