74 lines
1.9 KiB
Rust
74 lines
1.9 KiB
Rust
use std::borrow::Borrow;
|
|
use std::cell::RefCell;
|
|
use std::fmt::Debug;
|
|
use std::hash::Hash;
|
|
use std::rc::{Rc, Weak};
|
|
|
|
use hashbrown::HashMap;
|
|
use orchid_api_traits::Coding;
|
|
use orchid_base::interner::{IStr, IStrHandle, IStrv, IStrvHandle};
|
|
|
|
use crate::api;
|
|
|
|
trait Branch: 'static {
|
|
type Token: Clone + Copy + Debug + Hash + PartialEq + Eq + PartialOrd + Ord + Coding + 'static;
|
|
type Data: 'static + Borrow<Self::Borrow>;
|
|
type Borrow: ToOwned<Owned = Self::Data> + ?Sized;
|
|
type Handle: AsRef<Self::Borrow>;
|
|
type Interned: Clone;
|
|
fn mk_interned(t: Self::Token, h: Rc<Self::Handle>) -> Self::Interned;
|
|
}
|
|
|
|
struct StrBranch;
|
|
impl Branch for StrBranch {
|
|
type Data = String;
|
|
type Token = api::TStr;
|
|
type Borrow = str;
|
|
type Handle = Handle<Self>;
|
|
type Interned = IStr;
|
|
fn mk_interned(t: Self::Token, h: Rc<Self::Handle>) -> Self::Interned { IStr(t, h) }
|
|
}
|
|
struct StrvBranch;
|
|
impl Branch for StrvBranch {
|
|
type Data = Vec<IStr>;
|
|
type Token = api::TStrv;
|
|
type Borrow = [IStr];
|
|
type Handle = Handle<Self>;
|
|
type Interned = IStrv;
|
|
fn mk_interned(t: Self::Token, h: Rc<Self::Handle>) -> Self::Interned { IStrv(t, h) }
|
|
}
|
|
|
|
struct Data<B: Branch> {
|
|
token: B::Token,
|
|
data: Rc<B::Data>,
|
|
}
|
|
|
|
struct Handle<B: Branch> {
|
|
data: Rc<Data<B>>,
|
|
parent: Weak<RefCell<IntData<B>>>,
|
|
}
|
|
impl IStrHandle for Handle<StrBranch> {}
|
|
impl AsRef<str> for Handle<StrBranch> {
|
|
fn as_ref(&self) -> &str { self.data.data.as_ref().as_ref() }
|
|
}
|
|
impl IStrvHandle for Handle<StrvBranch> {}
|
|
impl AsRef<[IStr]> for Handle<StrvBranch> {
|
|
fn as_ref(&self) -> &[IStr] { self.data.data.as_ref().as_ref() }
|
|
}
|
|
|
|
struct Rec<B: Branch> {
|
|
handle: Weak<B::Handle>,
|
|
data: Rc<Data<B>>,
|
|
}
|
|
|
|
struct IntData<B: Branch> {
|
|
by_tok: HashMap<B::Token, Rec<B>>,
|
|
by_data: HashMap<Rc<B::Data>, Rec<B>>,
|
|
}
|
|
impl<B: Branch> IntData<B> {
|
|
async fn i(&mut self, q: &B::Borrow) -> B::Interned { todo!() }
|
|
async fn e(&mut self, q: &B::Token) -> B::Interned { todo!() }
|
|
}
|
|
|
|
struct Int<B: Branch>(Rc<RefCell<IntData<B>>>);
|