extern crate alloc;
use alloc::collections::BTreeMap;
use alloc::string::String;
use alloc::vec::Vec;
use super::super::super::super::support::dot;
use crate::kairos::Kairos;
use crate::metis::{
Anchor, Dot, DotMap, DotSet, Kind, Locus, Metatheses, Metathesis, Node, Scholia, Scholion,
Verge,
};
use proptest::prelude::*;
use super::super::Inscribed;
use super::harness::Covered;
use crate::metis::dot::RawDot;
pub(super) type Seed = Vec<((u32, u64), bool)>;
pub(super) fn arb_seed() -> impl Strategy<Value = Seed> {
prop::collection::vec(((0u32..3, 1u64..8), prop::bool::ANY), 0..12)
}
pub(super) fn value_for(station: u32, counter: u64) -> String {
alloc::format!("v{station}-{counter}")
}
pub(super) fn covered_inscribed(seed: &Seed) -> Covered<Inscribed> {
let mut context = DotSet::new();
let mut entries: BTreeMap<Dot, String> = BTreeMap::new();
for &((station, counter), keep) in seed {
let _ = context.insert(dot(station, counter));
if keep {
let _ = entries.insert(dot(station, counter), value_for(station, counter));
}
}
Covered::new(Inscribed::from_entries(entries), context)
}
pub(super) fn covered_scholia(seed: &Seed) -> Covered<Scholia<String>> {
let mut context = DotSet::new();
let mut store = Scholia::new();
for &((station, counter), keep) in seed {
let _ = context.insert(dot(station, counter));
if keep {
let start = match counter % 3 {
0 => Verge::Origin,
1 => Verge::Before(RawDot { station, counter }),
_ => Verge::After(RawDot { station, counter }),
};
let end = match (u64::from(station) + counter) % 3 {
0 => Verge::Terminus,
1 => Verge::After(RawDot {
station,
counter: counter + 1,
}),
_ => Verge::Before(RawDot {
station,
counter: counter + 1,
}),
};
let _ = store.insert(
dot(station, counter),
Scholion {
start,
end,
tag: value_for(station, counter),
},
);
}
}
Covered::new(store, context)
}
pub(super) fn covered_metatheses(seed: &Seed) -> Covered<Metatheses> {
let mut context = DotSet::new();
let mut record = Metatheses::new();
for &((station, counter), keep) in seed {
let _ = context.insert(dot(station, counter));
if keep {
let anchor = match counter % 3 {
0 => Anchor::Origin,
1 => Anchor::After(RawDot {
station,
counter: counter + 1,
}),
_ => Anchor::Before(RawDot {
station,
counter: counter + 1,
}),
};
let _ = record.insert(
dot(station, counter),
Metathesis {
target: RawDot::new(station, counter.wrapping_add(7)),
to: Locus {
anchor,
rank: Kairos::new(counter, 0u16, station, 0u16),
},
},
);
}
}
Covered::new(record, context)
}
pub(super) fn covered_dot_set(seed: &Seed) -> Covered<DotSet> {
let mut context = DotSet::new();
let mut store = DotSet::new();
for &((station, counter), keep) in seed {
let _ = context.insert(dot(station, counter));
if keep {
let _ = store.insert(dot(station, counter));
}
}
Covered::new(store, context)
}
pub(super) fn covered_node(seed: &Seed) -> Covered<Node<u8, String>> {
let mut context = DotSet::new();
let mut node: Node<u8, String> = Node::new();
for &((station, counter), keep) in seed {
let _ = context.insert(dot(station, counter));
if !keep {
continue;
}
match counter % 4 {
0 => {
let kind = match (u64::from(station) + counter) % 3 {
0 => Kind::Register,
1 => Kind::Map,
_ => Kind::Sequence,
};
let _ = node.write_tag(dot(station, counter), kind);
}
1 => {
let _ = node.write_register(dot(station, counter), value_for(station, counter));
}
2 => {
let key = u8::try_from(station).unwrap();
let mut held: Node<u8, String> =
node.children().get(&key).cloned().unwrap_or_default();
let _ = held.write_register(dot(station, counter), value_for(station, counter));
let _ = node.insert_child(key, held);
}
_ => {
let _ = node.weave(
dot(station, counter),
Locus {
anchor: Anchor::Origin,
rank: Kairos::new(counter, 0u16, 1, 0u16),
},
);
}
}
}
Covered::new(node, context)
}
pub(super) fn covered_dot_map(seed: &Seed) -> Covered<DotMap<u8, DotSet>> {
let mut context = DotSet::new();
let mut store = DotMap::new();
for &((station, counter), keep) in seed {
let _ = context.insert(dot(station, counter));
if keep {
let key = u8::try_from(station).unwrap();
let mut held: DotSet = store.get(&key).cloned().unwrap_or_default();
let _ = held.insert(dot(station, counter));
let _ = store.insert(key, held);
}
}
Covered::new(store, context)
}