I'd like to check, at compile-time, that a slice used in a From
implementation is a specific size.
#[derive(Debug)]
struct Pixel {
r: u8,
g: u8,
b: u8,
}
impl From<&[u8]> for Pixel {
fn from(arr: &[u8]) -> Pixel {
Pixel {
r: arr[0],
g: arr[1],
b: arr[2],
}
}
}
fn main() {
println!("Hello, world!");
let arr: [u8; 9] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
println!("{:.?}", pixels);
}
This is not as specific as I'd like. I'd like to check the arr
passed to Pixel::from<&[u8]>()
is 3 elements as clearly as possible (at compile time).
Thought of assert!(arr.len()==3)
, but this checks at runtime.
So I thought maybe I could do the conversion by (Playground):
impl From<[u8; 3]> for Pixel {
fn from(arr: [u8; 3]) -> Pixel {
Pixel {
r: arr[0],
g: arr[1],
b: arr[2],
}
}
}
but this leads to:
error[E0277]: the trait bound `Pixel: From<&[u8]>` is not satisfied
--> src/main.rs:22:30
|
22 | let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<&[u8]>` is not implemented for `Pixel`
|
= help: the following implementations were found:
<Pixel as From<[u8; 3]>>
error[E0277]: the trait bound `Pixel: From<&[u8]>` is not satisfied
--> src/main.rs:22:54
|
22 | let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
| ^^^^^^^^^^^ the trait `From<&[u8]>` is not implemented for `Pixel`
|
= help: the following implementations were found:
<Pixel as From<[u8; 3]>>
= note: required by `from`
error[E0277]: the trait bound `Pixel: From<&[u8]>` is not satisfied
--> src/main.rs:22:30
|
22 | let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<&[u8]>` is not implemented for `Pixel`
|
= help: the following implementations were found:
<Pixel as From<[u8; 3]>>
Similarly I tried From<&[u8; 3]>
but same result.
Is there a way to implement from for a specific sized slice?
This is a not a duplicate of How to convert a slice into an array reference? as this question specifically relates to checking at compile-time without runtime performance effects, it is not casting &[u8]
to &[u8; 3]
rather simply checking at compile time &[u8]
has 3 elements (which may be done via using &[u8; 3]
). All answers to the aforementioned question incur runtime affects, except I believe this approach in this answer (applied like this) but this does not check at all that the slice is the appropriate length. This question is not specifically about being able to use Pixel::from<[u8;3]>
but rather about generally checking the length at compile time, which none of these answers offer or relate to.