use core::mem::replace;
use super::Merge;
use super::error::Error;
#[derive(Debug)]
pub struct MergeCell<T> {
value: Option<T>,
result: Result<(), Error>,
}
impl<T> Default for MergeCell<T> {
fn default() -> Self {
Self::empty()
}
}
impl<T> MergeCell<T> {
pub fn empty() -> Self {
Self {
value: None,
result: Ok(()),
}
}
pub fn new(value: T) -> Self {
Self {
value: Some(value),
result: Ok(()),
}
}
pub fn is_empty(&self) -> bool {
self.value.is_none()
}
pub fn has_errored(&self) -> bool {
self.result.is_err()
}
pub fn finish(self) -> Result<T, Error> {
self.try_finish()
.expect("tried to .finish() an empty MergeCell")
}
pub fn try_finish(self) -> Option<Result<T, Error>> {
let value = self.value?;
let r = self.result.map(|()| value);
Some(r)
}
}
impl<T> MergeCell<T>
where
T: Merge,
{
pub fn merge(&mut self, other: T) {
match self.value {
Some(ref mut value) => {
let r = replace(&mut self.result, Ok(()));
self.result = r.and_then(|()| value.merge_ref(other));
}
None => self.value = Some(other),
}
}
}