<commit_before>use serde::{self, Deserialize, Serialize};
use std::fmt::Debug;
use std::mem;
use std::ops::Deref;

/// An object that can be incrementally updated with events.
pub trait Incremental<E>: Sized {
    /// Try to update the object with an event.
    fn update(self, e: &E) -> Self;
}

/// An incremental object that can fail when updated.
///
/// Use the `Incremental` implementation on a `Result` type with `FailingIncremental` value to use
/// this.
pub trait FailingIncremental<E>: Sized {
    /// Error in case an event couldn't be handled.
    type Error: Debug;

    /// Try to update the object with an event.
    fn update(self, e: &E) -> Result<Self, Self::Error>;
}

impl<T: FailingIncremental<E>, E> Incremental<E> for Result<T, T::Error> {
    fn update(self, e: &E) -> Self {
        match self {
            Ok(state) => state.update(e),
            err => err,
        }
    }
}

/// Handle that stores an `Incremental` object and the event sequence used to build it.
///
/// Serializes itself by only storing the log.
///
/// # Examples
///
/// ```
/// use calx::{Incremental, IncrementalState};
///
/// #[derive(Default)]
/// struct State(u32);
///
/// impl Incremental<u32> for State {
///     fn update(self, e: &u32) -> State { State(self.0 + *e) }
/// }
///
/// let mut handle: IncrementalState<State, u32> = Default::default();
/// assert_eq!(handle.0, 0);
///
/// for x in &[1, 2, 3, 4] { handle.push(*x); }
/// assert_eq!(handle.0, 10);
/// handle.pop();
/// assert_eq!(handle.0, 6);
/// ```
pub struct IncrementalState<T: Incremental<E> + Default, E> {
    log: Vec<E>,
    state: T,
}

// Implemented manually instead of derived so that T::Event doesn't need to implement Default.
impl<T: Incremental<E> + Default, E> Default for IncrementalState<T, E> {
    fn default() -> Self {
        IncrementalState {
            log: Vec::new(),
            state: Default::default(),
        }
    }
}

impl<T: Incremental<E> + Default, E> IncrementalState<T, E> {
    pub fn push(&mut self, e: E) {
        // XXX: Need to get state away from borrow checker for updating, is there a better way than
        // ugly unsafe tricks?
        let state = mem::replace(&mut self.state, unsafe { mem::uninitialized() }).update(&e);
        self.state = state;
        self.log.push(e);
    }

    pub fn pop(&mut self) -> Option<E> {
        // TODO: Way to pop several items without O(n) delay for each.
        let ret = self.log.pop();
        self.replay();
        ret
    }

    fn replay(&mut self) {
        let mut state: T = Default::default();

        for e in &self.log {
            state = state.update(e);
        }

        self.state = state;
    }
}

impl<T: Incremental<E> + Default, E> Deref for IncrementalState<T, E> {
    type Target = T;

    fn deref(&self) -> &T { &self.state }
}

impl<T: Incremental<E> + Default, E: Serialize> Serialize for IncrementalState<T, E> {
    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
        self.log.serialize(s)
    }
}

impl<'a, T: Incremental<E> + Default, E: Deserialize<'a>> Deserialize<'a>
    for IncrementalState<T, E>
{
    fn deserialize<D: serde::Deserializer<'a>>(d: D) -> Result<Self, D::Error> {
        let mut ret: Self = IncrementalState {
            log: Vec::deserialize(d)?,
            state: Default::default(),
        };
        ret.replay();
        Ok(ret)
    }
}<commit_msg>feat: Allow seed value in Incremental<commit_after>use serde;
use serde_derive::{Deserialize, Serialize};
use std::fmt::Debug;
use std::mem;
use std::ops::Deref;

/// An object that can be incrementally updated with events.
pub trait Incremental<E>: Sized {
    /// Try to update the object with an event.
    fn update(self, e: &E) -> Self;
}

/// An incremental object that can fail when updated.
///
/// Use the `Incremental` implementation on a `Result` type with `FailingIncremental` value to use
/// this.
pub trait FailingIncremental<E>: Sized {
    /// Error in case an event couldn't be handled.
    type Error: Debug;

    /// Try to update the object with an event.
    fn update(self, e: &E) -> Result<Self, Self::Error>;
}

impl<T: FailingIncremental<E>, E> Incremental<E> for Result<T, T::Error> {
    fn update(self, e: &E) -> Self {
        match self {
            Ok(state) => state.update(e),
            err => err,
        }
    }
}

/// Handle that stores an `Incremental` object and the event sequence used to build it.
///
/// Serializes itself by only storing the log.
///
/// # Examples
///
/// ```
/// use calx::{Incremental, IncrementalState};
///
/// #[derive(Default)]
/// struct State(u32);
///
/// impl Incremental<u32> for State {
///     fn update(self, e: &u32) -> State { State(self.0 + *e) }
/// }
///
/// impl From<u32> for State {
///     fn from(x: u32) -> Self { State(x) }
/// }
///
/// let mut handle: IncrementalState<State, u32, u32> = Default::default();
/// assert_eq!(handle.0, 0);
///
/// for x in &[1, 2, 3, 4] { handle.push(*x); }
/// assert_eq!(handle.0, 10);
/// handle.pop();
/// assert_eq!(handle.0, 6);
/// ```
pub struct IncrementalState<T: Incremental<E>, U: Into<T> + Clone, E> {
    state: T,
    history: History<U, E>,
}

#[derive(Serialize, Deserialize)]
struct History<U, E> {
    seed: U,
    log: Vec<E>,
}

// Implemented manually instead of derived so that T::Event doesn't need to implement Default.
impl<T: Incremental<E>, U: Into<T> + Clone + Default, E> Default for IncrementalState<T, U, E> {
    fn default() -> Self { IncrementalState::new(U::default()) }
}

impl<T: Incremental<E>, U: Into<T> + Clone, E> IncrementalState<T, U, E> {
    pub fn new(seed: U) -> Self {
        IncrementalState {
            state: seed.clone().into(),
            history: History {
                seed,
                log: Vec::new(),
            },
        }
    }
}

impl<T: Incremental<E>, U: Into<T> + Clone, E> IncrementalState<T, U, E> {
    pub fn push(&mut self, e: E) {
        // XXX: Need to get state away from borrow checker for updating, is there a better way than
        // ugly unsafe tricks?
        let state = mem::replace(&mut self.state, unsafe { mem::uninitialized() }).update(&e);
        self.state = state;
        self.history.log.push(e);
    }
}

impl<T: Incremental<E>, U: Into<T> + Clone, E> IncrementalState<T, U, E> {
    pub fn pop(&mut self) -> Option<E> {
        // TODO: Way to pop several items without O(n) delay for each.
        let ret = self.history.log.pop();
        self.replay();
        ret
    }

    fn replay(&mut self) {
        let mut state: T = self.history.seed.clone().into();

        for e in &self.history.log {
            state = state.update(e);
        }

        self.state = state;
    }
}

impl<T: Incremental<E>, U: Into<T> + Clone, E> Deref for IncrementalState<T, U, E> {
    type Target = T;

    fn deref(&self) -> &T { &self.state }
}

impl<T, U, E> serde::Serialize for IncrementalState<T, U, E>
where
    T: Incremental<E>,
    U: Into<T> + Clone + serde::Serialize,
    E: serde::Serialize,
{
    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
        self.history.serialize(s)
    }
}

impl<'a, T, U, E> serde::Deserialize<'a> for IncrementalState<T, U, E>
where
    T: Incremental<E>,
    U: Into<T> + Clone + serde::Deserialize<'a>,
    E: serde::Deserialize<'a>,
{
    fn deserialize<D: serde::Deserializer<'a>>(d: D) -> Result<Self, D::Error> {
        let history: History<U, E> = History::deserialize(d)?;
        let state = history.seed.clone().into();
        let mut ret: Self = IncrementalState { state, history };
        ret.replay();
        Ok(ret)
    }
}
{'fraction_non_alphanumeric': 0.17136517880448968, 'fraction_numerical': 0.006003654398329418, 'mean_word_length': 2.5362251961236733, 'pattern_counts': {'":': 0, '<': 92, '<?xml version=': 0, '>': 116, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '319617', 'n_tokens_mistral': 2646, 'n_tokens_neox': 2569, 'n_words': 771}