merge.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // Copyright 2020 Jebbs. All rights reserved.
  2. // Use of this source code is governed by MIT
  3. // license that can be found in the LICENSE file.
  4. /*
  5. Package merge provides the capbility to merge multiple
  6. JSON files or contents into one output.
  7. Merge Rules:
  8. - Simple values (string, number, boolean) are overwritten, others are merged
  9. - Elements with same "tag" (or "_tag") in an array will be merged
  10. - Add "_priority" property to array elements will help sort the
  11. */
  12. package merge
  13. import (
  14. "bytes"
  15. "encoding/json"
  16. "github.com/v2fly/v2ray-core/v4/infra/conf/serial"
  17. )
  18. // JSONs merges multiple json contents into one json.
  19. func JSONs(args [][]byte) ([]byte, error) {
  20. m := make(map[string]interface{})
  21. for _, arg := range args {
  22. if _, err := ToMap(arg, m); err != nil {
  23. return nil, err
  24. }
  25. }
  26. return FromMap(m)
  27. }
  28. // ToMap merges json content to target map and returns it
  29. func ToMap(content []byte, target map[string]interface{}) (map[string]interface{}, error) {
  30. if target == nil {
  31. target = make(map[string]interface{})
  32. }
  33. r := bytes.NewReader(content)
  34. n := make(map[string]interface{})
  35. err := serial.DecodeJSON(r, &n)
  36. if err != nil {
  37. return nil, err
  38. }
  39. if err = mergeMaps(target, n); err != nil {
  40. return nil, err
  41. }
  42. return target, nil
  43. }
  44. // FromMap apply merge rules to map and convert it to json
  45. func FromMap(target map[string]interface{}) ([]byte, error) {
  46. if target == nil {
  47. target = make(map[string]interface{})
  48. }
  49. err := ApplyRules(target)
  50. if err != nil {
  51. return nil, err
  52. }
  53. return json.Marshal(target)
  54. }