knife_util/
merge.rs

1//! JSON合并模块
2//!
3//! 提供 JSON 数据的深度合并功能。
4//!
5//! 模块结构索引:
6//! 1) 策略定义与常量
7//! 2) 小型辅助函数与策略解析
8//! 3) 合并核心 Trait:`MergeWithTrait`
9//! 4) 基础类型实现(数字/字符串/布尔)
10//! 5) serde_json::Value 实现(分发至对象/数组/原子)
11//! 6) Option<T> 实现
12//! 7) 集合类型实现(Vec/HashSet/BTreeSet)
13//! 8) Map 类型实现(HashMap/BTreeMap)
14//! 9) 便捷函数 `merge_json`
15//!
16//! 约定:
17//! - 节点(对象/映射/数组/原子)如何在“本层”合并由当前节点策略决定(由方法参数解析)。
18//! - 子节点在“递归合并”时如何处理,由来源对象上的 `key._policy_` 指定;未指定则传 Default 给子节点,由其结合 default_policy 决定默认行为。
19//! - 父层负责“该不该合并/覆盖/保留某键”,子层负责“具体值如何合并”。职责清晰,便于维护。
20
21use crate::error::AppError;
22use serde_json::Value;
23use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
24use std::fmt::Display;
25use std::str::FromStr;
26use crate::EnumTypeTrait;
27
28#[derive(Copy, Clone)]
29pub enum MergePolicy {
30    Default,
31    Merge,
32    Override,
33    Keep,
34    Skip,
35    VecAppend,
36    StringConcat,
37    BooleanTrueWin,
38    BooleanFalseWin,
39    NumberSum,
40    NumberMax,
41    NumberMin,
42}
43
44// 静态常量:避免重复创建临时变量
45static MERGE_POLICY: MergePolicy = MergePolicy::Merge;
46static VEC_APPEND_POLICY: MergePolicy = MergePolicy::VecAppend;
47static DEFAULT_POLICY: MergePolicy = MergePolicy::Default;
48
49// ========== 小型辅助函数 ==========
50#[inline]
51fn get_child_policy(obj: &serde_json::Map<String, Value>, key_str: &str) -> Result<MergePolicy, AppError> {
52    let policy_key = format!("{}._policy_", key_str);
53    if let Some(Value::String(policy_str)) = obj.get(&policy_key) {
54        parse_policy(policy_str)
55    } else {
56        Ok(MergePolicy::Default)
57    }
58}
59
60// ---------- 策略解析 ----------
61// 辅助函数:解析策略,返回实际要使用的策略值
62// 参数:
63//   current: 当前策略值
64//   default: 默认策略值
65//   expect: 期望策略值(当 current 和 default 都是 Default 时使用的策略)
66// 返回:实际要使用的策略值
67// 注意:使用 #[inline(always)] 确保在所有调用点内联,减少函数调用开销
68#[inline(always)]
69fn resolve_policy(current: MergePolicy, default: MergePolicy, expect: MergePolicy) -> MergePolicy {
70    // 使用 match 而不是 matches! 宏,编译器可以更好地优化
71    match current {
72        MergePolicy::Default => match default {
73            MergePolicy::Default => expect,
74            _ => default,
75        },
76        _ => current,
77    }
78}
79
80pub trait MergeWithTrait {
81    /// 从 JSON Value 合并数据
82    fn merge_json(&mut self, source: &Value) -> Result<(), AppError> {
83        self.merge_json_with_policy(source, DEFAULT_POLICY, DEFAULT_POLICY)
84    }
85
86    /// 从同类型对象合并数据
87    fn merge_from(&mut self, source: &Self) -> Result<(), AppError> {
88        self.merge_from_with_policy(source, DEFAULT_POLICY, DEFAULT_POLICY)
89    }
90
91    /// 从 JSON Value 合并数据(带策略)
92    fn merge_json_with_policy(&mut self, source: &Value, current_policy: MergePolicy, default_policy: MergePolicy) -> Result<(), AppError>;
93
94    /// 从同类型对象合并数据(带策略)
95    fn merge_from_with_policy(&mut self, source: &Self, current_policy: MergePolicy, default_policy: MergePolicy) -> Result<(), AppError>;
96}
97
98// ========== 基础类型实现(数字/字符串/布尔) ==========
99// 宏定义:为数字类型实现 MergeWithTrait
100/// 为数字类型实现 MergeWithTrait
101///
102/// 规则:
103/// - Merge/Override:覆盖值
104/// - NumberSum/NumberMax/NumberMin:按数值策略合并
105/// - Keep/Skip:保持/跳过
106/// - 其它策略:返回 INVALID_POLICY
107macro_rules! impl_merge_with_number {
108    ($($type:ty),*) => {
109        $(
110            impl MergeWithTrait for $type {
111                #[inline]
112                fn merge_from_with_policy(
113                    &mut self,
114                    source: &Self,
115                    current_policy: MergePolicy,
116                    default_policy: MergePolicy,
117                ) -> Result<(), AppError> {
118                    // 使用 resolve_policy 统一处理策略解析
119                    let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
120
121                    // 优化分支顺序:最常见的分支放在前面
122                    match policy {
123                        MergePolicy::Merge | MergePolicy::Override => { *self = *source; Ok(()) }
124                        MergePolicy::NumberSum => { *self += *source; Ok(()) }
125                        MergePolicy::NumberMax => { *self = (*self).max(*source); Ok(()) }
126                        MergePolicy::NumberMin => { *self = (*self).min(*source); Ok(()) }
127                        MergePolicy::Keep | MergePolicy::Skip => Ok(()),
128                        _ => Err(AppError::new("INVALID_POLICY", "策略对数字类型无效")),
129                    }
130                }
131
132                #[inline]
133                fn merge_json_with_policy(
134                    &mut self,
135                    source: &Value,
136                    current_policy: MergePolicy,
137                    default_policy: MergePolicy,
138                ) -> Result<(), AppError> {
139                    // 使用 resolve_policy 统一处理策略解析
140                    let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
141
142                    let source_value = match source {
143                        Value::Number(n) => {
144                            if let Some(v) = n.as_i64() {
145                                v as $type
146                            } else if let Some(v) = n.as_u64() {
147                                v as $type
148                            } else if let Some(v) = n.as_f64() {
149                                v as $type
150                } else {
151                                return Err(AppError::new("TYPE_MISMATCH", &format!("无法将非数字类型合并到{}", stringify!($type))));
152                            }
153                        }
154                        Value::String(s) => {
155                            if let Ok(v) = s.parse::<$type>() {
156                                v
157                            } else {
158                                return Err(AppError::new(
159                                    "PARSE_ERROR",
160                                    &format!("无法解析字符串 '{}' 为{}", s, stringify!($type)),
161                                ));
162                            }
163                        }
164                        _ => return Err(AppError::new("TYPE_MISMATCH", &format!("无法将非数字类型合并到{}", stringify!($type)))),
165                    };
166
167                    // 优化分支顺序
168                    match policy {
169                        MergePolicy::Merge | MergePolicy::Override => { *self = source_value; Ok(()) }
170                        MergePolicy::NumberSum => { *self += source_value; Ok(()) }
171                        MergePolicy::NumberMax => { *self = (*self).max(source_value); Ok(()) }
172                        MergePolicy::NumberMin => { *self = (*self).min(source_value); Ok(()) }
173                        MergePolicy::Keep | MergePolicy::Skip => Ok(()),
174                        _ => Err(AppError::new("INVALID_POLICY", "策略对数字类型无效")),
175                    }
176                }
177            }
178        )*
179    };
180}
181
182// 宏定义:为字符串类型实现 MergeWithTrait
183/// 为字符串类型实现 MergeWithTrait
184///
185/// 规则:
186/// - Merge:非空来源覆盖
187/// - Override:无条件覆盖
188/// - Keep:仅在目标为空时采用来源
189/// - StringConcat:拼接
190/// - 其它策略:返回 INVALID_POLICY
191macro_rules! impl_merge_with_string {
192    ($($type:ty),*) => {
193        $(
194            impl MergeWithTrait for $type {
195                #[inline]
196                fn merge_from_with_policy(
197                    &mut self,
198                    source: &Self,
199                    current_policy: MergePolicy,
200                    default_policy: MergePolicy,
201                ) -> Result<(), AppError> {
202                    // 使用 resolve_policy 统一处理策略解析
203                    let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
204
205                    match policy {
206                        MergePolicy::Override => { *self = source.clone(); Ok(()) }
207                        MergePolicy::Merge => { if !source.is_empty() { *self = source.clone(); } Ok(()) }
208                        MergePolicy::Keep => { if self.is_empty() { *self = source.clone(); } Ok(()) }
209                        MergePolicy::Skip => Ok(()),
210                        MergePolicy::StringConcat => {
211                            let mut result = String::with_capacity(self.len() + source.len());
212                            result.push_str(self);
213                            result.push_str(source);
214                            *self = result;
215                            Ok(())
216                        }
217                        _ => Err(AppError::new("INVALID_POLICY", "策略对字符串类型无效")),
218                    }
219                }
220
221                #[inline]
222                fn merge_json_with_policy(
223                    &mut self,
224                    source: &Value,
225                    current_policy: MergePolicy,
226                    default_policy: MergePolicy,
227                ) -> Result<(), AppError> {
228                    // 使用 resolve_policy 统一处理策略解析
229                    let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
230
231                    let source_value = match source {
232                        Value::String(s) => {
233                            if s.is_empty() {
234                                String::new() // 空字符串解析为空值
235                            } else {
236                                s.clone()
237                            }
238                        }
239                        Value::Number(n) => {
240                            if let Some(f) = n.as_f64() {
241                                if !f.is_finite() {
242                                    return Err(AppError::new("INVALID_NUMBER", "不支持将非有限数字转换为字符串"));
243                                }
244                            }
245                            n.to_string()
246                        },
247                        Value::Bool(b) => b.to_string(),
248                        _ => return Err(AppError::new("TYPE_MISMATCH", "无法将非字符串类型合并到字符串")),
249                    };
250
251                    match policy {
252                        MergePolicy::Override => { *self = source_value; Ok(()) }
253                        MergePolicy::Merge => { if !source_value.is_empty() { *self = source_value; } Ok(()) }
254                        MergePolicy::Keep => { if self.is_empty() { *self = source_value; } Ok(()) }
255                        MergePolicy::Skip => Ok(()),
256                        MergePolicy::StringConcat => {
257                            let mut result = String::with_capacity(self.len() + source_value.len());
258                            result.push_str(self);
259                            result.push_str(&source_value);
260                            *self = result;
261                            Ok(())
262                        }
263                        _ => Err(AppError::new("INVALID_POLICY", "策略对字符串类型无效")),
264                    }
265                }
266            }
267        )*
268    };
269}
270
271// 宏定义:为布尔类型实现 MergeWithTrait
272/// 为布尔类型实现 MergeWithTrait
273///
274/// 规则:
275/// - Merge/Override:覆盖值
276/// - BooleanTrueWin:true 胜
277/// - BooleanFalseWin:false 胜
278/// - Keep/Skip:保持/跳过
279/// - 其它策略:返回 INVALID_POLICY
280macro_rules! impl_merge_with_bool {
281    ($($type:ty),*) => {
282        $(
283            impl MergeWithTrait for $type {
284                #[inline]
285                fn merge_from_with_policy(
286                    &mut self,
287                    source: &Self,
288                    current_policy: MergePolicy,
289                    default_policy: MergePolicy,
290                ) -> Result<(), AppError> {
291                    // 使用 resolve_policy 统一处理策略解析
292                    let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
293
294                    match policy {
295                        MergePolicy::Merge | MergePolicy::Override => { *self = *source; Ok(()) }
296                        MergePolicy::BooleanTrueWin => { if *source { *self = true; } Ok(()) }
297                        MergePolicy::BooleanFalseWin => { if !*source { *self = false; } Ok(()) }
298                        MergePolicy::Keep | MergePolicy::Skip => Ok(()),
299                        _ => Err(AppError::new("INVALID_POLICY", "策略对布尔类型无效")),
300                    }
301                }
302
303                #[inline]
304                fn merge_json_with_policy(
305                    &mut self,
306                    source: &Value,
307                    current_policy: MergePolicy,
308                    default_policy: MergePolicy,
309                ) -> Result<(), AppError> {
310                    // 使用 resolve_policy 统一处理策略解析
311                    let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
312
313                    let source_value = match source {
314                        Value::Bool(b) => *b,
315                        Value::String(s) => {
316                            let trimmed = s.trim();
317                            if trimmed.eq_ignore_ascii_case("true")
318                                || trimmed.eq_ignore_ascii_case("yes")
319                                || trimmed.eq_ignore_ascii_case("on")
320                            {
321                                true
322                            } else if trimmed.eq_ignore_ascii_case("false")
323                                || trimmed.eq_ignore_ascii_case("no")
324                                || trimmed.eq_ignore_ascii_case("off")
325                            {
326                                false
327                            } else {
328                                return Err(AppError::new(
329                                    "PARSE_ERROR",
330                                    &format!("无法解析字符串 '{}' 为布尔值", s),
331                                ));
332                            }
333                        },
334                        _ => return Err(AppError::new("TYPE_MISMATCH", "无法将非布尔类型合并到bool")),
335                    };
336
337                    match policy {
338                        MergePolicy::Merge | MergePolicy::Override => { *self = source_value; Ok(()) }
339                        MergePolicy::BooleanTrueWin => { if source_value { *self = true; } Ok(()) }
340                        MergePolicy::BooleanFalseWin => { if !source_value { *self = false; } Ok(()) }
341                        MergePolicy::Keep | MergePolicy::Skip => Ok(()),
342                        _ => Err(AppError::new("INVALID_POLICY", "策略对布尔类型无效")),
343                    }
344                }
345            }
346        )*
347    };
348}
349
350// 为数字类型实现 MergeWithTrait
351impl_merge_with_number!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64);
352
353// 为字符串类型实现 MergeWithTrait
354impl_merge_with_string!(String);
355
356// 为布尔类型实现 MergeWithTrait
357impl_merge_with_bool!(bool);
358
359// ========== Option<T> 实现 ==========
360// 宏定义:为 Option 类型实现 MergeWithTrait
361/// 为 Option<T> 实现 MergeWithTrait
362///
363/// 规则(按 node_policy):
364/// - Merge:Some 覆盖 Some;None 不改变目标
365/// - Override:来源为 None 则置空;Some 则用来源递归合并
366/// - Keep:有值保持,无值采用来源
367/// - Skip:跳过
368macro_rules! impl_merge_with_option {
369    ($($type:ty),*) => {
370        $(
371            impl<T> MergeWithTrait for $type
372where
373    T: MergeWithTrait + Clone + Default,
374{
375                #[inline]
376    fn merge_from_with_policy(
377        &mut self,
378        source: &Self,
379        current_policy: MergePolicy,
380        default_policy: MergePolicy,
381    ) -> Result<(), AppError> {
382                    // 使用 resolve_policy 统一处理策略解析
383                    let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
384
385        match policy {
386            MergePolicy::Merge => {
387                // Merge: source有值用source,source无值用self
388                match source {
389                    Some(source_value) => {
390                        if let Some(target_value) = self {
391                            target_value.merge_from_with_policy(
392                                source_value,
393                                policy,
394                                default_policy,
395                            )?;
396                        } else {
397                            let mut new_value = T::default();
398                            new_value.merge_from_with_policy(
399                                source_value,
400                                policy,
401                                default_policy,
402                            )?;
403                            *self = Some(new_value);
404                        }
405                    }
406                    None => {
407                        // source为None,保持self不变
408                    }
409                }
410                Ok(())
411            }
412            MergePolicy::Override => {
413                // Override: 用source
414                match source {
415                    Some(source_value) => {
416                        if let Some(target_value) = self {
417                            target_value.merge_from_with_policy(
418                                source_value,
419                                policy,
420                                default_policy,
421                            )?;
422                        } else {
423                            let mut new_value = T::default();
424                            new_value.merge_from_with_policy(
425                                source_value,
426                                policy,
427                                default_policy,
428                            )?;
429                            *self = Some(new_value);
430                        }
431                    }
432                    None => {
433                        *self = None;
434                    }
435                }
436                Ok(())
437            }
438            MergePolicy::Keep => {
439                            // Keep: self有值用self,无值用source
440                match self {
441                    Some(_) => {
442                        // self有值,保持self不变
443                    }
444                    None => match source {
445                        Some(source_value) => {
446                            let mut new_value = T::default();
447                            new_value.merge_from_with_policy(
448                                source_value,
449                                policy,
450                                default_policy,
451                            )?;
452                            *self = Some(new_value);
453                        }
454                        None => {
455                            *self = None;
456                        }
457                    },
458                }
459                Ok(())
460            }
461            MergePolicy::Skip => Ok(()),
462            _ => Err(AppError::new("INVALID_POLICY", &format!("策略对{}类型无效", stringify!($type)))),
463        }
464    }
465
466                #[inline]
467    fn merge_json_with_policy(
468        &mut self,
469        source: &Value,
470        current_policy: MergePolicy,
471        default_policy: MergePolicy,
472    ) -> Result<(), AppError> {
473                    // 使用 resolve_policy 统一处理策略解析
474                    let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
475
476        match policy {
477            MergePolicy::Merge => {
478                            // Merge: source有值用source,source无值用self
479                match source {
480                    Value::Null => {}
481                    _ => {
482                        if let Some(inner) = self {
483                            inner.merge_json_with_policy(source, policy, default_policy)?;
484                        } else {
485                            let mut inner = T::default();
486                            inner.merge_json_with_policy(source, policy, default_policy)?;
487                            *self = Some(inner);
488                        }
489                    }
490                }
491                Ok(())
492            }
493            MergePolicy::Override => {
494                            // Override: 用source
495                match source {
496                    Value::Null => {
497                        *self = None;
498                    }
499                    _ => {
500                        let mut inner = T::default();
501                        inner.merge_json_with_policy(source, policy, default_policy)?;
502                        *self = Some(inner);
503                    }
504                }
505                Ok(())
506            }
507            MergePolicy::Keep => {
508                            // Keep: self有值用self,无值用source
509                match self {
510                                Some(_) => {
511                        // self有值,保持self不变
512                    }
513                    None => match source {
514                        Value::Null => {
515                            *self = None;
516                        }
517                        _ => {
518                            let mut inner = T::default();
519                            inner.merge_json_with_policy(source, policy, default_policy)?;
520                            *self = Some(inner);
521                        }
522                    },
523                }
524                Ok(())
525            }
526            MergePolicy::Skip => Ok(()),
527            _ => Err(AppError::new("INVALID_POLICY", &format!("策略对{}类型无效", stringify!($type)))),
528                    }
529                }
530            }
531        )*
532    };
533}
534
535// 为 Option 类型实现 MergeWithTrait
536impl_merge_with_option!(Option<T>);
537
538// ========== 集合类型实现(Vec/HashSet/BTreeSet) ==========
539// 宏定义:为集合类型实现 MergeWithTrait(Vec, HashSet, BTreeSet)
540// 统一使用迭代器遍历,合并三种集合类型的实现
541/// 为集合类型实现 MergeWithTrait(Vec/HashSet/BTreeSet)
542///
543/// 参数约定:
544/// - $type:集合类型
545/// - $insert_method:插入元素的方法(push/insert)
546/// - $type_name:仅用于错误消息的可读名称
547macro_rules! impl_merge_with_array {
548    // Vec 版本:使用 push,无额外 trait bounds
549    ($type:ty, push, $type_name:literal) => {
550        impl<T> MergeWithTrait for $type
551        where
552            T: MergeWithTrait + Clone + Default,
553        {
554            impl_merge_with_array_impl!($type, push, $type_name);
555        }
556    };
557    // HashSet 版本:使用 insert,需要 Eq + Hash
558    ($type:ty, insert, hash, $type_name:literal) => {
559        impl<T> MergeWithTrait for $type
560        where
561            T: MergeWithTrait + Clone + Default + Eq + std::hash::Hash,
562        {
563            impl_merge_with_array_impl!($type, insert, $type_name);
564        }
565    };
566    // BTreeSet 版本:使用 insert,需要 Ord
567    ($type:ty, insert, ord, $type_name:literal) => {
568        impl<T> MergeWithTrait for $type
569        where
570            T: MergeWithTrait + Clone + Default + Ord,
571        {
572            impl_merge_with_array_impl!($type, insert, $type_name);
573        }
574    };
575}
576
577// 实现宏:定义合并逻辑的实现
578/// 集合类型合并实现:
579/// - Default/VecAppend:逐元素递归合并后追加
580/// - Merge:来源非空则清空并重建;空来源不改变
581/// - Override:清空并重建
582/// - Keep:仅在目标为空时采用来源
583/// - Skip:跳过
584macro_rules! impl_merge_with_array_impl {
585    ($type:ty, $insert_method:ident, $type_name:literal) => {
586        fn merge_from_with_policy(&mut self, source: &Self, current_policy: MergePolicy, default_policy: MergePolicy) -> Result<(), AppError> {
587            let policy = resolve_policy(current_policy, default_policy, VEC_APPEND_POLICY);
588
589            // 统一使用迭代器遍历
590            match policy {
591                MergePolicy::Default | MergePolicy::VecAppend => {
592                    for item in source.iter() {
593                        let mut new_item = T::default();
594                        new_item.merge_from_with_policy(item, DEFAULT_POLICY, default_policy)?;
595                        self.$insert_method(new_item);
596                    }
597                    Ok(())
598                }
599                MergePolicy::Merge => {
600                    if !source.is_empty() {
601                        self.clear();
602                        for item in source.iter() {
603                            let mut new_item = T::default();
604                            new_item.merge_from_with_policy(item, DEFAULT_POLICY, default_policy)?;
605                            self.$insert_method(new_item);
606                        }
607                    }
608                    Ok(())
609                }
610                MergePolicy::Override => {
611                    self.clear();
612                    for item in source.iter() {
613                        let mut new_item = T::default();
614                        new_item.merge_from_with_policy(item, DEFAULT_POLICY, default_policy)?;
615                        self.$insert_method(new_item);
616                    }
617                    Ok(())
618                }
619                MergePolicy::Keep => {
620                    if self.is_empty() {
621                        for item in source.iter() {
622                            let mut new_item = T::default();
623                            new_item.merge_from_with_policy(item, DEFAULT_POLICY, default_policy)?;
624                            self.$insert_method(new_item);
625                        }
626                    }
627                    Ok(())
628                }
629                MergePolicy::Skip => Ok(()),
630                _ => Err(AppError::new("INVALID_POLICY", &format!("策略对{}类型无效", $type_name))),
631            }
632        }
633
634        fn merge_json_with_policy(&mut self, source: &Value, current_policy: MergePolicy, default_policy: MergePolicy) -> Result<(), AppError> {
635            let policy = resolve_policy(current_policy, default_policy, VEC_APPEND_POLICY);
636
637            match source {
638                Value::Array(arr) => {
639                    // 统一使用迭代器遍历
640                    match policy {
641                        MergePolicy::Default | MergePolicy::VecAppend => {
642                            for item in arr.iter() {
643                                let mut new_item = T::default();
644                                new_item.merge_json_with_policy(item, DEFAULT_POLICY, default_policy)?;
645                                self.$insert_method(new_item);
646                            }
647                            Ok(())
648                        }
649                        MergePolicy::Merge => {
650                            if !arr.is_empty() {
651                                self.clear();
652                                for item in arr.iter() {
653                                    let mut new_item = T::default();
654                                    new_item.merge_json_with_policy(item, DEFAULT_POLICY, default_policy)?;
655                                    self.$insert_method(new_item);
656                                }
657                            }
658                            Ok(())
659                        }
660                        MergePolicy::Override => {
661                            self.clear();
662                            for item in arr.iter() {
663                                let mut new_item = T::default();
664                                new_item.merge_json_with_policy(item, DEFAULT_POLICY, default_policy)?;
665                                self.$insert_method(new_item);
666                            }
667                            Ok(())
668                        }
669                        MergePolicy::Keep => {
670                            if self.is_empty() {
671                                for item in arr.iter() {
672                                    let mut new_item = T::default();
673                                    new_item.merge_json_with_policy(item, DEFAULT_POLICY, default_policy)?;
674                                    self.$insert_method(new_item);
675                                }
676                            }
677                            Ok(())
678                        }
679                        MergePolicy::Skip => Ok(()),
680                        _ => Err(AppError::new("INVALID_POLICY", &format!("策略对{}类型无效", $type_name))),
681                    }
682                }
683                _ => Err(AppError::new("TYPE_MISMATCH", &format!("无法将非数组类型合并到{}", $type_name))),
684            }
685        }
686    };
687}
688
689// 为 Vec 类型实现 MergeWithTrait(无额外 trait bounds)
690impl_merge_with_array!(Vec<T>, push, "Vec");
691
692// 为 HashSet 类型实现 MergeWithTrait(需要 Eq + Hash)
693impl_merge_with_array!(HashSet<T>, insert, hash, "HashSet");
694
695// 为 BTreeSet 类型实现 MergeWithTrait(需要 Ord)
696impl_merge_with_array!(BTreeSet<T>, insert, ord, "BTreeSet");
697
698// ========== Map 类型实现(HashMap/BTreeMap) ==========
699// 宏定义:为 Map 类型实现 MergeWithTrait(HashMap, BTreeMap)
700// 统一使用迭代器遍历,合并两种 Map 类型的实现
701/// 为映射类型实现 MergeWithTrait(HashMap/BTreeMap)
702///
703/// 说明:
704/// - 映射节点本层行为(是否覆盖/保持/合并键)由 node_policy(父层传入策略解析而来)决定
705/// - 每个键的子值在递归合并时,若在来源对象中声明了 `key._policy_`,则该策略作为 child_current_policy 传入子节点;否则传 Default
706macro_rules! impl_merge_with_map {
707    // HashMap 版本:需要 Eq + Hash
708    ($type:ty, hash, $type_name:literal) => {
709        impl<K, V> MergeWithTrait for $type
710        where
711            K: MergeWithTrait + Clone + Default + Eq + std::hash::Hash + FromStr + Display,
712            V: MergeWithTrait + Clone + Default,
713            <K as FromStr>::Err: Display,
714        {
715            impl_merge_with_map_impl!($type, $type_name);
716        }
717    };
718    // BTreeMap 版本:需要 Ord
719    ($type:ty, ord, $type_name:literal) => {
720        impl<K, V> MergeWithTrait for $type
721        where
722            K: MergeWithTrait + Clone + Default + Ord + FromStr + Display,
723            V: MergeWithTrait + Clone + Default,
724            <K as FromStr>::Err: Display,
725        {
726            impl_merge_with_map_impl!($type, $type_name);
727        }
728    };
729}
730
731// 实现宏:定义 Map 合并逻辑的实现
732/// Map 合并实现:详见上方宏注释
733macro_rules! impl_merge_with_map_impl {
734    ($type:ty, $type_name:literal) => {
735        fn merge_from_with_policy(&mut self, source: &Self, current_policy: MergePolicy, default_policy: MergePolicy) -> Result<(), AppError> {
736            // 使用 resolve_policy 统一处理策略解析
737            let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
738
739            // 统一使用迭代器遍历
740            match policy {
741                MergePolicy::Default | MergePolicy::Merge => {
742                    // Default/Merge: 合并所有键值对
743                    for (key, source_value) in source.iter() {
744                        if let Some(target_value) = self.get_mut(key) {
745                            target_value.merge_from_with_policy(source_value, DEFAULT_POLICY, default_policy)?;
746                        } else {
747                            let mut new_value = V::default();
748                            new_value.merge_from_with_policy(source_value, DEFAULT_POLICY, default_policy)?;
749                            self.insert(key.clone(), new_value);
750                        }
751                    }
752                    Ok(())
753                }
754                MergePolicy::Override => {
755                    self.clear();
756                    for (key, source_value) in source.iter() {
757                        let mut new_value = V::default();
758                        new_value.merge_from_with_policy(source_value, DEFAULT_POLICY, default_policy)?;
759                        self.insert(key.clone(), new_value);
760                    }
761                    Ok(())
762                }
763                MergePolicy::Keep => {
764                    // Keep: 保留self的值,只添加self中没有的键
765                    for (key, source_value) in source.iter() {
766                        if !self.contains_key(key) {
767                            let mut new_value = V::default();
768                            new_value.merge_from_with_policy(source_value, DEFAULT_POLICY, default_policy)?;
769                            self.insert(key.clone(), new_value);
770                        }
771                    }
772                    Ok(())
773                }
774                MergePolicy::Skip => Ok(()),
775                _ => Err(AppError::new("INVALID_POLICY", &format!("策略对{}类型无效", $type_name))),
776            }
777        }
778
779        fn merge_json_with_policy(&mut self, source: &Value, current_policy: MergePolicy, default_policy: MergePolicy) -> Result<(), AppError> {
780            match source {
781                Value::Object(obj) => {
782                    // 统一使用迭代器遍历所有键值对
783                    let node_policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
784                    for (key_str, source_value) in obj.iter() {
785                        if key_str.ends_with("._policy_") {
786                            continue;
787                        }
788
789                        // 解析键
790                        if let Ok(key) = key_str.parse::<K>() {
791                            // 查找该键的策略配置
792                            let policy_key = format!("{}._policy_", key_str);
793
794                            // 子节点 current_policy:字段声明则用之,否则 Default
795                            let child_current_policy = if let Some(Value::String(policy_str)) = obj.get(&policy_key) {
796                                parse_policy(policy_str)?
797                            } else {
798                                MergePolicy::Default
799                            };
800
801                            // 当前节点(Map)的行为只由 node_policy 决定;对子节点递归时传 child_current_policy
802                            match node_policy {
803                                MergePolicy::Default | MergePolicy::Merge => {
804                                    if let Some(target_value) = self.get_mut(&key) {
805                                        if let Err(err) = target_value.merge_json_with_policy(source_value, child_current_policy, default_policy) {
806                                                        return Err(err.with_attribute("key", key_str.as_str()));
807                                        }
808                                    } else {
809                                        let mut new_value = V::default();
810                                        if let Err(err) = new_value.merge_json_with_policy(source_value, child_current_policy, default_policy) {
811                                            return Err(err.with_attribute("key", key_str.as_str()));
812                                        }
813                                        self.insert(key, new_value);
814                                    }
815                                }
816                                MergePolicy::Override => {
817                                    let mut new_value = V::default();
818                                    // 覆盖:不递归,直接以 source 写入
819                                    if let Err(err) = new_value.merge_json_with_policy(source_value, child_current_policy, default_policy) {
820                                        return Err(err.with_attribute("key", key_str.as_str()));
821                                    }
822                                    self.insert(key, new_value);
823                                }
824                                MergePolicy::Keep => {
825                                    if !self.contains_key(&key) {
826                                        let mut new_value = V::default();
827                                        if let Err(err) = new_value.merge_json_with_policy(source_value, child_current_policy, default_policy) {
828                                            return Err(err.with_attribute("key", key_str.as_str()));
829                                        }
830                                        self.insert(key, new_value);
831                                    }
832                                }
833                                MergePolicy::Skip => continue,
834                                _ => return Err(AppError::new("INVALID_POLICY", &format!("策略对{}类型无效", $type_name))),
835                            }
836                        }
837                    }
838
839                    if matches!(current_policy, MergePolicy::Override) && obj.is_empty() {
840                        self.clear();
841                    }
842
843                    Ok(())
844                }
845                Value::Null => {
846                    // null 按策略处理:Default/Merge/Keep/Skip 保持不变,Override 清空
847                    match current_policy {
848                        MergePolicy::Override => { self.clear(); Ok(()) }
849                        MergePolicy::Default | MergePolicy::Merge | MergePolicy::Keep | MergePolicy::Skip => Ok(()),
850                        _ => Err(AppError::new("INVALID_POLICY", &format!("策略对{}类型无效", $type_name))),
851                    }
852                }
853                _ => Err(AppError::new("TYPE_MISMATCH", &format!("无法将非对象类型合并到{}", $type_name))),
854            }
855        }
856    };
857}
858
859// 为 HashMap 类型实现 MergeWithTrait(需要 Eq + Hash)
860impl_merge_with_map!(HashMap<K, V>, hash, "HashMap");
861
862// 为 BTreeMap 类型实现 MergeWithTrait(需要 Ord)
863impl_merge_with_map!(BTreeMap<K, V>, ord, "BTreeMap");
864
865// 辅助函数:解析策略字符串
866fn parse_policy(policy_str: &str) -> Result<MergePolicy, AppError> {
867    match policy_str.trim().to_lowercase().as_str() {
868        "default" => Ok(MergePolicy::Default),
869        "merge" => Ok(MergePolicy::Merge),
870        "override" => Ok(MergePolicy::Override),
871        "keep" => Ok(MergePolicy::Keep),
872        "skip" => Ok(MergePolicy::Skip),
873        "vec_append" => Ok(MergePolicy::VecAppend),
874        "string_concat" => Ok(MergePolicy::StringConcat),
875        "boolean_true_win" => Ok(MergePolicy::BooleanTrueWin),
876        "boolean_false_win" => Ok(MergePolicy::BooleanFalseWin),
877        "number_sum" => Ok(MergePolicy::NumberSum),
878        "number_max" => Ok(MergePolicy::NumberMax),
879        "number_min" => Ok(MergePolicy::NumberMin),
880        _ => Err(AppError::new("INVALID_POLICY", &format!("未知的策略字符串: '{}'", policy_str))),
881    }
882}
883
884// ========== serde_json::Value 实现 ==========
885// 为 serde_json::Value 实现 MergeWithTrait 的宏
886// 先根据数据类型分发到不同的内部宏处理
887/// 为 serde_json::Value 实现 MergeWithTrait:
888/// - Object:node_policy 决定对象层如何处理键;child_current_policy(来自 `key._policy_`)传入子节点
889/// - Array:按数组策略合并
890/// - String/Number/Bool/Null:按各自规则合并
891macro_rules! impl_merge_with_value {
892    ($($type:ty),*) => {
893        $(
894            impl MergeWithTrait for $type {
895                #[inline]
896                fn merge_from_with_policy(
897                    &mut self,
898                    source: &Self,
899                    current_policy: MergePolicy,
900                    default_policy: MergePolicy,
901                ) -> Result<(), AppError> {
902                    // 直接调用 merge_json_with_policy,因为 source 本身就是 Value 类型
903                    self.merge_json_with_policy(source, current_policy, default_policy)
904                }
905
906                #[inline]
907                fn merge_json_with_policy(
908                    &mut self,
909                    source: &Value,
910                    current_policy: MergePolicy,
911                    default_policy: MergePolicy,
912                ) -> Result<(), AppError> {
913                    match self {
914                        &mut Value::Object(ref mut target_obj) => {
915                            match source {
916                                Value::Object(source_obj) => {
917                                    // 先计算当前节点(对象)的合并规则
918                                    let node_policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
919
920                                    for (key_str, source_value) in source_obj.iter() {
921                                        if key_str.ends_with("._policy_") { continue; }
922
923                                        // 子节点的 current_policy:若字段声明了 _policy_ 则用之,否则传 Default
924                                        let child_current_policy = get_child_policy(source_obj, key_str)?;
925
926                                        // 当前节点的合并仅由 node_policy 决定;对子节点递归时使用 child_current_policy
927                                        match node_policy {
928                                            // Default/Merge:对已存在键做递归合并;不存在则直接插入
929                                            MergePolicy::Default | MergePolicy::Merge => {
930                                                if let Some(target_value) = target_obj.get_mut(key_str) {
931                                                    if let Err(err) = target_value.merge_json_with_policy(source_value, child_current_policy, default_policy) {
932                                                        return Err(err.with_attribute("key", key_str.as_str()));
933                                                    }
934                                                } else {
935                                                    target_obj.insert(key_str.clone(), source_value.clone());
936                                                }
937                                            }
938                                            // Override:无条件覆盖该键(不递归)
939                                            MergePolicy::Override => {
940                                                target_obj.insert(key_str.clone(), source_value.clone());
941                                            }
942                                            // Keep:仅当不存在该键时插入
943                                            MergePolicy::Keep => {
944                                                if !target_obj.contains_key(key_str) {
945                                                    target_obj.insert(key_str.clone(), source_value.clone());
946                                                }
947                                            }
948                                            // Skip:跳过本层对象的所有字段更新
949                                            MergePolicy::Skip => { /* do nothing */ }
950                                            _ => return Err(AppError::new("INVALID_POLICY", "策略对对象类型无效").with_attribute("key", key_str.as_str())),
951                                        }
952                                    }
953                                    Ok(())
954                                }
955                                _ => Err(AppError::new("TYPE_MISMATCH", "无法将非对象类型合并到对象类型")),
956                            }
957                        }
958                        &mut Value::Array(ref mut target_arr) => {
959                            let policy = resolve_policy(current_policy, default_policy, VEC_APPEND_POLICY);
960                            let source_arr = match source {
961                                Value::Array(arr) => arr.clone(),
962                                _ => vec![source.clone()],
963                            };
964
965                            match policy {
966                                MergePolicy::Default | MergePolicy::VecAppend => {
967                                    for item in source_arr.iter() { target_arr.push(item.clone()); }
968                                    Ok(())
969                                }
970                                MergePolicy::Merge => { if !source_arr.is_empty() { *target_arr = source_arr; } Ok(()) }
971                                MergePolicy::Override => { *target_arr = source_arr; Ok(()) }
972                                MergePolicy::Keep => { if target_arr.is_empty() { *target_arr = source_arr; } Ok(()) }
973                                MergePolicy::Skip => Ok(()),
974                                _ => Err(AppError::new("INVALID_POLICY", "策略对数组类型无效")),
975                            }
976                        }
977                        &mut Value::String(ref mut target_str) => {
978                            let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
979                            let source_str = match source {
980                                Value::String(s) => s.clone(),
981                                Value::Number(n) => {
982                                    // 在 Value -> String 的路径中,不再校验非有限数字
983                                    n.to_string()
984                                },
985                                Value::Bool(b) => b.to_string(),
986                                // 将 null 视为“空输入”,便于在默认(Merge)策略下保持原值
987                                Value::Null => String::new(),
988                                _ => return Err(AppError::new(
989                                    "TYPE_MISMATCH",
990                                    "无法将该类型转换为字符串"
991                                )),
992                            };
993
994                            match policy {
995                                MergePolicy::Override | MergePolicy::Merge => { if !source_str.is_empty() { *target_str = source_str; } Ok(()) }
996                                MergePolicy::StringConcat => {
997                                    let mut result = String::with_capacity(target_str.len() + source_str.len());
998                                    result.push_str(target_str);
999                                    result.push_str(&source_str);
1000                                    *target_str = result;
1001                                    Ok(())
1002                                }
1003                                MergePolicy::Keep => { if target_str.is_empty() { *target_str = source_str; } Ok(()) }
1004                                MergePolicy::Skip => Ok(()),
1005                                _ => Err(AppError::new("INVALID_POLICY", "策略对字符串类型无效")),
1006                            }
1007                        }
1008                        Value::Number(..) => {
1009                            let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
1010                            // source 为 null:默认/合并策略下不变;覆盖策略下置为 null
1011                            if let Value::Null = source {
1012                                return match policy {
1013                                    MergePolicy::Override => { *self = Value::Null; Ok(()) }
1014                                    MergePolicy::Merge | MergePolicy::Default | MergePolicy::Keep | MergePolicy::Skip => Ok(()),
1015                                    _ => Err(AppError::new("INVALID_POLICY", "策略对数字类型无效")),
1016                                };
1017                            }
1018                            let source_num = match source {
1019                                Value::Number(n) => {
1020                                    if let Some(v) = n.as_i64() {
1021                                        v as f64
1022                                    } else if let Some(v) = n.as_u64() {
1023                                        v as f64
1024                                    } else if let Some(v) = n.as_f64() {
1025                                        v
1026                                    } else {
1027                                        return Err(AppError::new("TYPE_MISMATCH", "无法解析数字"));
1028                                    }
1029                                }
1030                                Value::String(s) => {
1031                                    s.parse::<f64>().map_err(|_| {
1032                                        AppError::new("PARSE_ERROR", &format!("无法解析字符串 '{}' 为数字", s))
1033                                    })?
1034                                }
1035                                _ => return Err(AppError::new("TYPE_MISMATCH", "无法将该类型转换为数字")),
1036                            };
1037
1038                            let target_num = if let Value::Number(n) = self {
1039                                if let Some(v) = n.as_i64() {
1040                                    v as f64
1041                                } else if let Some(v) = n.as_u64() {
1042                                    v as f64
1043                                } else if let Some(v) = n.as_f64() {
1044                                    v
1045                                } else {
1046                                    return Err(AppError::new("TYPE_MISMATCH", "无法解析当前数字"));
1047                                }
1048                            } else {
1049                                0.0
1050                            };
1051
1052                            match policy {
1053                                MergePolicy::Override | MergePolicy::Merge => {
1054                                    // 保持原始数字类型
1055                                    if let Value::Number(source_n) = source {
1056                                        *self = Value::Number(source_n.clone());
1057                                    } else {
1058                                        *self = Value::Number(serde_json::Number::from_f64(source_num).ok_or_else(|| AppError::new("INVALID_NUMBER", "无效的数字值"))?);
1059                                    }
1060                                    Ok(())
1061                                }
1062                                MergePolicy::NumberSum => {
1063                                    // 尝试保持整数类型
1064                                    let result = target_num + source_num;
1065                                    if result.fract() == 0.0 && result >= i64::MIN as f64 && result <= i64::MAX as f64 {
1066                                        *self = Value::Number(serde_json::Number::from(result as i64));
1067                                    } else {
1068                                        *self = Value::Number(serde_json::Number::from_f64(result).ok_or_else(|| AppError::new("INVALID_NUMBER", "无效的数字值"))?);
1069                                    }
1070                                    Ok(())
1071                                }
1072                                MergePolicy::NumberMax => {
1073                                    // 尝试保持整数类型
1074                                    let result = target_num.max(source_num);
1075                                    if result.fract() == 0.0 && result >= i64::MIN as f64 && result <= i64::MAX as f64 {
1076                                        *self = Value::Number(serde_json::Number::from(result as i64));
1077                                    } else {
1078                                        *self = Value::Number(serde_json::Number::from_f64(result).ok_or_else(|| AppError::new("INVALID_NUMBER", "无效的数字值"))?);
1079                                    }
1080                                    Ok(())
1081                                }
1082                                MergePolicy::NumberMin => {
1083                                    // 尝试保持整数类型
1084                                    let result = target_num.min(source_num);
1085                                    if result.fract() == 0.0 && result >= i64::MIN as f64 && result <= i64::MAX as f64 {
1086                                        *self = Value::Number(serde_json::Number::from(result as i64));
1087                                    } else {
1088                                        *self = Value::Number(serde_json::Number::from_f64(result).ok_or_else(|| AppError::new("INVALID_NUMBER", "无效的数字值"))?);
1089                                    }
1090                                    Ok(())
1091                                }
1092                                MergePolicy::Keep | MergePolicy::Skip => Ok(()),
1093                                _ => Err(AppError::new("INVALID_POLICY", "策略对数字类型无效")),
1094                            }
1095                        }
1096                        &mut Value::Bool(ref mut target_bool) => {
1097                            let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
1098                            // source 为 null:默认/合并策略下不变;覆盖策略下置为 null
1099                            if let Value::Null = source {
1100                                return match policy {
1101                                    MergePolicy::Override => { *self = Value::Null; Ok(()) }
1102                                    MergePolicy::Merge | MergePolicy::Default | MergePolicy::Keep | MergePolicy::Skip => Ok(()),
1103                                    _ => Err(AppError::new("INVALID_POLICY", "策略对布尔类型无效")),
1104                                };
1105                            }
1106                            let source_bool = match source {
1107                                Value::Bool(b) => *b,
1108                                Value::String(s) => {
1109                                    let trimmed = s.trim();
1110                                    if trimmed.eq_ignore_ascii_case("true")
1111                                        || trimmed.eq_ignore_ascii_case("yes")
1112                                        || trimmed.eq_ignore_ascii_case("on")
1113                                    {
1114                                        true
1115                                    } else if trimmed.eq_ignore_ascii_case("false")
1116                                        || trimmed.eq_ignore_ascii_case("no")
1117                                        || trimmed.eq_ignore_ascii_case("off")
1118                                    {
1119                                        false
1120                                    } else {
1121                                        return Err(AppError::new(
1122                                            "PARSE_ERROR",
1123                                            &format!("无法解析字符串 '{}' 为布尔值", s)
1124                                        ));
1125                                    }
1126                                }
1127                                _ => return Err(AppError::new("TYPE_MISMATCH", "无法将非布尔类型转换为布尔值")),
1128                            };
1129
1130                            match policy {
1131                                MergePolicy::Override | MergePolicy::Merge => { *target_bool = source_bool; Ok(()) }
1132                                MergePolicy::BooleanTrueWin => { *target_bool = *target_bool || source_bool; Ok(()) }
1133                                MergePolicy::BooleanFalseWin => { *target_bool = *target_bool && source_bool; Ok(()) }
1134                                MergePolicy::Keep => Ok(()),
1135                                MergePolicy::Skip => Ok(()),
1136                                _ => Err(AppError::new("INVALID_POLICY", "策略对布尔类型无效")),
1137                            }
1138                        }
1139                        Value::Null => {
1140                            let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
1141                            match policy {
1142                                MergePolicy::Override | MergePolicy::Merge => { *self = source.clone(); Ok(()) }
1143                                MergePolicy::Keep | MergePolicy::Skip => Ok(()),
1144                                _ => Err(AppError::new("INVALID_POLICY", "策略对 null 类型无效")),
1145                            }
1146                        }
1147                    }
1148                }
1149            }
1150        )*
1151    };
1152}
1153
1154// 为 serde_json::Value 实现 MergeWithTrait
1155impl_merge_with_value!(Value);
1156
1157// 针对实现了 EnumTypeTrait + Display + FromStr 的类型,按字符串策略进行合并
1158impl<T> MergeWithTrait for T
1159where
1160    T: EnumTypeTrait + Display + FromStr,
1161    <T as FromStr>::Err: Display,
1162{
1163    fn merge_json_with_policy(
1164        &mut self,
1165        source: &Value,
1166        current_policy: MergePolicy,
1167        default_policy: MergePolicy,
1168    ) -> Result<(), AppError> {
1169        let mut target_str = self.to_string();
1170        target_str.merge_json_with_policy(source, current_policy, default_policy)?;
1171        *self = T::from_str(&target_str).map_err(|e| AppError::new(
1172            "PARSE_ERROR",
1173            &format!("无法将字符串 '{}' 解析为目标枚举: {}", target_str, e),
1174        ))?;
1175        Ok(())
1176    }
1177
1178    fn merge_from_with_policy(
1179        &mut self,
1180        source: &Self,
1181        current_policy: MergePolicy,
1182        default_policy: MergePolicy,
1183    ) -> Result<(), AppError> {
1184        let mut target_str = self.to_string();
1185        let source_str = source.to_string();
1186        target_str.merge_from_with_policy(&source_str, current_policy, default_policy)?;
1187        *self = T::from_str(&target_str).map_err(|e| AppError::new(
1188            "PARSE_ERROR",
1189            &format!("无法将字符串 '{}' 解析为目标枚举: {}", target_str, e),
1190        ))?;
1191        Ok(())
1192    }
1193}
1194
1195/// 便捷函数:合并两个 JSON Value,返回合并后的新值
1196pub fn merge_json(target: &Value, source: &Value) -> Result<Value, AppError> {
1197    let mut result = target.clone();
1198    result.merge_json(source)?;
1199    Ok(result)
1200}