I am attempting to create a structure with a few friendly From
trait implementations. The structure is a wrapper for an array of arrays of arrays to represent a 3D matrix.
pub struct Table<T, const X: usize, const Y: usize, const Z: usize> {
pub content: [[[T; X]; Y]; Z],
}
impl<T, const X: usize> From<[T; X]> for Table<T, X, 1, 1> {
fn from(row: [T; X]) -> Self {
Table { content: [[row]] }
}
}
impl<T, const X: usize, const Y: usize> From<[[T; X]; Y]> for Table<T, X, Y, 1> {
fn from(layer: [[T; X]; Y]) -> Self {
Table { content: [layer] }
}
}
impl<T, const X: usize, const Y: usize, const Z: usize> From<[[[T; X]; Y]; Z]>
for Table<T, X, Y, Z>
{
fn from(matrix: [[[T; X]; Y]; Z]) -> Self {
Table { content: matrix }
}
}
fn main() {
let i1 = [1];
let i2 = [[1]];
let i3 = [[[1]]];
// Table<i32>
// notice how you can avoid specifying the constant values
let tbl1 = Table::from(i1);
// type annotations needed
// cannot infer type for struct `Table<_, {_: usize}, {_: usize}, {_: usize}>`
// let tbl2 = Table::from(i2);
}
I have tried a few alternative solutions including:
to_table
trait solution (which lead to the same issue in reverse)- macro_rules (was unable to determine whether the provided types were nested within arrays. I have minimal macro experience)
- specific type impl(s) (this works, but is a bad choice because it limits the number of out-of-the-box supported types I could use to populate a table)
I would love to understand how to distinguish generic type implementations from generic type implementations within arrays. I feel that my fundamental issue is that
T
and [T; _]
are the same thing- or rather they confuse the compiler.
Alternative question: Is there a way to specify the non-constant generic types of an element in Rust? I would be happy if using
// possible to skip X, Y, Z?
let tbl: Table<i32> = Table::from([[1]]);
worked, but you have to go through specifying the lengths of all the constants if you manually enter the generic property. Clarification on this second point would be greatly appreciated as well.