use std::{
array,
fmt::{Debug, Write},
};
use dicetest::hint;
use crate::{Elem, Eval};
#[derive(Clone, Copy)]
pub struct Vars<'a, S: Debug, const N: usize> {
pub set: &'a str,
pub elems: [Elem<'a, S>; N],
}
impl<'a, S: Debug, const N: usize> Vars<'a, S, N> {
pub fn new(set: &'a str, elems: [Elem<'a, S>; N]) -> Self {
Self { set, elems }
}
pub fn eval(self) -> [Eval<&'a str, S>; N] {
let set = self.set;
let elems = self.elems;
fn elem_names<S: Debug, const N: usize>(elems: &[Elem<S>; N]) -> String {
let mut acc = String::new();
for (i, elem) in elems.iter().enumerate() {
if i == 0 {
write!(acc, "{}", elem.name).unwrap();
} else {
write!(acc, ", {}", elem.name).unwrap();
}
}
acc
}
hint!("{} of {}", elem_names(&elems), set);
elems.map(|elem| elem.eval())
}
pub fn as_ref<'b: 'a>(&'b self) -> Vars<'a, &'b S, N> {
let elems = array::from_fn(|i| self.elems[i].as_ref());
Vars::new(self.set, elems)
}
}