use std::collections::VecDeque;
use crate::ObjectStatus;
#[derive(Debug)]
#[non_exhaustive]
pub struct RetainResult<T> {
pub retained: usize,
pub removed: Vec<T>,
}
pub(crate) trait SealedState {
type Object;
fn status(&self) -> ObjectStatus;
fn mut_object(&mut self) -> &mut Self::Object;
fn take_object(self) -> Self::Object;
}
pub(crate) fn do_vec_deque_retain<T, State: SealedState<Object = T>>(
deque: &mut VecDeque<State>,
mut f: impl FnMut(&mut T, ObjectStatus) -> bool,
) -> RetainResult<T> {
let len = deque.len();
let mut idx = 0;
let mut cur = 0;
while cur < len {
let state = &mut deque[cur];
let status = state.status();
if !f(state.mut_object(), status) {
cur += 1;
break;
}
cur += 1;
idx += 1;
}
while cur < len {
let state = &mut deque[cur];
let status = state.status();
if !f(state.mut_object(), status) {
cur += 1;
continue;
}
deque.swap(idx, cur);
cur += 1;
idx += 1;
}
let removed = if cur != idx {
let removed = deque.split_off(idx);
removed.into_iter().map(State::take_object).collect()
} else {
Vec::new()
};
RetainResult {
retained: idx,
removed,
}
}