Search code examples
structrusttraits

Implementing inner type's traits on outer type


With the struct:

    struct U85 (
        [u8; 5]
    );

I get the error:

error[E0608]: cannot index into a value of type `&U85`
   --> /home/fadedbee/test.rs:11:40
    |
11  |                     s.serialize_bytes(&self[..])
    |

whereas when I use the simple type [u8; 5] everything is fine.

  • What trait of [u8; 5] causes the indexing error?
  • How can I implement it for U85?

Solution

  • The x[y] syntax is implemented with the Index and IndexMut traits. One catch with indexing for slices is that x, x..y, .., ..y, x.. are all different types. You can either pick-and-choose what you want to support, but if you just want to do what slices can do, you can implement it like so:

    use std::ops::Index;
    use std::slice::SliceIndex;
    
    struct U85([u8; 5]);
    
    impl<I> Index<I> for U85 where I: SliceIndex<[u8]> {
        type Output = I::Output;
        fn index(&self, index: I) -> &I::Output {
            &self.0[index]
        }
    }
    

    If you find yourself implementing traits for wrapper types a lot, you can look into using the derive_more crate, which will allow you to derive traits (like Index) that defer to the inner type.

    use derive_more::Index;
    
    #[derive(Index)]
    struct U85([u8; 5]);