use core::{convert::Infallible, iter::Fuse};
use serde::Serialize;
use crate::{DescendError, Internal, KeyError, Schema};
pub trait Key {
fn find(&self, internal: &Internal) -> Option<usize>;
}
impl<T: Key + ?Sized> Key for &T {
fn find(&self, internal: &Internal) -> Option<usize> {
(**self).find(internal)
}
}
impl<T: Key + ?Sized> Key for &mut T {
fn find(&self, internal: &Internal) -> Option<usize> {
(**self).find(internal)
}
}
pub trait Keys {
fn next(&mut self, internal: &Internal) -> Result<usize, KeyError>;
fn finalize(&mut self) -> Result<(), KeyError>;
fn chain<U: IntoKeys>(self, other: U) -> Chain<Self, U::IntoKeys>
where
Self: Sized,
{
Chain(self, other.into_keys())
}
fn track(self) -> Track<Self>
where
Self: Sized,
{
Track {
inner: self,
depth: 0,
}
}
fn short(self) -> Short<Self>
where
Self: Sized,
{
Short {
inner: self,
leaf: false,
}
}
}
impl<T: Keys + ?Sized> Keys for &mut T {
fn next(&mut self, internal: &Internal) -> Result<usize, KeyError> {
(**self).next(internal)
}
fn finalize(&mut self) -> Result<(), KeyError> {
(**self).finalize()
}
}
pub trait IntoKeys {
type IntoKeys: Keys;
fn into_keys(self) -> Self::IntoKeys;
}
pub trait Transcode {
type Error;
fn transcode(
&mut self,
schema: &Schema,
keys: impl IntoKeys,
) -> Result<(), DescendError<Self::Error>>;
}
impl<T: Transcode + ?Sized> Transcode for &mut T {
type Error = T::Error;
fn transcode(
&mut self,
schema: &Schema,
keys: impl IntoKeys,
) -> Result<(), DescendError<Self::Error>> {
(**self).transcode(schema, keys)
}
}
#[derive(Clone, Debug, Default, PartialEq, PartialOrd, Hash, Serialize)]
pub struct Short<K> {
inner: K,
leaf: bool,
}
impl<K> Short<K> {
pub fn new(inner: K) -> Self {
Self { inner, leaf: false }
}
pub fn leaf(&self) -> bool {
self.leaf
}
pub fn inner(&self) -> &K {
&self.inner
}
pub fn into_inner(self) -> (K, bool) {
(self.inner, self.leaf)
}
}
impl<K: Keys> IntoKeys for &mut Short<K> {
type IntoKeys = Self;
fn into_keys(self) -> Self::IntoKeys {
self.leaf = false;
self
}
}
impl<K: Keys> Keys for Short<K> {
fn next(&mut self, internal: &Internal) -> Result<usize, KeyError> {
self.inner.next(internal)
}
fn finalize(&mut self) -> Result<(), KeyError> {
self.inner.finalize()?;
self.leaf = true;
Ok(())
}
}
impl<T: Transcode> Transcode for Short<T> {
type Error = T::Error;
fn transcode(
&mut self,
schema: &Schema,
keys: impl IntoKeys,
) -> Result<(), DescendError<Self::Error>> {
self.leaf = false;
match self.inner.transcode(schema, keys) {
Err(DescendError::Key(KeyError::TooShort)) => Ok(()),
Ok(()) | Err(DescendError::Key(KeyError::TooLong)) => {
self.leaf = true;
Ok(())
}
ret => ret,
}
}
}
#[derive(Clone, Debug, Default, PartialEq, PartialOrd, Hash, Serialize)]
pub struct Track<K> {
inner: K,
depth: usize,
}
impl<K> Track<K> {
pub fn new(inner: K) -> Self {
Self { inner, depth: 0 }
}
pub fn depth(&self) -> usize {
self.depth
}
pub fn inner(&self) -> &K {
&self.inner
}
pub fn into_inner(self) -> (K, usize) {
(self.inner, self.depth)
}
}
impl<K: Keys> IntoKeys for &mut Track<K> {
type IntoKeys = Self;
fn into_keys(self) -> Self::IntoKeys {
self.depth = 0;
self
}
}
impl<K: Keys> Keys for Track<K> {
fn next(&mut self, internal: &Internal) -> Result<usize, KeyError> {
let k = self.inner.next(internal);
if k.is_ok() {
self.depth += 1;
}
k
}
fn finalize(&mut self) -> Result<(), KeyError> {
self.inner.finalize()
}
}
impl<T: Transcode> Transcode for Track<T> {
type Error = T::Error;
fn transcode(
&mut self,
schema: &Schema,
keys: impl IntoKeys,
) -> Result<(), DescendError<Self::Error>> {
self.depth = 0;
let mut tracked = keys.into_keys().track();
let ret = self.inner.transcode(schema, &mut tracked);
self.depth = tracked.depth;
ret
}
}
impl Transcode for () {
type Error = Infallible;
fn transcode(
&mut self,
schema: &Schema,
keys: impl IntoKeys,
) -> Result<(), DescendError<Self::Error>> {
schema.descend(keys.into_keys(), |_, _| Ok(()))
}
}
#[derive(Debug, Clone)]
#[repr(transparent)]
pub struct KeysIter<T>(Fuse<T>);
impl<T: Iterator> KeysIter<T> {
fn new(inner: T) -> Self {
Self(inner.fuse())
}
}
impl<T> Keys for KeysIter<T>
where
T: Iterator,
T::Item: Key,
{
fn next(&mut self, internal: &Internal) -> Result<usize, KeyError> {
let n = self.0.next().ok_or(KeyError::TooShort)?;
n.find(internal).ok_or(KeyError::NotFound)
}
fn finalize(&mut self) -> Result<(), KeyError> {
match self.0.next() {
Some(_) => Err(KeyError::TooLong),
None => Ok(()),
}
}
}
impl<T> IntoKeys for T
where
T: IntoIterator,
<T::IntoIter as Iterator>::Item: Key,
{
type IntoKeys = KeysIter<T::IntoIter>;
fn into_keys(self) -> Self::IntoKeys {
KeysIter::new(self.into_iter())
}
}
impl<T> IntoKeys for KeysIter<T>
where
T: Iterator,
T::Item: Key,
{
type IntoKeys = KeysIter<T>;
fn into_keys(self) -> Self::IntoKeys {
self
}
}
pub struct Chain<T, U>(T, U);
impl<T: Keys, U: Keys> Keys for Chain<T, U> {
fn next(&mut self, internal: &Internal) -> Result<usize, KeyError> {
match self.0.next(internal) {
Err(KeyError::TooShort) => self.1.next(internal),
ret => ret,
}
}
fn finalize(&mut self) -> Result<(), KeyError> {
self.0.finalize().and_then(|_| self.1.finalize())
}
}
impl<T: Keys, U: Keys> IntoKeys for Chain<T, U> {
type IntoKeys = Self;
fn into_keys(self) -> Self::IntoKeys {
self
}
}