1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
 * Copyright 2021 Fluence Labs Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

mod fold_lore_resolver;

use super::*;
pub use fold_lore_resolver::*;

#[derive(Debug, Default, Clone)]
pub struct MergerFoldResult {
    pub prev_fold_lore: ResolvedFold,
    pub current_fold_lore: ResolvedFold,
}

pub(crate) fn try_merge_next_state_as_fold(data_keeper: &mut DataKeeper) -> MergeResult<MergerFoldResult> {
    use ExecutedState::Fold;

    let prev_state = data_keeper.prev_slider_mut().next_state();
    let current_state = data_keeper.current_slider_mut().next_state();

    let fold_result = match (prev_state, current_state) {
        (Some(Fold(prev_fold)), Some(Fold(current_fold))) => {
            MergerFoldResult::from_fold_results(&prev_fold, &current_fold, data_keeper)
        }
        (None, Some(Fold(current_fold))) => {
            MergerFoldResult::from_fold_result(&current_fold, MergeCtxType::Current, data_keeper)
        }
        (Some(Fold(prev_fold)), None) => {
            MergerFoldResult::from_fold_result(&prev_fold, MergeCtxType::Previous, data_keeper)
        }
        (None, None) => return Ok(MergerFoldResult::default()),
        (prev_state, current_state) => return Err(MergeError::incompatible_states(prev_state, current_state, "fold")),
    }?;

    Ok(fold_result)
}

impl MergerFoldResult {
    pub(self) fn from_fold_result(
        fold: &FoldResult,
        ctx_type: MergeCtxType,
        data_keeper: &DataKeeper,
    ) -> MergeResult<Self> {
        let (prev_fold_lore, current_fold_lore) = match ctx_type {
            MergeCtxType::Previous => {
                let fold_lore = resolve_fold_lore(fold, &data_keeper.prev_ctx)?;
                (fold_lore, <_>::default())
            }
            MergeCtxType::Current => {
                let fold_lore = resolve_fold_lore(fold, &data_keeper.current_ctx)?;
                (<_>::default(), fold_lore)
            }
        };

        let merge_result = Self {
            prev_fold_lore,
            current_fold_lore,
        };

        Ok(merge_result)
    }

    pub(self) fn from_fold_results(
        prev_fold: &FoldResult,
        current_fold: &FoldResult,
        data_keeper: &DataKeeper,
    ) -> MergeResult<Self> {
        let prev_fold_lore = resolve_fold_lore(prev_fold, &data_keeper.prev_ctx)?;
        let current_fold_lore = resolve_fold_lore(current_fold, &data_keeper.current_ctx)?;

        let merge_result = Self {
            prev_fold_lore,
            current_fold_lore,
        };

        Ok(merge_result)
    }
}