EDIT: This question isn't relevant on versions of Rust >= 1.47 because "const generics" has started being implemented.
I'm trying to implement a sudoku solver in Rust for learning purposes. I'm trying to create a board with a fixed size (81) array of Cells (which is Copy) but I can't seem to get it to work. I can create a line of 9 Cells so I guess I'm running into the problem where there are only generics for TryFrom for up 32 for this kind of conversion.
Cell looks like this for now:
#[derive(Debug, Default, Clone, Copy)]
struct Cell {
row: u8,
column: u8,
}
This works:
use std::convert::TryInto;
fn main() {
let cells: Vec<Cell> = std::iter::repeat(0)
.zip(0..9u8)
.map(|(row, column)| Cell { row, column} )
.collect();
let c: Box<[Cell; 9]> = cells.into_boxed_slice().try_into().unwrap();
println!("{:#?}", c);
}
But this doesn't:
use std::convert::TryInto;
fn main() {
let cells: Vec<Cell> = (0..9u8).into_iter()
.flat_map(|x| {
std::iter::repeat(x)
.zip(0..9u8)
})
.map(|(row, column)| Cell { row, column} )
.collect();
let c: Box<[Cell; 81]> = cells.into_boxed_slice().try_into().unwrap();
println!("{:#?}", c);
}
I tried to use the code from std as a guide like this:
impl TryFrom<Box<[Cell]>> for Box<[Cell; 81]> {
type Error = Box<[Cell]>;
fn try_from(boxed_slice: Box<[Cell]>) -> Result<Self, Self::Error> {
if boxed_slice.len() == 81 {
Ok(unsafe { Box::from_raw(Box::into_raw(boxed_slice) as *mut [Cell; 91]) })
} else {
Err(boxed_slice)
}
}
}
but that runs into an error about conflicting implementations of trait which I guess makes sense.
I know I could just use a Vec or do something like [[Cell; 9]; 9] but I'd really like to understand what's going on. While trying to figure this out I've seen a number of similar questions where people were trying to use types that didn't implement Copy and that was the problem but that's not the case here and I can't figure out how to make this work.