Numeric trait bounds. Constrain problem

Hi.

I'd like to implement a serde serializer for which I want to constrain on generic unsigned integer type. Since usize is arch dependent, I need to encode it with some byte length. I'd like to decide if I want to encode it as u32 or u16, thus my LenType trait bound. I've encountered a problem when trying to convert to le_bytes().

error[E0308]: mismatched types
  --> shared/src/deser.rs:76:37
   |
76 |         self.output.copy_from_slice(&value.to_le_bytes())?;
   |                     --------------- ^^^^^^^^^^^^^^^^^^^^ expected `&[u8]`, found `&<LenType as Numeric>::Bytes`
   |                     |
   |                     arguments to this method are incorrect
   |
   = note: expected reference `&[u8]`
              found reference `&<LenType as Numeric>::Bytes`
   = help: consider constraining the associated type `<LenType as Numeric>::Bytes` to `[u8]`
   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html

And another one:

error[E0599]: the method `push_usize_len` exists for mutable reference `&mut Serializer<OUT, LenType>`, but its trait bounds were not satisfied
   --> shared/src/deser.rs:200:14
    |
200 |         self.push_usize_len(v.len())?;
    |              ^^^^^^^^^^^^^^ method cannot be called on `&mut Serializer<OUT, LenType>` due to unsatisfied trait bounds

Code gbot/shared/src/deser.rs at main · luqasz/gbot · GitHub

For the first one, it looks like <_ as Numeric>::Bytes gets defined as arrays of different sizes, and arrays of different sizes have different types. I believe you could just add this to your generics and bounds:

impl<OUT, LenType, const LEN: usize> Serializer<OUT, LenType>
where
   LenType: Numeric<Bytes = [u8; LEN]>,
   // ...

Or even just

impl<OUT, LenType> Serializer<OUT, LenType>
where
   LenType: Numeric<Bytes: AsRef<[u8]>>,
   // ...

   self.output.copy_from_slice(value.to_le_bytes().as_ref())?;
1 Like

@quinedot

impl<OUT, LenType> Serializer<OUT, LenType>
where
   LenType: Numeric<Bytes: AsRef<[u8]>>,
   // ...

   self.output.copy_from_slice(value.to_le_bytes().as_ref())?;

This worked. Thx.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.