use std::{fmt::Debug,
ops::{Deref, DerefMut}};
use super::sizing;
use crate::{idx, Index, RingBuffer as _};
#[derive(Clone, Copy, PartialEq, Debug, Default)]
pub struct CurIndex(pub Option<Index>);
mod construct {}
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum CurIndexLoc {
EmptyHistory,
Start,
End(Index),
Middle(Index),
}
impl CurIndexLoc {
pub fn locate(cur_index: &CurIndex, versions: &sizing::HistoryBuffer) -> CurIndexLoc {
if versions.is_empty() {
return CurIndexLoc::EmptyHistory;
}
match cur_index.0 {
None => {
CurIndexLoc::Start
}
Some(inner) => {
if inner == versions.len().convert_to_index() {
CurIndexLoc::End(inner)
} else {
CurIndexLoc::Middle(inner)
}
}
}
}
pub fn inc(cur_index: &mut CurIndex, versions: &sizing::HistoryBuffer) {
match Self::locate(cur_index, versions) {
Self::EmptyHistory => {
}
Self::End(_) => {
}
Self::Start => {
cur_index.0 = Some(idx(0));
}
Self::Middle(_) => {
if let Some(index) = cur_index.0 {
cur_index.0 = Some(index + idx(1));
}
}
}
}
pub fn dec(cur_index: &mut CurIndex, versions: &sizing::HistoryBuffer) {
match Self::locate(cur_index, versions) {
Self::EmptyHistory => {
}
Self::Start => {
cur_index.0 = None;
}
Self::End(_) | Self::Middle(_) => {
if let Some(index) = cur_index.0 {
if index > idx(0) {
cur_index.0 = Some(index - idx(1));
} else {
cur_index.0 = None;
}
}
}
}
}
}
impl CurIndex {
pub fn as_index(self) -> Index { self.0.unwrap_or(idx(0)) }
pub fn clear(&mut self) { self.0 = None; }
}
mod ops {
use super::*;
impl Deref for CurIndex {
type Target = Option<Index>;
fn deref(&self) -> &Self::Target { &self.0 }
}
impl DerefMut for CurIndex {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}
}
mod convert {
use super::*;
impl From<usize> for CurIndex {
fn from(val: usize) -> Self { CurIndex(Some(Index(val.into()))) }
}
impl From<isize> for CurIndex {
fn from(val: isize) -> Self { CurIndex(Some(Index(val.into()))) }
}
impl From<i32> for CurIndex {
fn from(val: i32) -> Self { CurIndex(Some(Index(val.into()))) }
}
impl From<i16> for CurIndex {
fn from(val: i16) -> Self { CurIndex(Some(Index(val.into()))) }
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::EditorContent;
#[test]
fn test_cur_index_locate_empty() {
let versions = sizing::HistoryBuffer::new();
let cur_index = CurIndex::default();
assert_eq!(
CurIndexLoc::locate(&cur_index, &versions),
CurIndexLoc::EmptyHistory
);
}
#[test]
fn test_cur_index_locate_start() {
let mut versions = sizing::HistoryBuffer::new();
versions.add(EditorContent::default());
let cur_index = CurIndex::default();
assert_eq!(
CurIndexLoc::locate(&cur_index, &versions),
CurIndexLoc::Start
);
}
#[test]
fn test_cur_index_locate_end() {
let mut versions = sizing::HistoryBuffer::new();
versions.add(EditorContent::default());
let cur_index = CurIndex::from(0);
assert_eq!(
CurIndexLoc::locate(&cur_index, &versions),
CurIndexLoc::End(cur_index.as_index())
);
}
#[test]
fn test_cur_index_locate_middle() {
let mut versions = sizing::HistoryBuffer::new();
versions.add(EditorContent::default());
versions.add(EditorContent::default());
let cur_index = CurIndex::from(0);
assert_eq!(
CurIndexLoc::locate(&cur_index, &versions),
CurIndexLoc::Middle(cur_index.as_index())
);
}
}