#[allow(unused)] use crate::SelectionMsg;
use kas::Id;
use kas::cast::Cast;
use kas::event::{ConfigCx, EventCx};
#[allow(unused)] use kas::{Events, Widget};
use std::borrow::Borrow;
use std::fmt::Debug;
use std::ops::Range;
mod generator;
pub use generator::*;
#[derive(Debug, Default)]
pub struct Token<K, I> {
pub key: K,
pub item: I,
}
impl<K, I> Token<K, I> {
#[inline]
pub fn new(key: K, item: I) -> Self {
Token { key, item }
}
}
impl<K, I> Borrow<K> for Token<K, I> {
fn borrow(&self) -> &K {
&self.key
}
}
pub trait Key: Clone + Debug + Default + PartialEq + Eq + 'static {
fn make_id(&self, parent: &Id) -> Id;
fn reconstruct_key(parent: &Id, child: &Id) -> Option<Self>;
}
impl Key for () {
fn make_id(&self, parent: &Id) -> Id {
parent.make_child(0)
}
fn reconstruct_key(parent: &Id, child: &Id) -> Option<Self> {
if child.next_key_after(parent) == Some(0) {
Some(())
} else {
None
}
}
}
macro_rules! impl_1D {
($t:ty) => {
impl Key for $t {
fn make_id(&self, parent: &Id) -> Id {
parent.make_child((*self).cast())
}
fn reconstruct_key(parent: &Id, child: &Id) -> Option<Self> {
child.next_key_after(parent).map(|i| i.cast())
}
}
};
}
impl_1D!(usize);
impl_1D!(u32);
#[cfg(target_pointer_width = "64")]
impl_1D!(u64);
macro_rules! impl_2D {
($t:ty) => {
impl Key for ($t, $t) {
fn make_id(&self, parent: &Id) -> Id {
parent.make_child(self.0.cast()).make_child(self.1.cast())
}
fn reconstruct_key(parent: &Id, child: &Id) -> Option<Self> {
let mut iter = child.iter_keys_after(parent);
let col = iter.next().map(|i| i.cast());
let row = iter.next().map(|i| i.cast());
col.zip(row)
}
}
};
}
impl_2D!(usize);
impl_2D!(u32);
#[cfg(target_pointer_width = "64")]
impl_2D!(u64);
#[derive(Clone, Debug, PartialEq, Eq)]
#[must_use]
pub enum Changes<Index> {
None,
NoPreparedItems,
Range(Range<Index>),
Any,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[must_use]
pub enum TokenChanges {
None,
SameKey,
Any,
}
impl TokenChanges {
pub(crate) fn key(self) -> bool {
self == TokenChanges::Any
}
pub(crate) fn item(self) -> bool {
self != TokenChanges::None
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Len<Index> {
Known(Index),
LBound(Index),
}
impl<Index: Copy> Len<Index> {
#[inline]
pub fn len(&self) -> Index {
match self {
Len::Known(len) => *len,
Len::LBound(len) => *len,
}
}
#[inline]
pub fn is_known(&self) -> bool {
matches!(self, Len::Known(_))
}
}
pub trait Clerk<Index> {
type Data;
type Item;
fn len(&self, data: &Self::Data, lbound: Index) -> Len<Index>;
fn mock_item(&self, data: &Self::Data) -> Option<Self::Item> {
let _ = data;
None
}
}
pub trait AsyncClerk<Index>: Clerk<Index> {
type Key: Key;
fn update(
&mut self,
cx: &mut ConfigCx,
id: Id,
view_range: Range<Index>,
data: &Self::Data,
) -> Changes<Index>;
fn prepare_range(
&mut self,
cx: &mut ConfigCx,
id: Id,
view_range: Range<Index>,
data: &Self::Data,
range: Range<Index>,
) {
let _ = (cx, id, view_range, data, range);
}
fn handle_messages(
&mut self,
cx: &mut EventCx,
id: Id,
view_range: Range<Index>,
data: &Self::Data,
opt_key: Option<Self::Key>,
) -> Changes<Index> {
let _ = (cx, id, view_range, data, opt_key);
Changes::None
}
}
pub trait TokenClerk<Index>: AsyncClerk<Index> {
type Token: Borrow<Self::Key>;
fn update_token(
&self,
data: &Self::Data,
index: Index,
update_item: bool,
token: &mut Option<Self::Token>,
) -> TokenChanges;
fn item<'r>(&'r self, data: &'r Self::Data, token: &'r Self::Token) -> &'r Self::Item;
}
pub fn update_token<Key: PartialEq>(
key: Option<Key>,
update_item: bool,
token: &mut Option<Key>,
) -> TokenChanges {
if *token == key {
if update_item {
TokenChanges::SameKey
} else {
TokenChanges::None
}
} else {
*token = key;
TokenChanges::Any
}
}