| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- // Copyright 2020 Jebbs. All rights reserved.
- // Use of this source code is governed by MIT
- // license that can be found in the LICENSE file.
- /*
- Package merge provides the capbility to merge multiple
- 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"
- "io"
- "github.com/v2fly/v2ray-core/v4/common/cmdarg"
- "github.com/v2fly/v2ray-core/v4/infra/conf/serial"
- )
- // FilesToJSON merges multiple jsons files into one json, accepts remote url, or local file path
- func FilesToJSON(args []string) ([]byte, error) {
- m, err := FilesToMap(args)
- if err != nil {
- return nil, err
- }
- return json.Marshal(m)
- }
- // BytesToJSON merges multiple json contents into one json.
- func BytesToJSON(args [][]byte) ([]byte, error) {
- m, err := BytesToMap(args)
- if err != nil {
- return nil, err
- }
- return json.Marshal(m)
- }
- // FilesToMap merges multiple json files into one map, accepts remote url, or local file path
- func FilesToMap(args []string) (m map[string]interface{}, err error) {
- m, err = loadFiles(args)
- if err != nil {
- return nil, err
- }
- err = applyRules(m)
- if err != nil {
- return nil, err
- }
- return m, nil
- }
- // BytesToMap merges multiple json contents into one map.
- func BytesToMap(args [][]byte) (m map[string]interface{}, err error) {
- m, err = loadBytes(args)
- if err != nil {
- return nil, err
- }
- err = applyRules(m)
- if err != nil {
- return nil, err
- }
- return m, nil
- }
- func loadFiles(args []string) (map[string]interface{}, error) {
- c := make(map[string]interface{})
- for _, arg := range args {
- r, err := cmdarg.LoadArg(arg)
- if err != nil {
- return nil, err
- }
- m, err := decode(r)
- if err != nil {
- return nil, err
- }
- if err = mergeMaps(c, m); err != nil {
- return nil, err
- }
- }
- return c, nil
- }
- func loadBytes(args [][]byte) (map[string]interface{}, error) {
- conf := make(map[string]interface{})
- for _, arg := range args {
- r := bytes.NewReader(arg)
- m, err := decode(r)
- if err != nil {
- return nil, err
- }
- if err = mergeMaps(conf, m); err != nil {
- return nil, err
- }
- }
- return conf, nil
- }
- func decode(r io.Reader) (map[string]interface{}, error) {
- c := make(map[string]interface{})
- err := serial.DecodeJSON(r, &c)
- if err != nil {
- return nil, err
- }
- return c, nil
- }
|