2020-11-28 09:06:03 -05:00
|
|
|
// Copyright 2020 Jebbs. All rights reserved.
|
|
|
|
// Use of this source code is governed by MIT
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
/*
|
2021-12-26 23:33:08 -05:00
|
|
|
Package merge provides the capability to merge multiple
|
2020-11-28 09:06:03 -05:00
|
|
|
JSON files or contents into one output.
|
|
|
|
|
|
|
|
Merge Rules:
|
|
|
|
|
|
|
|
- Simple values (string, number, boolean) are overwritten, others are merged
|
|
|
|
- Elements with same "tag" (or "_tag") in an array will be merged
|
|
|
|
- Add "_priority" property to array elements will help sort the
|
|
|
|
|
|
|
|
*/
|
|
|
|
package merge
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
2020-12-02 17:11:24 -05:00
|
|
|
|
2022-01-02 10:16:23 -05:00
|
|
|
"github.com/v2fly/v2ray-core/v5/infra/conf/serial"
|
2020-11-28 09:06:03 -05:00
|
|
|
)
|
|
|
|
|
2021-02-21 10:02:42 -05:00
|
|
|
// JSONs merges multiple json contents into one json.
|
|
|
|
func JSONs(args [][]byte) ([]byte, error) {
|
|
|
|
m := make(map[string]interface{})
|
|
|
|
for _, arg := range args {
|
|
|
|
if _, err := ToMap(arg, m); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-11-28 09:06:03 -05:00
|
|
|
}
|
2021-02-21 10:02:42 -05:00
|
|
|
return FromMap(m)
|
2020-11-28 09:06:03 -05:00
|
|
|
}
|
|
|
|
|
2021-02-21 10:02:42 -05:00
|
|
|
// ToMap merges json content to target map and returns it
|
|
|
|
func ToMap(content []byte, target map[string]interface{}) (map[string]interface{}, error) {
|
|
|
|
if target == nil {
|
|
|
|
target = make(map[string]interface{})
|
2020-11-28 09:06:03 -05:00
|
|
|
}
|
2021-02-21 10:02:42 -05:00
|
|
|
r := bytes.NewReader(content)
|
|
|
|
n := make(map[string]interface{})
|
|
|
|
err := serial.DecodeJSON(r, &n)
|
2020-11-28 09:06:03 -05:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-02-21 10:02:42 -05:00
|
|
|
if err = mergeMaps(target, n); err != nil {
|
2020-11-28 09:06:03 -05:00
|
|
|
return nil, err
|
|
|
|
}
|
2021-02-21 10:02:42 -05:00
|
|
|
return target, nil
|
2020-11-28 09:06:03 -05:00
|
|
|
}
|
|
|
|
|
2021-02-21 10:02:42 -05:00
|
|
|
// FromMap apply merge rules to map and convert it to json
|
|
|
|
func FromMap(target map[string]interface{}) ([]byte, error) {
|
|
|
|
if target == nil {
|
|
|
|
target = make(map[string]interface{})
|
2020-11-28 09:06:03 -05:00
|
|
|
}
|
2021-02-21 10:02:42 -05:00
|
|
|
err := ApplyRules(target)
|
2020-12-02 17:11:24 -05:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-02-21 10:02:42 -05:00
|
|
|
return json.Marshal(target)
|
2020-12-02 17:11:24 -05:00
|
|
|
}
|