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

Read/Write mutable reference in serialize and deserialize_reader is unnecessary #270

Open
Tracked by #279
billythedummy opened this issue Dec 10, 2023 · 8 comments

Comments

@billythedummy
Copy link

Currently, the required method for BorshDeserialize has the following signature:

fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self>;

However, it can be changed to just:

fn deserialize_reader<R: Read>(reader: R) -> Result<Self>;

because Read has a blanket impl for mut references: https://docs.rs/borsh/latest/borsh/io/trait.Read.html#impl-Read-for-%26mut+R

Similarly, BorshSerialize can be changed from

fn serialize<W: Write>(&self, writer: &mut W) -> Result<()>;

to

fn serialize<W: Write>(&self, writer: W) -> Result<()>;

because Write has a blanket impl for mut references: https://docs.rs/borsh/latest/borsh/io/trait.Write.html#impl-Write-for-%26mut+W

This will be a breaking change

@billythedummy billythedummy changed the title Read/Write mutable reference in serialize and deserialize_reader is unnecessary Read/Write mutable reference in serialize and deserialize_reader is unnecessary Dec 10, 2023
@dj8yfo
Copy link
Collaborator

dj8yfo commented Dec 10, 2023

it probably should've been

fn deserialize_reader<R: Read>(mut reader: R) -> Result<Self>;

Does this change allow any wider use cases for the traits?
I believe both signatures are equivalent with respect to how the traits can be used in practice, and mutable reference argument better reflects semantics of what the traits are doing: they borrow Reader/Writer for de/ser of one object and return it intact to the caller (by-value argument drops Reader/Writer after one object).

@billythedummy
Copy link
Author

billythedummy commented Dec 11, 2023

It probably should've been
fn deserialize_reader<R: Read>(mut reader: R) -> Result<Self>;

No. You do not need to specify mut in the trait definition itself, only in the implementation. See playground link below.

Does this change allow any wider use cases for the traits?

It's somewhat weird that you have to pass a mutable reference to a immutable buffer when you're deserializing. See playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=dd2f2606d714535fbba3e5e5b00208cc

mutable reference argument better reflects semantics of what the traits are doing

Yes. But if your writer is a mutable reference itself then it makes sense for the mutable reference to be dropped after one object, does it not?

For reference: serde_json also bounds most stuff by W and R instead of &mut W and &mut R https://docs.rs/serde_json/latest/serde_json/fn.to_writer.html , https://docs.rs/serde_json/latest/serde_json/fn.from_reader.html

@dj8yfo
Copy link
Collaborator

dj8yfo commented Dec 11, 2023

It's somewhat weird that you have to pass a mutable reference to a immutable buffer when you're deserializing

these are playground examples for Read and Write

https://doc.rust-lang.org/src/std/io/impls.rs.html#248

@billythedummy
Copy link
Author

billythedummy commented Dec 11, 2023

I believe Rust API guidelines recommends to pass Read and Write by value: https://rust-lang.github.io/api-guidelines/interoperability.html#generic-readerwriter-functions-take-r-read-and-w-write-by-value-c-rw-value

Regarding the playground examples, I think this is what by_ref() is for. Read example fixed, Write example fixed

@billythedummy
Copy link
Author

More info here: rust-lang/api-guidelines#174

@dj8yfo
Copy link
Collaborator

dj8yfo commented Dec 13, 2023

Frankly speaking this is illuminating

video_2023-12-13_17-22-28.mp4

@billythedummy
Copy link
Author

So, do you guys intend to change this for 2.0? I also wanna add that this issue has surfaced before: #34

@frol frol mentioned this issue Feb 6, 2024
4 tasks
@frol
Copy link
Collaborator

frol commented Feb 6, 2024

@billythedummy Thank you for raising it

So, do you guys intend to change this for 2.0?

We don't intent to release 2.0 any time soon unless there is a very good reason to. I have created a tracking issue for the ideas that would require us to bump the major version here: #279

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants