Fixed Size Slices as Function Parameters

I have a function that takes a fixed size buffer as parameter like a 32 byte digest. This data might be buried somewhere in a bigger buffer.

I could make the function parameter a slice &[u8] but I am not entirely happy with that solution:

  • It does not communicate that the parameter has to have exactly 32 bytes
  • I have to check the size dynamically in the function or let it panic if the function is used in a wrong way

I could also take a reference to an array as parameter &[u8; 32] and then convert a slice with try_into()

  • Now when I put in a slice where the size is known at compile time I have a lot of noise around this function parameter (&buf[4..36].try_into().unwrap()) altough there is no chance this could ever panic.

What do you recommend? Is there a better solution?

If the fixed size part is always at the same index in the slice then you turn the slice access into a function, ecapsulating the try and unwrap (fn foo(&[u8]) -> &[u8; 32]). A good name would also improve code legibility.

The essence of the problem is that you want to extract a 32-byte-long buffer from something that may or may not have the correct size. I think that should be a TryInto<[u8; 32]> and the burden of conversion should be on the function itself. In this manner, you could use an infallible pattern match (once !, the "never type", is a thing) to assert that a conversion from [u8; 32] can never fail: playground.

1 Like