use std::collections::BTreeMap;
use std::fmt;
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
pub struct NodeId(pub Vec<u32>);
impl fmt::Debug for NodeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{self}")
}
}
impl fmt::Display for NodeId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let parts: Vec<String> = self.0.iter().map(u32::to_string).collect();
f.write_str(&parts.join("/"))
}
}
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct OrderKey(Box<[u8]>);
impl fmt::Debug for OrderKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:02x?}", self.0)
}
}
impl OrderKey {
pub fn nth(i: usize, n: usize) -> OrderKey {
let mut digits = 1;
let mut room = 255usize;
while room < n {
digits += 1;
room = room.saturating_mul(255);
}
let mut v = i;
let mut out = vec![0u8; digits];
for d in out.iter_mut().rev() {
*d = (v % 255) as u8 + 1;
v /= 255;
}
OrderKey(out.into_boxed_slice())
}
pub fn between(a: Option<&OrderKey>, b: Option<&OrderKey>) -> OrderKey {
let a: &[u8] = a.map_or(&[], |k| &k.0);
let mut b: Option<&[u8]> = b.map(|k| &*k.0);
let mut out = Vec::new();
let mut i = 0;
loop {
let da = a.get(i).copied().unwrap_or(0) as u16;
let db = match b {
Some(b) => b.get(i).copied().unwrap_or(0) as u16,
None => 256,
};
if db > da + 1 {
out.push(((da + db) / 2) as u8);
return OrderKey(out.into_boxed_slice());
}
out.push(da as u8);
if db == da + 1 {
b = None;
}
i += 1;
}
}
}
#[derive(Clone, Default)]
pub struct Children<T>(BTreeMap<OrderKey, T>);
impl<T: fmt::Debug> fmt::Debug for Children<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.0.values()).finish()
}
}
impl<T: PartialEq> PartialEq for Children<T> {
fn eq(&self, other: &Self) -> bool {
self.0.len() == other.0.len() && self.0.values().eq(other.0.values())
}
}
impl<T> Children<T> {
pub fn new() -> Self {
Children(BTreeMap::new())
}
pub fn from_vec(nodes: Vec<T>) -> Self {
let n = nodes.len();
Children(
nodes
.into_iter()
.enumerate()
.map(|(i, t)| (OrderKey::nth(i, n), t))
.collect(),
)
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn iter(&self) -> impl DoubleEndedIterator<Item = &T> + ExactSizeIterator {
self.0.values()
}
pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut T> + ExactSizeIterator {
self.0.values_mut()
}
pub fn entries(&self) -> impl DoubleEndedIterator<Item = (&OrderKey, &T)> {
self.0.iter()
}
pub fn get(&self, key: &OrderKey) -> Option<&T> {
self.0.get(key)
}
pub fn get_mut(&mut self, key: &OrderKey) -> Option<&mut T> {
self.0.get_mut(key)
}
pub fn nth(&self, at: usize) -> Option<&T> {
self.0.values().nth(at)
}
pub fn nth_mut(&mut self, at: usize) -> Option<&mut T> {
self.0.values_mut().nth(at)
}
pub fn first_key(&self) -> Option<&OrderKey> {
self.0.keys().next()
}
pub fn last_key(&self) -> Option<&OrderKey> {
self.0.keys().next_back()
}
pub fn key_after(&self, key: &OrderKey) -> Option<&OrderKey> {
use std::ops::Bound::{Excluded, Unbounded};
self.0
.range((Excluded(key), Unbounded))
.next()
.map(|(k, _)| k)
}
pub fn key_before(&self, key: &OrderKey) -> Option<&OrderKey> {
self.0.range(..key).next_back().map(|(k, _)| k)
}
pub fn push(&mut self, t: T) -> OrderKey {
let key = OrderKey::between(self.last_key(), None);
self.0.insert(key.clone(), t);
key
}
pub fn insert_after(&mut self, after: Option<&OrderKey>, t: T) -> OrderKey {
let next = match after {
Some(a) => self.key_after(a).cloned(),
None => self.first_key().cloned(),
};
let key = OrderKey::between(after, next.as_ref());
self.0.insert(key.clone(), t);
key
}
pub fn put(&mut self, key: OrderKey, t: T) {
self.0.insert(key, t);
}
pub fn remove(&mut self, key: &OrderKey) -> Option<T> {
self.0.remove(key)
}
pub fn clear(&mut self) {
self.0.clear()
}
pub fn rank(&self, key: &OrderKey) -> usize {
self.0.range(..key).count()
}
}
impl<'a, T> IntoIterator for &'a Children<T> {
type Item = &'a T;
type IntoIter = std::collections::btree_map::Values<'a, OrderKey, T>;
fn into_iter(self) -> Self::IntoIter {
self.0.values()
}
}
impl<T> std::ops::Index<usize> for Children<T> {
type Output = T;
fn index(&self, at: usize) -> &T {
self.nth(at).expect("a child at that place")
}
}
impl<T> FromIterator<T> for Children<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Children::from_vec(iter.into_iter().collect())
}
}
pub type Order = Vec<OrderKey>;
pub trait Node: Sized {
fn id(&self) -> &NodeId;
fn children(&self) -> &Children<Self>;
}
#[derive(Clone, Debug, Default)]
pub struct Ids(std::collections::HashMap<NodeId, Order>);
impl Ids {
pub fn of<N: Node>(root: &N) -> Ids {
let mut ids = Ids::default();
ids.add(root, Vec::new());
ids
}
pub fn add<N: Node>(&mut self, n: &N, order: Order) {
for (k, c) in n.children().entries() {
let mut o = order.clone();
o.push(k.clone());
self.add(c, o);
}
self.0.insert(n.id().clone(), order);
}
pub fn remove<N: Node>(&mut self, n: &N) {
self.0.remove(n.id());
for c in n.children() {
self.remove(c);
}
}
pub fn get(&self, id: &NodeId) -> Option<&Order> {
self.0.get(id)
}
pub fn contains(&self, id: &NodeId) -> bool {
self.0.contains_key(id)
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[cfg(test)]
mod tests;