-
-
Notifications
You must be signed in to change notification settings - Fork 272
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
v2 release candidate initiative to include stateful decode impls akin to serde's DeserializeSeed? #578
Comments
Is there a reason we cannot do this? pub trait DecodeInPlace: Sized { // name is bikesheddable
// note: &mut self, and does not return a value
fn decode_seed<D: Decoder>(&mut self, decoder: &mut D) -> Result<(), DecodeError>;
} |
One thing that might become a problem is that we'll start scaling the types rapidly. Say we implement an
If we add another variant, we'll end up with 16 different types, although I'm currently not sure if we'll need another type. |
I feel that this design could be slightly less ergonomic in cases where we might want to utilize a reference rather than some mutable data structure and get some kind of meaning full return. For example, if we wanted to filter a component of a larger message in order to avoid further decoding, we could use a reference to a HashSet containing the variants we are interested in. We can encode the following struct: #[derive(Debug, Encode, Decode, Hash, Eq, PartialEq)]
enum Color {
Red,
Blue,
Green,
}
#[derive(Debug, Encode)]
pub struct Car {
color: Color,
top_speed: u64,
cylinders: u8,
} And define the following struct implementing DecodeSeed where we are filtering for desired colors: struct CarSeed<'a> {
filter: &'a HashSet<Color>,
}
impl<'a> DecodeSeed for CarSeed<'a> {
type Value = Option<Car>;
#[inline]
fn decode_seed<D: bincode::de::Decoder>(self, decoder: &mut D) -> Result<Self::Value, bincode::error::DecodeError> {
let color = bincode::Decode::decode(decoder)?;
if !self.filter.contains(&color) {
return Ok(None);
}
let top_speed = bincode::Decode::decode(decoder)?;
let cylinders = bincode::Decode::decode(decoder)?;
Ok(Some(Car { color, top_speed, cylinders }))
}
} // Encode
let car = Car { color: Color::Blue, top_speed: 80, cylinders: 4};
let buffer = bincode::encode_to_vec(&car, config::standard()).unwrap();
// Create HashSet filter containing the Green Color variant
let mut filter = HashSet::new();
filter.insert(Color::Green);
let seed = CarSeed { filter: &filter };
// Decode
let slice_reader = SliceReader::new(&buffer[..]);
let mut decoder = bincode::de::DecoderImpl::new(slice_reader, config::standard());
let result = seed.decode_seed(&mut decoder);
println!("{result:?}") // Ok(None) In this case, I feel having a return type is more clear.
This is a valid concern. I agree that if there appears to be a way forward for adding several new types or traits akin to what you suggested, then adding a new Seed variant could become cumbersome for maintainability. After working with the library release candidate for the past few days, I found it is actually quite straight forward to implement custom decoding sequences using the exposed internals. Thus, all of what I would want to do in terms of stateful decoding appears to be fully possible. I see the real benefit of adding a stateful decoding trait to the library itself would be for standardization. |
I've been considering making a |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Until a repo for |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
With the transition to the bincode specific encode and decode traits in the v2 release candidate, it appears there is currently no mechanism available for stateful deserialization comparable to Serde's
DeserializeSeed
trait.See: https://github.com/serde-rs/serde/blob/f52d134c14f6904010d0a59107987b050b36b811/serde/src/de/mod.rs#L770
The following trait definitions could be included to provide this functionality.
For example, utilizing the
DecodeSeed
trait defined above, theSequenceSeed
struct could be defined below:Utilizing
SequenceSeed
, we can append each decoded element to a pre-allocated vector.I feel this functionality provides many opportunities for optimizations and would be a useful addition.
The text was updated successfully, but these errors were encountered: