Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement BCS deserialization from_reader (#6)
* Implement BCS deserialization from_reader ** Strategy ** The commit aims to maintain a minimal diff over the previous implementation. To that end, the following changes have been made. - Make `Deserializer` generic over an inner type `R` - Factor as much of the implementation as possible into a new trait `BcsReader`, which implements BCS in terms of a few primitive operations. Implement `serde::Deserialize<'de> for Deserializer<R> where Deserializer<R>: BcsReader<'de>` - Implement `BcsReader<'de>` for `Deserializer<&'de [u8]>` using existing code - Implement `BcsReader` generically for (a version of) `Deserializer<R: Read>`. The existing implementation is very close to supporting deserialization from readers. There are only two places in which its behavior relied on access to a byte slice was in the implementation of `de::MapAccess`. The first case is `map` deserialization. `bcs` needs access to the serialized representation of map keys in order to enforce canonicity. When deserializing from a slice, this is straightforward - the implementation can simply deserialize a map key, and then "look back" at the original input slice to determine its serialized representation. When deserializing from a reader, however, this kind of rewinding is not generally possible. To solve this problem, I introduce a the `TeeReader` struct, which wraps a `Read`er and optionally copies its bytes into a `capture_buffer` for later retrieval. Then, I simply implement `BcsReader` for `Deserializer<TeeReader<...>>`. The second case is the `end` method, which checks that all input bytes have been consumed. To handle this case, I simply attempt to read one extra byte from the `Read`er after deserialization and assert that an EOF error is returned from the underlying `Read`er. ** Testing ** All existing unit tests except for `zero_copy_parse` have been modified to test that deserialization `from_bytes` and `from_reader` yield the same output. That test is not applicable since readers are not capable of zero-copy deserialization.
- Loading branch information