use super::{Change, ChangeReason};
use std::fmt;
use std::ops::Deref;
use std::rc::Rc;
pub struct ChangeSet<T, K> {
changes: Rc<Vec<Change<T, K>>>,
}
impl<T, K> Clone for ChangeSet<T, K> {
fn clone(&self) -> Self {
Self { changes: self.changes.clone() }
}
}
impl<T, K> Default for ChangeSet<T, K> {
fn default() -> Self {
Self::empty()
}
}
impl<T, K> ChangeSet<T, K> {
pub fn empty() -> Self {
Self { changes: Rc::new(Vec::new()) }
}
pub fn changes(&self) -> &[Change<T, K>] {
&self.changes
}
pub fn count(&self) -> usize {
self.changes.len()
}
fn count_of(&self, reason: ChangeReason) -> usize {
self.changes.iter().filter(|change| change.reason() == reason).count()
}
pub fn adds(&self) -> usize {
self.count_of(ChangeReason::Add)
}
pub fn updates(&self) -> usize {
self.count_of(ChangeReason::Update)
}
pub fn removes(&self) -> usize {
self.count_of(ChangeReason::Remove)
}
pub fn refreshes(&self) -> usize {
self.count_of(ChangeReason::Refresh)
}
pub fn moves(&self) -> usize {
self.count_of(ChangeReason::Moved)
}
pub fn to_vec(&self) -> Vec<Change<T, K>>
where
T: Clone,
K: Clone,
{
self.changes.as_ref().clone()
}
pub fn ptr_eq(&self, other: &Self) -> bool {
Rc::ptr_eq(&self.changes, &other.changes)
}
}
impl<T, K> From<Vec<Change<T, K>>> for ChangeSet<T, K> {
fn from(changes: Vec<Change<T, K>>) -> Self {
Self { changes: Rc::new(changes) }
}
}
impl<T, K> FromIterator<Change<T, K>> for ChangeSet<T, K> {
fn from_iter<I: IntoIterator<Item = Change<T, K>>>(iter: I) -> Self {
Self::from(iter.into_iter().collect::<Vec<_>>())
}
}
impl<T, K> Deref for ChangeSet<T, K> {
type Target = [Change<T, K>];
fn deref(&self) -> &Self::Target {
&self.changes
}
}
impl<'a, T, K> IntoIterator for &'a ChangeSet<T, K> {
type Item = &'a Change<T, K>;
type IntoIter = std::slice::Iter<'a, Change<T, K>>;
fn into_iter(self) -> Self::IntoIter {
self.changes.iter()
}
}
impl<T: PartialEq, K: PartialEq> PartialEq for ChangeSet<T, K> {
fn eq(&self, other: &Self) -> bool {
self.changes == other.changes
}
}
impl<T: fmt::Debug, K: fmt::Debug> fmt::Debug for ChangeSet<T, K> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.changes.iter()).finish()
}
}
pub trait IChangeSet<T, K>: Clone + 'static {
fn change_set(&self) -> &ChangeSet<T, K>;
}
impl<T: 'static, K: 'static> IChangeSet<T, K> for ChangeSet<T, K> {
fn change_set(&self) -> &ChangeSet<T, K> {
self
}
}