Hello lovely Rust community,
I'm trying a toy project, recreating numpy in Rust, to help me learn Rust.
I've been trying to work out a way of generalising a Vec to N dimesions.
A function or macro that can generate an Vec of Vecs, to a depth of N.
My current implementation is only made up of functions and an enum going to 4D. However, I very quickly found this made my code huge and repeated.
pub enum ArrayData {
OneD(Vec<f64>),
TwoD(Vec<Vec<f64>>),
ThreeD(Vec<Vec<Vec<f64>>>),
FourD(Vec<Vec<Vec<Vec<f64>>>>),
}
impl ArrayData {
fn iter(&self) -> ArrayData {
match self {
Self::OneD(arg0) => ArrayData::OneD(arg0.iter().cloned().collect()),
Self::TwoD(arg0) => ArrayData::TwoD(
arg0.iter()
.map(|arg1| arg1.iter().cloned().collect())
.collect(),
),
Self::ThreeD(arg0) => ArrayData::ThreeD(
arg0.iter()
.map(|arg1| {
arg1.iter()
.map(|arg2| arg2.iter().cloned().collect())
.collect()
})
.collect(),
),
Self::FourD(arg0) => ArrayData::FourD(
arg0.iter()
.map(|arg1| {
arg1.iter()
.map(|arg2| {
arg2.iter()
.map(|arg3| arg3.iter().cloned().collect())
.collect()
})
.collect()
})
.collect(),
),
}
}
}
I then worked out I could use functions that take functions, so that this matching mess would only be in one place. For writing functions like Adding two Arrays together.
However, this still struck me as a hacky solution. Especially as it doesn't work for N dimesions, e.g. N = 1000.
I have been investigating Macros and this looks like the perfect use case. However, no matter what I try I can't get it working.
I've tried recursive macros, but always seem to hit the recursion limit, e.g.
which hits the recursion limit, even though, it can't recurse with the if statement (likely a problem with my limited understand of macros)
macro_rules! resursive {
( $v:expr, $s:expr) => {
if ($s < 0) | ($s > 10) {
vec![$v]
} else {
resursive![vec![$v], $s - 1]
};
};
}
The best I've been able to get is similar to the vec! macro
macro_rules! mac1 {
( $( $x:expr ),* ) => {
{
let temp_vec= vec![0];
$(
$x;
let temp_vec = vec![temp_vec];
)*
temp_vec
}
};
}
using syntax like mac1[1, 1, 1, 1]
and getting a nested vec of vecs [[[[[[0]]]]]]
.
I can't come up with a way of looping N number of times, with syntax like mac1[4]
being the same as mac1[1, 1, 1, 1]
. My instinct says this requires using tt
instead of expr
but that is waaaaay beyond me at the moment.
Any ideas on how to do this?