use std::{array, fmt::Debug, marker::PhantomData};
use dicetest::{Die, DieOnce, dice};
use crate::{Elem, Vars};
pub struct Set<'a, S: Debug, D: DieOnce<S> + 'a> {
pub name: &'a str,
pub elem_die: D,
_s: PhantomData<S>,
}
impl<'a, S: Debug, D: DieOnce<S> + 'a> Set<'a, S, D> {
pub fn new(name: &'a str, elem_die: D) -> Self {
Self {
name,
elem_die,
_s: PhantomData,
}
}
pub fn var_once(self, name: &'a str) -> impl DieOnce<Vars<'a, S, 1>> {
let set = self.name;
let die = self.elem_die;
dice::from_fn_once(move |mut fate| {
let value = fate.roll(die);
let elem = Elem::new(name, value);
Vars::new(set, [elem])
})
}
}
impl<'a, S: Debug, D: Die<S> + 'a> Set<'a, S, D> {
pub fn as_ref<'b: 'a>(&'b self) -> Set<'a, S, &'b D> {
Set {
name: self.name,
elem_die: &self.elem_die,
_s: PhantomData,
}
}
pub fn vars<const N: usize>(self, names: [&'a str; N]) -> impl Die<Vars<'a, S, N>> {
let set = self.name;
let die = self.elem_die;
dice::from_fn(move |mut fate| {
let elems: [_; N] = array::from_fn(|i| {
let name = names[i];
let value = fate.roll(&die);
Elem::new(name, value)
});
Vars::new(set, elems)
})
}
}