merge.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. use super::{use_filter, use_lowercase};
  2. use serde_yaml::{self, Mapping, Sequence, Value};
  3. const MERGE_FIELDS: [&str; 10] = [
  4. "prepend-rules",
  5. "append-rules",
  6. "prepend-rule-providers",
  7. "append-rule-providers",
  8. "prepend-proxies",
  9. "append-proxies",
  10. "prepend-proxy-providers",
  11. "append-proxy-providers",
  12. "prepend-proxy-groups",
  13. "append-proxy-groups",
  14. ];
  15. pub fn use_merge(merge: Mapping, mut config: Mapping) -> Mapping {
  16. // 直接覆盖原字段
  17. use_lowercase(merge.clone())
  18. .into_iter()
  19. .filter(|(key, _)| !MERGE_FIELDS.contains(&key.as_str().unwrap_or_default()))
  20. .for_each(|(key, value)| {
  21. config.insert(key, value);
  22. });
  23. let merge_list = MERGE_FIELDS.iter().map(|s| s.to_string());
  24. let merge = use_filter(merge, &merge_list.collect());
  25. ["rule-providers", "proxy-providers"]
  26. .iter()
  27. .for_each(|key_str| {
  28. let key_val = Value::from(key_str.to_string());
  29. let mut map = Mapping::default();
  30. map = config.get(&key_val).map_or(map.clone(), |val| {
  31. val.as_mapping().map_or(map, |v| v.clone())
  32. });
  33. let pre_key = Value::from(format!("prepend-{key_str}"));
  34. let post_key = Value::from(format!("append-{key_str}"));
  35. if let Some(pre_val) = merge.get(&pre_key) {
  36. if pre_val.is_mapping() {
  37. let mut pre_val = pre_val.as_mapping().unwrap().clone();
  38. pre_val.extend(map);
  39. map = pre_val;
  40. }
  41. }
  42. if let Some(post_val) = merge.get(&post_key) {
  43. if post_val.is_mapping() {
  44. map.extend(post_val.as_mapping().unwrap().clone());
  45. }
  46. }
  47. if !map.is_empty() {
  48. config.insert(key_val, Value::from(map));
  49. }
  50. });
  51. ["rules", "proxies", "proxy-groups"]
  52. .iter()
  53. .for_each(|key_str| {
  54. let key_val = Value::from(key_str.to_string());
  55. let mut list = Sequence::default();
  56. list = config.get(&key_val).map_or(list.clone(), |val| {
  57. val.as_sequence().map_or(list, |v| v.clone())
  58. });
  59. let pre_key = Value::from(format!("prepend-{key_str}"));
  60. let post_key = Value::from(format!("append-{key_str}"));
  61. if let Some(pre_val) = merge.get(&pre_key) {
  62. if pre_val.is_sequence() {
  63. let mut pre_val = pre_val.as_sequence().unwrap().clone();
  64. pre_val.extend(list);
  65. list = pre_val;
  66. }
  67. }
  68. if let Some(post_val) = merge.get(&post_key) {
  69. if post_val.is_sequence() {
  70. list.extend(post_val.as_sequence().unwrap().clone());
  71. }
  72. }
  73. if !list.is_empty() {
  74. config.insert(key_val, Value::from(list));
  75. }
  76. });
  77. config
  78. }
  79. #[test]
  80. fn test_merge() -> anyhow::Result<()> {
  81. let merge = r"
  82. prepend-rules:
  83. - prepend
  84. - 1123123
  85. append-rules:
  86. - append
  87. prepend-proxies:
  88. - 9999
  89. append-proxies:
  90. - 1111
  91. rules:
  92. - replace
  93. proxy-groups:
  94. - 123781923810
  95. tun:
  96. enable: true
  97. dns:
  98. enable: true
  99. ";
  100. let config = r"
  101. rules:
  102. - aaaaa
  103. script1: test
  104. ";
  105. let merge = serde_yaml::from_str::<Mapping>(merge)?;
  106. let config = serde_yaml::from_str::<Mapping>(config)?;
  107. let result = serde_yaml::to_string(&use_merge(merge, config))?;
  108. println!("{result}");
  109. Ok(())
  110. }