use std::{
borrow::Borrow,
fmt::{Debug, Display},
marker::PhantomData,
};
use num::{cast, NumCast, PrimInt, ToPrimitive};
use crate::types::{
HashKind, HyperType, LabelStore, Labeled, MySlice, NodeId, NodeStore, NodeStoreMut, Stored,
Typed, WithChildren, WithStats,
};
pub struct SimpleTree<K> {
kind: K,
label: Option<String>,
children: Vec<SimpleTree<K>>,
}
impl<K> SimpleTree<K> {
pub fn new(k: K, l: Option<&str>, c: Vec<SimpleTree<K>>) -> Self {
Self {
kind: k,
label: l.map(|s| s.to_owned()),
children: c,
}
}
}
fn store<'a>(ls: &mut LS<u16>, ns: &mut NS<Tree>, node: &SimpleTree<u8>) -> u16 {
fn store_aux<'a>(ls: &mut LS<u16>, ns: &mut NS<Tree>, node: &SimpleTree<u8>) -> Tree {
let lid = node
.label
.as_ref()
.map(|x| ls.get_or_insert(x.as_str()))
.unwrap_or(0);
let mut size = 1;
let mut height = 0;
let children = node
.children
.iter()
.map(|x| {
let t = store_aux(ls, ns, x);
size += t.size;
height = height.max(t.height);
ns.get_or_insert(t)
})
.collect();
height += 1;
Tree {
t: node.kind,
label: lid,
children,
size,
height,
}
}
let t = store_aux(ls, ns, node);
ns.get_or_insert(t)
}
pub fn vpair_to_stores<'a>(
(src, dst): (SimpleTree<u8>, SimpleTree<u8>),
) -> (LS<u16>, NS<Tree>, u16, u16) {
let (mut label_store, mut compressed_node_store) = make_stores();
let src = store(&mut label_store, &mut compressed_node_store, &src);
let dst = store(&mut label_store, &mut compressed_node_store, &dst);
(label_store, compressed_node_store, src, dst)
}
impl AsRef<Tree> for &Tree {
fn as_ref(&self) -> &Tree {
self
}
}
pub struct DisplayTree<'a, 'b, I: num::PrimInt, T: WithChildren> {
ls: &'a LS<I>,
ns: &'b NS<T>,
node: u16,
depth: usize,
}
impl<'a, 'b> DisplayTree<'a, 'b, u16, Tree> {
#[allow(dead_code)]
pub fn new(ls: &'a LS<u16>, ns: &'b NS<Tree>, node: u16) -> Self {
Self {
ls,
ns,
node,
depth: 0,
}
}
}
impl<'a, 'b> Display for DisplayTree<'a, 'b, u16, Tree>
where
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let cs = self.ns.resolve(&self.node);
writeln!(
f,
"{}|-{}:{} \ts{}\th{}",
" ".repeat(self.depth),
cs.get_type(),
self.ls.resolve(cs.get_label_unchecked()),
cs.size(),
cs.height(),
)?;
if let Some(cs) = cs.children() {
let cs: Vec<_> = cs.into();
for n in cs {
Display::fmt(
&Self {
ls: self.ls,
ns: self.ns,
node: n,
depth: self.depth + 1,
},
f,
)?;
}
}
Ok(())
}
}
impl<'a, 'b> Debug for DisplayTree<'a, 'b, u16, Tree> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let cs = self.ns.resolve(&self.node);
writeln!(
f,
"{}|-{}:{} \t({})\ts{}\th{}",
" ".repeat(self.depth),
cs.get_type(),
self.ls.resolve(cs.get_label_unchecked()),
self.node,
cs.size(),
cs.height(),
)?;
if let Some(cs) = cs.children() {
let cs: Vec<_> = cs.into();
for n in cs {
Debug::fmt(
&Self {
ls: self.ls,
ns: self.ns,
node: n,
depth: self.depth + 1,
},
f,
)?;
}
}
Ok(())
}
}
#[allow(dead_code)]
fn make_stores<'a>() -> (LS<u16>, NS<Tree>) {
let label_store = LS::<u16> {
v: Default::default(),
phantom: PhantomData,
};
let compressed_node_store = NS::<Tree> { v: vec![] };
(label_store, compressed_node_store)
}
#[derive(PartialEq, Eq)]
pub struct Tree {
pub t: u8,
pub label: u16,
pub children: Vec<u16>,
pub size: u16,
pub height: u16,
}
impl crate::types::NodeStoreExt<Tree> for NS<Tree> {
fn build_then_insert(
&mut self,
_i: <Tree as crate::types::Stored>::TreeId,
t: <Tree as crate::types::Typed>::Type,
_l: Option<<Tree as crate::types::Labeled>::Label>,
cs: Vec<<Tree as Stored>::TreeId>,
) -> <Tree as Stored>::TreeId {
let node = Tree {
t,
label: 0,
children: cs,
size: 0,
height: 0,
};
self.get_or_insert(node)
}
}
impl crate::types::Typed for Tree {
type Type = u8;
fn get_type(&self) -> Self::Type {
self.t
}
}
impl crate::types::WithSerialization for Tree {
fn try_bytes_len(&self) -> Option<usize> {
todo!()
}
}
impl<T> crate::types::WithSerialization for TreeRef<'_, T> {
fn try_bytes_len(&self) -> Option<usize> {
todo!()
}
}
impl<T> Clone for TreeRef<'_, T> {
fn clone(&self) -> Self {
Self(self.0)
}
}
impl<T: crate::types::Typed> crate::types::Typed for TreeRef<'_, T> {
type Type = T::Type;
fn get_type(&self) -> Self::Type {
self.0.get_type()
}
}
impl crate::types::Labeled for Tree {
type Label = u16;
fn get_label_unchecked(&self) -> &Self::Label {
&self.label
}
fn try_get_label<'a>(&'a self) -> Option<&'a Self::Label> {
Some(self.get_label_unchecked())
}
}
impl<T: crate::types::Labeled> crate::types::Labeled for TreeRef<'_, T> {
type Label = T::Label;
fn get_label_unchecked(&self) -> &Self::Label {
self.0.get_label_unchecked()
}
fn try_get_label<'a>(&'a self) -> Option<&'a Self::Label> {
Some(self.get_label_unchecked())
}
}
impl crate::types::Node for Tree {}
impl<T: crate::types::Node> crate::types::Node for TreeRef<'_, T> {}
impl crate::types::Tree for Tree {
fn has_children(&self) -> bool {
self.children.len() > 0
}
fn has_label(&self) -> bool {
self.label != 0
}
}
impl crate::types::ErasedHolder for Tree {
fn unerase_ref<T: 'static + Send + Sync>(&self, tid: std::any::TypeId) -> Option<&T> {
todo!()
}
}
impl<'a, T> crate::types::ErasedHolder for TreeRef<'_, T> {
fn unerase_ref<TT: 'static + Send + Sync>(&self, tid: std::any::TypeId) -> Option<&TT> {
todo!()
}
}
impl<T: crate::types::Tree> crate::types::Tree for TreeRef<'_, T>
where
T::TreeId: Clone + NodeId<IdN = T::TreeId>,
{
fn has_children(&self) -> bool {
self.0.has_children()
}
fn has_label(&self) -> bool {
self.0.has_label()
}
}
impl crate::types::Stored for Tree {
type TreeId = u16;
}
impl<T: crate::types::Stored> crate::types::Stored for TreeRef<'_, T> {
type TreeId = T::TreeId;
}
impl WithChildren for Tree {
type ChildIdx = u8;
type Children<'a> = MySlice<Self::TreeId>;
fn child_count(&self) -> Self::ChildIdx {
self.children.len() as u8
}
fn child(&self, idx: &Self::ChildIdx) -> Option<Self::TreeId> {
self.children.get(idx.to_usize().unwrap()).map(|x| *x)
}
fn child_rev(&self, idx: &Self::ChildIdx) -> Option<Self::TreeId> {
let idx = num::CheckedSub::checked_sub(&self.child_count(), &(*idx + 1))?;
self.children.get(idx.to_usize().unwrap()).copied()
}
fn children(&self) -> Option<&Self::Children<'_>> {
Some(self.children.as_slice().into())
}
}
impl<T: WithChildren> WithChildren for TreeRef<'_, T>
where
T::TreeId: Clone + NodeId<IdN = T::TreeId>,
{
type ChildIdx = T::ChildIdx;
type Children<'a>
= T::Children<'a>
where
Self: 'a;
fn child_count(&self) -> Self::ChildIdx {
self.0.child_count()
}
fn child(&self, idx: &Self::ChildIdx) -> Option<Self::TreeId> {
self.0.child(idx)
}
fn child_rev(&self, idx: &Self::ChildIdx) -> Option<Self::TreeId> {
self.0.child_rev(idx)
}
fn children(&self) -> Option<&Self::Children<'_>> {
self.0.children()
}
}
impl WithStats for Tree {
fn size(&self) -> usize {
self.size.to_usize().unwrap()
}
fn height(&self) -> usize {
self.height.to_usize().unwrap()
}
fn line_count(&self) -> usize {
todo!()
}
}
impl<T: Stored + WithStats> WithStats for TreeRef<'_, T>
where
T::TreeId: Clone,
{
fn size(&self) -> usize {
self.0.size()
}
fn height(&self) -> usize {
self.0.height()
}
fn line_count(&self) -> usize {
self.0.line_count()
}
}
pub enum H {
S,
L,
}
impl HashKind for H {
fn structural() -> Self {
H::S
}
fn label() -> Self {
H::L
}
}
impl crate::types::WithHashs for Tree {
type HK = H;
type HP = u8;
fn hash(&self, _kind: &H) -> u8 {
0
}
}
impl<T: crate::types::WithHashs> crate::types::WithHashs for TreeRef<'_, T> {
type HK = T::HK;
type HP = T::HP;
fn hash(&self, kind: &Self::HK) -> Self::HP {
self.0.hash(kind)
}
}
pub struct NS<T> {
v: Vec<T>,
}
impl<T: crate::types::Tree> NodeStore<T::TreeId> for NS<T>
where
T::TreeId: ToPrimitive,
{
type R<'a>
= TreeRef<'a, T>
where
T: 'a;
fn resolve(&self, id: &T::TreeId) -> TreeRef<'_, T> {
TreeRef(&self.v[id.to_usize().unwrap()])
}
}
#[derive(PartialEq, Eq)]
pub struct TreeRef<'a, T>(&'a T);
impl<T: crate::types::Tree + Eq> NodeStoreMut<T> for NS<T>
where
T::TreeId: ToPrimitive + NumCast,
{
fn get_or_insert(&mut self, node: T) -> T::TreeId {
let p = self.v.iter().position(|x| node.eq(x));
if let Some(p) = p {
self.v[p] = node;
cast::<usize, T::TreeId>(p).unwrap()
} else {
self.v.push(node);
cast::<usize, T::TreeId>(self.v.len() - 1).unwrap()
}
}
}
impl<'a, T: 'a + WithChildren + Eq> NS<T>
where
T::TreeId: PrimInt,
{
fn get_or_insert(&mut self, node: T) -> T::TreeId {
if let Some(i) = self
.v
.iter()
.enumerate()
.find_map(|(i, x)| if x == &node { Some(i) } else { None })
{
cast(i).unwrap()
} else {
let l = self.v.len();
self.v.push(node);
cast(l).unwrap()
}
}
}
pub struct LS<I: PrimInt> {
v: Vec<crate::types::OwnedLabel>,
phantom: PhantomData<*const I>,
}
impl<'a, I: PrimInt> LabelStore<crate::types::SlicedLabel> for LS<I> {
type I = I;
fn get_or_insert<T: Borrow<crate::types::SlicedLabel>>(&mut self, node: T) -> Self::I {
let a = &mut self.v;
let b = a
.iter()
.enumerate()
.find_map(|(i, x)| if x.eq(node.borrow()) { Some(i) } else { None })
.to_owned();
if let Some(i) = b {
cast(i).unwrap()
} else {
let l = a.len();
a.push(node.borrow().to_owned());
cast(l).unwrap()
}
}
fn get<T: Borrow<crate::types::SlicedLabel>>(&self, node: T) -> Option<Self::I> {
let a = &self.v;
let b = a
.iter()
.enumerate()
.find_map(|(i, x)| if x.eq(node.borrow()) { Some(i) } else { None })
.to_owned();
b.map(|i| cast(i).unwrap())
}
fn resolve(&self, id: &Self::I) -> &crate::types::SlicedLabel {
&self.v[cast::<Self::I, usize>(*id).unwrap()]
}
}
#[allow(unused_macros)]
macro_rules! tree {
( $k:expr ) => {
SimpleTree::new($k, None, vec![])
};
( $k:expr, $l:expr) => {
SimpleTree::new($k, Some($l), vec![])
};
( $k:expr, $l:expr; [$($x:expr),+ $(,)?]) => {
SimpleTree::new($k, Some($l), vec![$($x),+])
};
( $k:expr; [$($x:expr),+ $(,)?]) => {
SimpleTree::new($k, None, vec![$($x),+])
};
}
pub struct TStore;
#[derive(Clone, Copy, std::hash::Hash, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "bevy_ecs", derive(bevy_ecs::prelude::Component))] pub struct Ty(u8);
impl Display for Ty {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
todo!()
}
}
impl HyperType for Ty {
fn as_shared(&self) -> crate::types::Shared {
todo!()
}
fn as_any(&self) -> &dyn std::any::Any {
todo!()
}
fn as_static(&self) -> &'static dyn HyperType {
todo!()
}
fn as_static_str(&self) -> &'static str {
todo!()
}
fn generic_eq(&self, other: &dyn HyperType) -> bool
where
Self: 'static + Sized,
{
todo!()
}
fn is_file(&self) -> bool {
todo!()
}
fn is_directory(&self) -> bool {
todo!()
}
fn is_spaces(&self) -> bool {
todo!()
}
fn is_syntax(&self) -> bool {
todo!()
}
fn is_hidden(&self) -> bool {
todo!()
}
fn is_named(&self) -> bool {
todo!()
}
fn is_supertype(&self) -> bool {
todo!()
}
fn get_lang(&self) -> crate::types::LangWrapper<Self>
where
Self: Sized,
{
todo!()
}
fn lang_ref(&self) -> crate::types::LangWrapper<crate::types::AnyType> {
todo!()
}
}
impl crate::types::TypeStore for TStore {
type Ty = self::Ty;
}