pub trait CompareUpdate<Current, T> {
type Error;
type Retry;
type Final;
fn initial(self) -> (Self::Retry, Current, T);
fn retry(retry: Self::Retry, current: Current, val: T)
-> Result<(Self::Retry, T), Self::Error>;
fn finalize(retry: Self::Retry, val: T) -> Self::Final;
}
impl<FI, U, T, F, C, E, FF, R> CompareUpdate<U, T> for (FI, F, FF)
where
FI: FnOnce() -> (C, U, T),
F: FnMut(C, U, T) -> Result<(C, T), E>,
FF: FnOnce(C, T) -> R,
{
type Error = E;
type Retry = (C, F, FF);
type Final = R;
fn initial(self) -> (Self::Retry, U, T) {
let (c, u, t) = self.0();
((c, self.1, self.2), u, t)
}
fn retry(
(c, mut f, ff): Self::Retry,
current: U,
val: T,
) -> Result<(Self::Retry, T), Self::Error> {
f(c, current, val).map(|(c, t)| ((c, f, ff), t))
}
fn finalize((c, _, ff): Self::Retry, val: T) -> Self::Final {
ff(c, val)
}
}
impl<FI, U, T, F, C, E> CompareUpdate<U, T> for (FI, F)
where
FI: FnOnce() -> (C, U, T),
F: FnMut(C, U, T) -> Result<(C, T), E>,
{
type Error = E;
type Retry = (C, F);
type Final = T;
fn initial(self) -> (Self::Retry, U, T) {
let (c, u, t) = self.0();
((c, self.1), u, t)
}
fn retry((c, mut f): Self::Retry, current: U, val: T) -> Result<(Self::Retry, T), Self::Error> {
f(c, current, val).map(|(c, t)| ((c, f), t))
}
fn finalize(_retry: Self::Retry, val: T) -> Self::Final {
val
}
}
impl<U, T, F, C, E> CompareUpdate<U, T> for (C, U, T, F)
where
F: FnMut(C, U, T) -> Result<(C, T), E>,
{
type Error = E;
type Retry = (C, F);
type Final = T;
fn initial(self) -> (Self::Retry, U, T) {
((self.0, self.3), self.1, self.2)
}
fn retry((c, mut f): Self::Retry, current: U, val: T) -> Result<(Self::Retry, T), Self::Error> {
f(c, current, val).map(|(c, t)| ((c, f), t))
}
fn finalize(_retry: Self::Retry, val: T) -> Self::Final {
val
}
}
impl<U, T, F, C, E, FF, R> CompareUpdate<U, T> for (C, U, T, F, FF)
where
F: FnMut(C, U, T) -> Result<(C, T), E>,
FF: FnOnce(C, T) -> R,
{
type Error = E;
type Retry = (C, F, FF);
type Final = R;
fn initial(self) -> (Self::Retry, U, T) {
((self.0, self.3, self.4), self.1, self.2)
}
fn retry(
(c, mut f, ff): Self::Retry,
current: U,
val: T,
) -> Result<(Self::Retry, T), Self::Error> {
f(c, current, val).map(|(c, t)| ((c, f, ff), t))
}
fn finalize((c, _, ff): Self::Retry, val: T) -> Self::Final {
ff(c, val)
}
}