use super::*;
use crate::merger::errors::CanonResultError;
const EXPECTED_STATE_NAME: &str = "canon";
#[derive(Debug, Clone)]
pub enum MergerCanonResult {
Empty,
CanonResult(CanonResult),
}
pub(crate) fn try_merge_next_state_as_canon(data_keeper: &mut DataKeeper) -> MergeResult<MergerCanonResult> {
use ExecutedState::Canon;
let prev_state = data_keeper.prev_slider_mut().next_state();
let current_state = data_keeper.current_slider_mut().next_state();
match (prev_state, current_state) {
(Some(Canon(prev_canon)), Some(Canon(current_canon))) => prepare_both_canon_result(prev_canon, current_canon),
(Some(Canon(prev_canon)), None) => prepare_single_canon_result(prev_canon),
(None, Some(Canon(current_canon))) => prepare_single_canon_result(current_canon),
(None, None) => Ok(MergerCanonResult::Empty),
(prev_state, current_state) => Err(MergeError::incompatible_states(
prev_state,
current_state,
EXPECTED_STATE_NAME,
)),
}
}
fn prepare_both_canon_result(
prev_canon_result: CanonResult,
current_canon_result: CanonResult,
) -> MergeResult<MergerCanonResult> {
let canon_result =
merge_canon_results(prev_canon_result, current_canon_result).map_err(MergeError::IncorrectCanonResult)?;
prepare_single_canon_result(canon_result)
}
fn prepare_single_canon_result(canon_result: CanonResult) -> MergeResult<MergerCanonResult> {
let merger_result = MergerCanonResult::CanonResult(canon_result);
Ok(merger_result)
}
fn merge_canon_results(
prev_canon_result: CanonResult,
current_canon_result: CanonResult,
) -> Result<CanonResult, CanonResultError> {
use CanonResult::*;
match (&prev_canon_result, ¤t_canon_result) {
(Executed(prev), Executed(cur)) if prev != cur => Err(CanonResultError::incompatible_state(
prev_canon_result,
current_canon_result,
)),
(RequestSentBy(_), Executed(_)) => Ok(current_canon_result),
(RequestSentBy(_), RequestSentBy(_)) | (Executed(_), RequestSentBy(_)) | (Executed(_), Executed(_)) => {
Ok(prev_canon_result)
}
}
}