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
use crate::core::structs::{MutItem, ListDefObj, RustParam, ListSabValue, ListDefValue, Qv, MetaTables};
use crate::diff::imp::structs_write::{ListItemDiffW, ListDiffW};
use std::collections::BTreeMap;
use crate::diff::imp::prepare::get_mlist_diff::get_mlist_diff;
use crate::diff::imp::prepare::new_list::new_list;

pub(crate) fn compare_items<'a, 'b>(from : &'a MutItem, to : &'b MutItem, def : &'b ListDefObj, meta : &'b MetaTables) -> Option<ListItemDiffW<'b>>{
    let ref_def = def.refs();
    let def = def.default();
    let mut params : BTreeMap<usize, &RustParam> = BTreeMap::new();
    let mut lists : BTreeMap<usize, Option<ListDiffW>> = BTreeMap::new();

    let from_values = from.values();
    for (key, value) in to.values(){
        match value{
            ListSabValue::Param(p) =>{
                if let Some((id, _item)) = def.get_with_id(key) {
                    if let Some(ListSabValue::Param(from_p)) = from_values.get(key) {
                        if p != from_p {
                            params.insert(id, p);
                        }
                    } else {
                        params.insert(id, p);
                    }
                }
            },
            ListSabValue::Mil(mil) =>{
                if let Some((id, ListDefValue::MilDef(mil_def))) = def.get_with_id(key) {
                    let meta = if let Some(tables) = meta.items().get_tables(id) { tables } else {
                        panic!("invalid meta")
                    };
                    if let Some(ListSabValue::Mil(from_mil)) = from_values.get(key) {
                        if from_mil.is_none() && mil.is_none() {
                            continue;
                        }
                        if let Some(from_mil) = from_mil {
                            if let Some(mil) = mil {
                                if let Some(diff) = get_mlist_diff(from_mil.list(), mil.list(), mil_def.list_def(), meta) {
                                    lists.insert(id, Some(diff));
                                }
                            } else{
                                //コンバート時にundefinedになりうる
                                lists.insert(id, None);
                            }
                        } else{
                            if let Some(mil) = mil {
                                lists.insert(id, Some(new_list(mil,
                                                               mil_def.list_def(), meta)));
                            }
                        }
                    } else{
                        if let Some(mil) = mil {
                            lists.insert(id, Some(new_list(mil,
                                                           mil_def.list_def(), meta)));
                        } else{
                            lists.insert(id, None);
                        }
                    }
                }
            },
            ListSabValue::Cil(_) =>{}
        }
    }

    let mut refs : BTreeMap<usize, &Qv<String>> = BTreeMap::new();
    let from_ref = from.refs();
    for (key, value) in to.refs(){
        if let Some((id, _v)) = ref_def.refs().get_with_id(key) {
            let to_val = value.value();
            if let Some(from_value) = from_ref.get(key) {
                if from_value.value() != to_val {
                    refs.insert(id, to_val);
                }
            } else{
                refs.insert(id, to_val);
            }
        }
    }

    if params.len() == 0 && refs.len() == 0 && lists.len() == 0{
        None
    } else {
        Some(ListItemDiffW::new(params, refs, lists))
    }
}