use crate::full;
use crate::{EmptyHistoryError, Select};
use std::collections::TryReserveError;
use std::ops::RangeBounds;
mod docs_impl;
#[doc(hidden)]
pub use docs_impl::__Prefixed;
pub trait IntoScoped {
type Scope;
type Ignored;
fn into_scoped(self) -> (Self::Scope, Self::Ignored);
fn from_scoped(scope: Self::Scope, ignored: Self::Ignored) -> Self;
}
pub trait AsThinScoped: IntoScoped {
type ThinScoped<'this>;
fn as_thin_scoped<'a>(
scope: &'a Self::Scope,
ignored: &'a Self::Ignored,
) -> Self::ThinScoped<'a>;
}
pub trait AsThinScopedMut: AsThinScoped {
type ThinScopedMut<'this>;
fn as_thin_scoped_mut<'a>(
scope: &'a mut Self::Scope,
ignored: &'a mut Self::Ignored,
) -> Self::ThinScopedMut<'a>;
}
#[derive(Debug, PartialEq, Eq)]
pub struct Snaplog<T: IntoScoped> {
full: full::Snaplog<T::Scope>,
ignored: T::Ignored,
}
impl<T: IntoScoped> Snaplog<T> {
pub fn new(initial: T) -> Self {
let (scope, ignored) = initial.into_scoped();
Self {
full: full::Snaplog::new(scope),
ignored,
}
}
pub fn try_from_vec(
history: Vec<T::Scope>,
ignored: T::Ignored,
) -> Result<Self, EmptyHistoryError> {
Ok(Self {
full: full::Snaplog::try_from_vec(history)?,
ignored,
})
}
pub fn from_vec(history: Vec<T::Scope>, ignored: T::Ignored) -> Self {
match Self::try_from_vec(history, ignored) {
Ok(this) => this,
Err(_) => panic!("history must not be empty"),
}
}
pub fn try_from_history<I>(history: I, ignored: T::Ignored) -> Result<Self, EmptyHistoryError>
where
I: IntoIterator<Item = T::Scope>,
{
Self::try_from_vec(history.into_iter().collect(), ignored)
}
pub fn from_history<I>(history: I, ignored: T::Ignored) -> Self
where
I: IntoIterator<Item = T::Scope>,
{
Self::from_vec(history.into_iter().collect(), ignored)
}
}
impl<T: IntoScoped> Snaplog<T> {
pub fn scope(&self) -> &full::Snaplog<T::Scope> {
&self.full
}
pub fn scope_mut(&mut self) -> &mut full::Snaplog<T::Scope> {
&mut self.full
}
pub fn ignored(&self) -> &T::Ignored {
&self.ignored
}
pub fn into_scope(self) -> full::Snaplog<T::Scope> {
self.full
}
}
impl<T: IntoScoped> Snaplog<T> {
pub fn record(&mut self, snapshot: T::Scope) {
self.full.record(snapshot);
}
pub fn record_all<I>(&mut self, snapshots: I)
where
I: IntoIterator<Item = T::Scope>,
{
self.full.record_all(snapshots);
}
pub fn record_change<F>(&mut self, f: F)
where
F: FnMut(&T::Scope) -> T::Scope,
{
self.full.record_change(f)
}
pub fn try_record_change<F, E>(&mut self, f: F) -> Result<(), E>
where
F: FnMut(&T::Scope) -> Result<T::Scope, E>,
{
self.full.try_record_change(f)
}
pub fn record_changes_all<F, M>(&mut self, mutations: &mut [M], f: F)
where
F: FnMut(&mut M, &T::Scope) -> T::Scope,
{
self.full.record_changes_all(mutations, f);
}
pub fn has_changes(&self) -> bool {
self.full.has_changes()
}
pub fn initial(&self) -> &T::Scope {
self.full.initial()
}
pub fn snapshot_at(&self, select: Select) -> &T::Scope {
self.full.snapshot_at(select)
}
pub fn current(&self) -> &T::Scope {
self.full.current()
}
pub fn initial_mut(&mut self) -> &mut T::Scope {
self.full.initial_mut()
}
pub fn snapshot_at_mut(&mut self, select: Select) -> &mut T::Scope {
self.full.snapshot_at_mut(select)
}
pub fn current_mut(&mut self) -> &mut T::Scope {
self.full.current_mut()
}
pub fn clone_snapshot_at(&self, select: Select) -> T
where
T::Scope: Clone,
T::Ignored: Clone,
{
T::from_scoped(self.snapshot_at(select).clone(), self.ignored.clone())
}
pub fn history(&self) -> &[T::Scope] {
self.full.history()
}
pub fn history_mut(&mut self) -> &mut [T::Scope] {
self.full.history_mut()
}
pub fn drain<'r, R>(&'r mut self, range: R) -> impl Iterator<Item = T::Scope> + 'r
where
R: RangeBounds<usize> + 'r,
{
self.full.drain(range)
}
pub fn clear_history(&mut self) {
self.full.clear_history();
}
pub fn reset(&mut self) {
self.full.reset();
}
pub fn reserve(&mut self, n: usize) {
self.full.reserve(n);
}
pub fn try_reserve(&mut self, n: usize) -> Result<(), TryReserveError> {
self.full.try_reserve(n)
}
pub fn iter(&self) -> Iter<'_, T> {
self.into_iter()
}
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
self.into_iter()
}
pub fn into_initial(self) -> T {
T::from_scoped(self.full.into_initial(), self.ignored)
}
pub fn into_current(self) -> T {
T::from_scoped(self.full.into_current(), self.ignored)
}
pub fn into_snapshot_at(self, select: Select) -> T {
T::from_scoped(self.full.into_snapshot_at(select), self.ignored)
}
pub fn into_inner(self) -> (full::Snaplog<T::Scope>, T::Ignored) {
(self.full, self.ignored)
}
}
impl<T: IntoScoped> Snaplog<T> {
pub fn thin_snapshot_at(&self, select: Select) -> T::ThinScoped<'_>
where
T: AsThinScoped,
{
T::as_thin_scoped(self.snapshot_at(select), &self.ignored)
}
pub fn thin_snapshot_at_mut(&mut self, select: Select) -> T::ThinScopedMut<'_>
where
T: AsThinScopedMut,
{
T::as_thin_scoped_mut(self.full.snapshot_at_mut(select), &mut self.ignored)
}
}
impl<T: IntoScoped> Snaplog<T> {
pub unsafe fn from_vec_unchecked(history: Vec<T::Scope>, ignored: T::Ignored) -> Self {
Self {
full: unsafe { full::Snaplog::from_vec_unchecked(history) },
ignored,
}
}
pub unsafe fn from_history_unchecked<I>(history: I, ignored: T::Ignored) -> Self
where
I: IntoIterator<Item = T::Scope>,
{
unsafe { Self::from_vec_unchecked(history.into_iter().collect(), ignored) }
}
pub unsafe fn history_mut_vec(&mut self) -> &mut Vec<T::Scope> {
unsafe { self.full.history_mut_vec() }
}
pub unsafe fn ignored_mut(&mut self) -> &mut T::Ignored {
&mut self.ignored
}
}
impl<T: IntoScoped> Clone for Snaplog<T>
where
T::Scope: Clone,
T::Ignored: Clone,
{
fn clone(&self) -> Self {
Self {
full: self.full.clone(),
ignored: self.ignored.clone(),
}
}
fn clone_from(&mut self, source: &Self) {
self.full.clone_from(&source.full);
self.ignored.clone_from(&source.ignored);
}
}
impl<T: IntoScoped> std::ops::Index<Select> for Snaplog<T> {
type Output = T::Scope;
fn index(&self, index: Select) -> &Self::Output {
self.snapshot_at(index)
}
}
impl<T: IntoScoped> std::ops::IndexMut<Select> for Snaplog<T> {
fn index_mut(&mut self, index: Select) -> &mut Self::Output {
self.snapshot_at_mut(index)
}
}
impl<T: IntoScoped> std::iter::Extend<T::Scope> for Snaplog<T> {
fn extend<I: IntoIterator<Item = T::Scope>>(&mut self, iter: I) {
self.full.extend(iter);
}
}
#[derive(Debug)]
pub struct IntoIter<T: IntoScoped> {
inner: full::IntoIter<T::Scope>,
ignored: T::Ignored,
}
impl<T: IntoScoped> IntoIter<T> {
pub fn ignored(&self) -> &T::Ignored {
&self.ignored
}
}
impl<T: IntoScoped> Iterator for IntoIter<T>
where
T::Ignored: Clone,
{
type Item = (T::Scope, T::Ignored);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|s| (s, self.ignored.clone()))
}
}
impl<T: IntoScoped> IntoIterator for Snaplog<T>
where
T::Ignored: Clone,
{
type Item = (T::Scope, T::Ignored);
type IntoIter = IntoIter<T>;
fn into_iter(self) -> Self::IntoIter {
Self::IntoIter {
inner: self.full.into_iter(),
ignored: self.ignored,
}
}
}
#[derive(Debug)]
pub struct Iter<'cl, T: IntoScoped> {
inner: full::Iter<'cl, T::Scope>,
ignored: &'cl T::Ignored,
}
impl<'cl, T: IntoScoped> Iter<'cl, T> {
pub fn ignored(&self) -> &'cl T::Ignored {
self.ignored
}
}
impl<'cl, T: IntoScoped> Iterator for Iter<'cl, T> {
type Item = (&'cl T::Scope, &'cl T::Ignored);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|s| (s, self.ignored))
}
}
impl<'cl, T: IntoScoped> IntoIterator for &'cl Snaplog<T> {
type Item = (&'cl T::Scope, &'cl T::Ignored);
type IntoIter = Iter<'cl, T>;
fn into_iter(self) -> Self::IntoIter {
Iter {
inner: self.full.iter(),
ignored: &self.ignored,
}
}
}
#[derive(Debug)]
pub struct IterMut<'cl, T: IntoScoped> {
inner: full::IterMut<'cl, T::Scope>,
ignored: &'cl T::Ignored,
}
impl<'cl, T: IntoScoped> IterMut<'cl, T> {
pub fn ignored(&self) -> &'cl T::Ignored {
self.ignored
}
}
impl<'cl, T: IntoScoped> Iterator for IterMut<'cl, T> {
type Item = (&'cl mut T::Scope, &'cl T::Ignored);
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|s| (s, self.ignored))
}
}
impl<'cl, T: IntoScoped> IntoIterator for &'cl mut Snaplog<T> {
type Item = (&'cl mut T::Scope, &'cl T::Ignored);
type IntoIter = IterMut<'cl, T>;
fn into_iter(self) -> Self::IntoIter {
IterMut {
inner: self.full.iter_mut(),
ignored: &mut self.ignored,
}
}
}
impl<T: IntoScoped> From<T> for Snaplog<T> {
fn from(initial: T) -> Self {
Self::new(initial)
}
}
impl<T: IntoScoped> From<Snaplog<T>> for (full::Snaplog<T::Scope>, T::Ignored) {
fn from(snaplog: Snaplog<T>) -> Self {
snaplog.into_inner()
}
}
impl<T: IntoScoped> TryFrom<(Vec<T::Scope>, T::Ignored)> for Snaplog<T> {
type Error = EmptyHistoryError;
fn try_from(value: (Vec<T::Scope>, T::Ignored)) -> Result<Self, Self::Error> {
Self::try_from_vec(value.0, value.1)
}
}