Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,12 @@ pub trait Bounded {
/// Encoding support.
pub trait Encoding: Sized {
/// Byte array representation.
type Repr: AsRef<[u8]> + AsMut<[u8]> + Copy + Clone + Sized;
type Repr: AsRef<[u8]>
+ AsMut<[u8]>
+ Copy
+ Clone
+ Sized
+ for<'a> TryFrom<&'a [u8], Error = core::array::TryFromSliceError>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the error type is particularly relevant here? Do we really need to mandate it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It helps a lot with writing down trait bounds in the user code. See rust-lang/rust#113517 for example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To add to that, even with the workaround in the issue above, it does not work when another level is added. That is, if the foo() in the issue is a serde-standard deserialize() function, and I want to make a custom deserializer using serde_with as

impl<'de, const N: usize> serde_with::DeserializeAs<'de, Uint<N>> for UintWrapper<N>
where
    Uint<N>: Encoding,

there is no way to write trait bounds that would tell the compiler that the returned error is Display (so that it could be wrapped in the serde error).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, if there's a legitimate use case I guess we can include it.

It's just a completely useless error that includes no relevant information, so it's easily handled without bounding on it by using .ok() or .map_err(...).

But if it helps with serde, I guess that's fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is pretty useless, I agree. But if you have a function that is generic on something that's TryFrom<&[u8]> and you want the error to be Display (because it may be useful for some types, so you don't want to discard it), fixing the error in this specific case helps with the bounds. I don't particularly like it either, but unfortunately Rust compiler is currently not smart enough to handle bounds without it. I think it should be pretty harmless, since it's essentially an internal trait that's not supposed to be used outside of the crate.


/// Decode from big endian bytes.
fn from_be_bytes(bytes: Self::Repr) -> Self;
Expand Down