state_tree/
patch.rs

1use crate::tree::StateTree;
2
3/// A patch to be applied to a Empty StateTree from old tree.
4#[derive(Debug, PartialEq, Clone)]
5pub struct CopyFromPatch {
6    pub new_path: Vec<usize>,
7    pub old_path: Vec<usize>,
8}
9
10/// パッチを新しい木に適用する
11///
12/// # Arguments
13/// * `new_tree` - データのコピー先となる、構造が新しい木(中身は0で初期化済み)
14/// * `old_tree` - データのコピー元となる、古い木
15/// * `patches` - `diff`関数で生成されたパッチのリスト
16///
17/// # Panics
18/// パッチに含まれるパスが無効な場合、またはコピー元とコピー先のノードの型が一致しない場合にパニックする可能性があります。
19/// (`diff`が正しく実装されていれば、通常は起こりません)
20pub fn apply_patches(new_tree: &mut StateTree, old_tree: &StateTree, patches: &[CopyFromPatch]) {
21    for patch in patches {
22        let source_node = old_tree
23            .get_node(&patch.old_path)
24            .expect("Invalid old_path in patch");
25        let dest_node = new_tree
26            .get_node_mut(&patch.new_path)
27            .expect("Invalid new_path in patch");
28
29        // `diff`の`nodes_match`によって型とlenが一致していることは保証されているはず
30        // ここでは、その前提に基づいてデータをコピーする
31        match (source_node, dest_node) {
32            (
33                StateTree::Delay {
34                    readidx: r_src,
35                    writeidx: w_src,
36                    data: d_src,
37                },
38                StateTree::Delay {
39                    readidx: r_dest,
40                    writeidx: w_dest,
41                    data: d_dest,
42                },
43            ) => {
44                *r_dest = *r_src;
45                *w_dest = *w_src;
46                d_dest.copy_from_slice(d_src);
47            }
48            (StateTree::Mem { data: d_src }, StateTree::Mem { data: d_dest }) => {
49                d_dest.copy_from_slice(d_src);
50            }
51            (StateTree::Feed { data: d_src }, StateTree::Feed { data: d_dest }) => {
52                d_dest.copy_from_slice(d_src);
53            }
54            // FnCallはデータを持たないので何もしない
55            (StateTree::FnCall(_), StateTree::FnCall(_)) => (),
56            // 型が一致しない場合はロジックエラー
57            _ => panic!("Mismatched node types during patch application. This should not happen."),
58        }
59    }
60}