extern crate alloc;
use alloc::vec::Vec;
use crate::kairos::Kairos;
use crate::metis::{Anchor, Locus, Rhapsody};
use proptest::prelude::*;
use super::d;
mod accounting;
mod dangling;
mod round_trip;
mod totality;
#[derive(Clone, Debug)]
pub(super) struct Weave {
station: u32,
index: u64,
anchor_pick: Option<usize>,
before_side: bool,
tick: u64,
}
pub(super) fn arb_weaves() -> impl Strategy<Value = Vec<Weave>> {
prop::collection::vec(
(
1u32..=3,
1u64..=8,
prop::option::of(0usize..8),
any::<bool>(),
0u64..64,
)
.prop_map(|(station, index, anchor_pick, before_side, tick)| Weave {
station,
index,
anchor_pick,
before_side,
tick,
}),
0..24,
)
}
pub(super) fn build(weaves: &[Weave]) -> Rhapsody {
let mut rhapsody = Rhapsody::new();
let mut woven: Vec<(u32, u64)> = Vec::new();
for (ordinal, w) in weaves.iter().enumerate() {
let dot = d(w.station, w.index);
let anchor = w
.anchor_pick
.and_then(|pick| {
if woven.is_empty() {
None
} else {
Some(woven[pick % woven.len()])
}
})
.map_or(Anchor::Origin, |a| {
if w.before_side {
Anchor::Before(a.into())
} else {
Anchor::After(a.into())
}
});
let rank = Kairos::new(
w.tick,
u16::try_from(ordinal % 0xFFFF).unwrap_or(0),
w.station,
0u16,
);
if rhapsody.weave(dot, Locus { anchor, rank }) {
woven.push(dot.into());
}
}
rhapsody
}