1use 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
44static MERGE_POLICY: MergePolicy = MergePolicy::Merge;
46static VEC_APPEND_POLICY: MergePolicy = MergePolicy::VecAppend;
47static DEFAULT_POLICY: MergePolicy = MergePolicy::Default;
48
49#[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#[inline(always)]
69fn resolve_policy(current: MergePolicy, default: MergePolicy, expect: MergePolicy) -> MergePolicy {
70 match current {
72 MergePolicy::Default => match default {
73 MergePolicy::Default => expect,
74 _ => default,
75 },
76 _ => current,
77 }
78}
79
80pub trait MergeWithTrait {
81 fn merge_json(&mut self, source: &Value) -> Result<(), AppError> {
83 self.merge_json_with_policy(source, DEFAULT_POLICY, DEFAULT_POLICY)
84 }
85
86 fn merge_from(&mut self, source: &Self) -> Result<(), AppError> {
88 self.merge_from_with_policy(source, DEFAULT_POLICY, DEFAULT_POLICY)
89 }
90
91 fn merge_json_with_policy(&mut self, source: &Value, current_policy: MergePolicy, default_policy: MergePolicy) -> Result<(), AppError>;
93
94 fn merge_from_with_policy(&mut self, source: &Self, current_policy: MergePolicy, default_policy: MergePolicy) -> Result<(), AppError>;
96}
97
98macro_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 let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
120
121 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 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 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
182macro_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 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 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() } 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
271macro_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 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 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
350impl_merge_with_number!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64);
352
353impl_merge_with_string!(String);
355
356impl_merge_with_bool!(bool);
358
359macro_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 let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
384
385 match policy {
386 MergePolicy::Merge => {
387 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 }
409 }
410 Ok(())
411 }
412 MergePolicy::Override => {
413 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 match self {
441 Some(_) => {
442 }
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 let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
475
476 match policy {
477 MergePolicy::Merge => {
478 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 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 match self {
510 Some(_) => {
511 }
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
535impl_merge_with_option!(Option<T>);
537
538macro_rules! impl_merge_with_array {
548 ($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 ($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 ($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
577macro_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 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 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
689impl_merge_with_array!(Vec<T>, push, "Vec");
691
692impl_merge_with_array!(HashSet<T>, insert, hash, "HashSet");
694
695impl_merge_with_array!(BTreeSet<T>, insert, ord, "BTreeSet");
697
698macro_rules! impl_merge_with_map {
707 ($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 ($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
731macro_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 let policy = resolve_policy(current_policy, default_policy, MERGE_POLICY);
738
739 match policy {
741 MergePolicy::Default | MergePolicy::Merge => {
742 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 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 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 if let Ok(key) = key_str.parse::<K>() {
791 let policy_key = format!("{}._policy_", key_str);
793
794 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 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 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 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
859impl_merge_with_map!(HashMap<K, V>, hash, "HashMap");
861
862impl_merge_with_map!(BTreeMap<K, V>, ord, "BTreeMap");
864
865fn 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
884macro_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 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 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 let child_current_policy = get_child_policy(source_obj, key_str)?;
925
926 match node_policy {
928 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 MergePolicy::Override => {
940 target_obj.insert(key_str.clone(), source_value.clone());
941 }
942 MergePolicy::Keep => {
944 if !target_obj.contains_key(key_str) {
945 target_obj.insert(key_str.clone(), source_value.clone());
946 }
947 }
948 MergePolicy::Skip => { }
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 n.to_string()
984 },
985 Value::Bool(b) => b.to_string(),
986 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 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 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 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 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 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 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
1154impl_merge_with_value!(Value);
1156
1157impl<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
1195pub 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}