Skip to content
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

Use a Config trait to configure bincodes compile-time decisions #180

Closed
wants to merge 5 commits into from

Conversation

@TyOverby
Copy link
Collaborator

TyOverby commented Apr 30, 2017

This design will not only reduce the complexity of many type signatures, but it'll also allow us to add more features without breaking back-compat.

This is because the config trait is not implementable by customers of the library (it has a trait bound of a hidden type), and the BasicConfig object is not referenceable by type name because it is parameterized by a hidden type.

What this means practically is that adding another option to bincode like "use variable length encoding" is possible to add as an option without it being a breaking change.

@TyOverby TyOverby requested a review from dtolnay Apr 30, 2017
@dtolnay
Copy link
Collaborator

dtolnay commented Apr 30, 2017

Neat idea. What are the advantages of including SizeLimit in this config and handling it with Bincode-specific code throughout?

On the deserialization side, it seems like size limit is configuring a property of the IO stream not a property of Bincode, so to me it doesn't belong in the Bincode config. Implementing this as a wrapper that puts a cap on the number of bytes read from a reader would make it reusable across all formats. Also it could potentially be implemented in a significantly more performant way for buffered readers. We only need to check the size limit once per filling of the buffer, not every single time a piece is read from the buffer.

On the serialization side, many of the uses of Bounded I saw on GitHub were pretty worthless. For example this one.

packet.append(&mut serialize::<_,_,NetworkEndian>(&(p as u16), Bounded(2)).unwrap());

I would prefer to push people to use serialized_size_bounded because it makes it clear at the call site what state the stream is left in if the input is too big.


/// The default configuration options for bincode.
///
/// Endianness: BigEndian - Big endian is the fastest option on most modern CPU architectures

This comment has been minimized.

@dtolnay

dtolnay Apr 30, 2017

Collaborator

The code says LittleEndian.

This comment has been minimized.

@TyOverby

TyOverby May 3, 2017

Author Collaborator

Fixed

@dtolnay
Copy link
Collaborator

dtolnay commented Apr 30, 2017

Also I would like an API that is more friendly to the overwhelmingly common case than this.

bincode::serialize(&t, DEFAULT_CONFIG)

Maybe something like:

bincode::serialize(&t)
bincode::little_endian().serialize(&t)
bincode::bounded(50<<20).little_endian().serialize(&t)
@TyOverby
Copy link
Collaborator Author

TyOverby commented May 3, 2017

What are the advantages of including SizeLimit in this config

Benefit is that all configuration trait parameters go in one trait.

and handling it with Bincode-specific code throughout?

I firmly believe that size-limit should be a part of the bincode API, though maybe not as prominently (or as baked-in) as it currently is. I'd be willing to do some experiments with making this generic over Readers.

Also I would like an API that is more friendly to the overwhelmingly common case than this.

Your examples look great! I think that something like this would be perfect for the final API.

@dtolnay
Copy link
Collaborator

dtolnay commented May 3, 2017

Seems good to me as long as we agree to change the serialize(&t, DEFAULT_CONFIG) API before release this.

Also be careful because this code would be broken by adding another type parameter:

struct S<E: ByteOrder, L: SizeLimit, O> {
    bincode: BasicConfig<E, L, O>
}
@TyOverby
Copy link
Collaborator Author

TyOverby commented May 6, 2017

Also be careful because this code would be broken by adding another type parameter:

Damn, I was really hoping to avoid this. Is there any way to keep people from storing references to such structs?

@dtolnay
Copy link
Collaborator

dtolnay commented May 6, 2017

Yes but I think keeping people from storing references to such structs is not the best approach. How about defining BasicConfig without any type parameters? Then when serializing / deserializing, as early as possible turn it into a private generic one similar to BasicConfig in this PR.

@TyOverby
Copy link
Collaborator Author

TyOverby commented May 6, 2017

Interesting thought. Yeah, if we use the builder API like you've proposed above, it wouldn't be necessary to have the generic type parameters.

@TyOverby
Copy link
Collaborator Author

TyOverby commented Nov 15, 2017

Closed in favor of #217

@TyOverby TyOverby closed this Nov 15, 2017
@dtolnay dtolnay deleted the config branch Mar 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants
You can’t perform that action at this time.