pub mod error;
pub mod into;
pub mod parser;
pub mod path;
use error::KeyTreeErr;
use path::{UniquePath, NonUniquePath};
use std::collections::{BTreeMap, HashMap};
use std::collections::btree_map::Range;
use core::fmt;
use core::fmt::{Debug, Display};
use core::iter::Peekable;
use core::ops::Index;
use core::ops::Bound::Included;
#[derive(Clone, Copy, Debug)]
enum Token {
Key(Key),
Value(Value),
}
impl Token {
fn start_key(&self) -> usize {
match self {
Token::Key(k) => k.start_key,
Token::Value(kv) => kv.start_key,
}
}
}
impl Display for Token {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Key(k) => {
write!(f, "({}, {})", k.start_key, k.end_key)
},
Self::Value(v) => {
write!(f, "({}, {}):({}, {})", v.start_key, v.end_key, v.start_val, v.end_val)
},
}
}
}
#[derive(Clone, Copy, Debug)]
struct Key {
start_key: usize,
end_key: usize,
}
impl Key {
fn new(sk: usize, ek: usize) -> Self {
Key {
start_key: sk,
end_key: ek,
}
}
}
#[derive(Clone, Copy, Debug)]
struct Value {
start_key: usize,
end_key: usize,
start_val: usize,
end_val: usize,
}
impl Value {
fn new(sk: usize, ek: usize, sv: usize, ev: usize) -> Self {
Value {
start_key: sk,
end_key: ek,
start_val: sv,
end_val: ev,
}
}
}
struct Tokens(Vec<Token>);
impl Tokens {
fn new() -> Self {
Tokens(Vec::new())
}
fn push(&mut self, token: Token) {
self.0.push(token)
}
fn len(&self) -> usize {
self.0.len()
}
}
impl Index<usize> for Tokens {
type Output = Token;
fn index(&self, i: usize) -> &Self::Output {
&(self.0)[i]
}
}
impl fmt::Debug for Tokens {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut s = String::from("Tokens: ");
for tok in &self.0 {
s.push_str(&tok.to_string());
s.push_str(", ");
};
s.pop();
s.pop();
write!(f, "{:?}", s)
}
}
#[derive(Clone, Copy)]
struct TokenIndex((usize, Option<usize>));
impl TokenIndex {
fn new(start: usize) -> Self {
TokenIndex((start, None))
}
fn start(&self) -> usize {
(self.0).0
}
fn end(&self) -> usize {
(self.0).1.unwrap()
}
fn set_end(&mut self, i: usize) {
(self.0).1 = Some(i);
}
}
impl fmt::Display for TokenIndex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match (self.0).1 {
Some(_) => write!(f, "({}, {})", self.start(), self.end()),
None => write!(f, "({}, _)", self.start()),
}
}
}
impl fmt::Debug for TokenIndex{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.to_string())
}
}
#[derive(Debug)]
struct EachIndent(Vec<UniquePath>);
impl EachIndent {
fn push(&mut self, path: &UniquePath) {
self.0.push(path.clone())
}
fn new() -> Self {
EachIndent(Vec::new())
}
fn new_index(&self, path: &UniquePath, indent: usize) -> usize {
let max_indent = self.0.len() - 1;
if indent <= max_indent && path.eq_base(&self.0[indent]) {
self.0[indent].last_index() + 1
} else {
0
}
}
fn insert(&mut self, path: &UniquePath, indent: usize) {
if self.0.is_empty() {
self.0.push(path.clone())
} else if indent <= self.0.len() - 1 {
self.0[indent] = path.clone();
} else {
self.0.push(path.clone())
}
}
fn len(&self) -> usize {
self.0.len()
}
}
impl Index<usize> for EachIndent {
type Output = UniquePath;
fn index(&self, index: usize) -> &Self::Output {
&self.0[index]
}
}
struct KeyMap(BTreeMap<UniquePath, TokenIndex>);
impl KeyMap {
fn new() -> Self {
let bt: BTreeMap<UniquePath, TokenIndex> = BTreeMap::new();
KeyMap(bt)
}
fn get(&self, path: &UniquePath) -> Option<TokenIndex> {
self.0.get(path).map(|tok_ix| *tok_ix)
}
fn set_end(&mut self, path: &UniquePath, end: usize) {
let token_index = self.0.get_mut(path).unwrap();
token_index.set_end(end);
}
fn insert(&mut self, path: &UniquePath, start: usize) {
self.0.insert(path.clone(), TokenIndex::new(start));
}
pub fn len(&self) -> usize {
self.0.len()
}
}
impl Debug for KeyMap {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut s = String::with_capacity(self.len() * 40);
s.push_str("KeyMap:\n");
for (key, value) in self.0.iter() {
s.push_str(&format!("{:?}:{}\n", key, value));
};
s.pop();
write!(f, "{}", s)
}
}
#[derive(Clone, Debug)]
enum Context<'a> {
Unique(Peekable<Range<'a, UniquePath, TokenIndex>>),
Iter(Peekable<Range<'a, UniquePath, TokenIndex>>),
EmptyIter(NonUniquePath),
}
#[derive(Clone, Debug)]
pub struct KeyTree<'a> {
keytree_core: &'a KeyTreeCore<'a>,
context: Context<'a>,
}
impl<'a> KeyTree<'a> {
pub fn from_core(keytree_core: &'a KeyTreeCore) -> Self {
KeyTree {
keytree_core: keytree_core,
context: keytree_core.iter(keytree_core.root.clone().non_unique()),
}
}
pub fn at<T>(&self, path: &str) -> T
where
KeyTree<'a>: Into<T>
{
let local_path = match NonUniquePath::from(path) {
Ok(path) => path,
Err(_) => { KeyTreeErr::parse_keytree(); unreachable!() },
};
let global_path = match &self.context {
Context::Unique(iter) | Context::Iter(iter) => {
iter.clone()
.peek()
.unwrap()
.0
.clone()
.append_non_unique(&local_path.tail())
},
Context::EmptyIter(_) => {
KeyTreeErr::not_unique_but_empty();
unreachable!();
},
};
KeyTree {
keytree_core: &self.keytree_core,
context: self.keytree_core.iter(global_path),
}.into()
}
pub fn op<T>(&self, path: &str) -> Option<T>
where
KeyTree<'a>: Into<T>
{
let local_path = match NonUniquePath::from(path) {
Ok(path) => path,
Err(_) => { KeyTreeErr::parse_keytree(); unreachable!() },
};
let global_path = match &self.context {
Context::Unique(iter) | Context::Iter(iter) => {
iter.clone()
.peek()
.unwrap()
.0
.clone()
.append_non_unique(&local_path.tail())
},
Context::EmptyIter(_) => {
KeyTreeErr::not_unique_but_empty();
unreachable!();
},
};
let context = self.keytree_core.iter(global_path);
match context {
Context::EmptyIter(_) => None,
_ => {
Some(
KeyTree {
keytree_core: &self.keytree_core,
context: context,
}.into()
)
}
}
}
pub fn value(&mut self) -> Option<&str> {
match &self.context {
Context::Unique(iter) => {
let tok_ix = iter.clone()
.peek()
.unwrap()
.1
.end();
let token = self
.keytree_core
.tokens[tok_ix];
match token {
Token::Value(tok) => Some(&self.keytree_core.s[tok.start_val..=tok.end_val]),
Token::Key(_) => { panic!("Should not be reachable.") },
}
},
Context::Iter(_) => { KeyTreeErr::not_unique(); unreachable!() },
Context::EmptyIter(_) => None,
}
}
}
impl<'a> Iterator for KeyTree<'a> {
type Item = KeyTree<'a>;
fn next(&mut self) -> Option<Self::Item> {
match self.context {
Context::Iter(ref mut context) | Context::Unique(ref mut context) => {
match context.next() {
Some((path, _)) => {
let iter = self
.keytree_core.keymap.0
.range((Included(path), Included(path)))
.peekable();
Some(
KeyTree {
keytree_core: &self.keytree_core,
context: Context::Unique(iter),
}
)
},
None => None,
}
},
Context::EmptyIter(_) => {
panic!("Should not call next() on KeyTree with Context::EmptyIter(_)");
},
}
}
}
pub struct KeyTreeCore<'a> {
s: &'a str,
keymap: KeyMap,
keylen: KeyLen,
tokens: Tokens,
root: UniquePath,
}
impl<'a> KeyTreeCore<'a> {
fn iter(&self, global_path: NonUniquePath) -> Context {
match self.keylen.0.get(&global_path) {
Some(max) => {
let start_path = global_path.clone().unique(0);
let end_path = global_path.clone().unique(*max);
let iter = self
.keymap.0
.range((Included(start_path), Included(end_path)))
.peekable();
if *max == 0 {
Context::Unique(iter)
} else {
Context::Iter(iter)
}
},
None => {
Context::EmptyIter(global_path)
},
}
}
}
impl<'a> fmt::Debug for KeyTreeCore<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}\n{:?}\n{:?}\n{:?}", self.s, self.tokens, self.keymap, self.keylen)
}
}
struct KeyLen(HashMap<NonUniquePath, usize>);
impl KeyLen {
fn new() -> Self {
KeyLen(HashMap::new())
}
fn get(&self, path: &NonUniquePath) -> Option<usize> {
match self.0.get(path) {
Some(path) => Some(*path),
None => None,
}
}
fn insert(&mut self, path: &UniquePath) {
self.0.insert(path.clone().non_unique(), path.last_index());
}
}
impl<'a> fmt::Debug for KeyLen {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut s = String::from("Keylen: \n");
for (key, value) in self.0.iter() {
s.push_str(&format!("{:?}: {:?}\n", key, value));
};
write!(f, "{}", s)
}
}