github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/infra/conf/mergers/merger_base.go (about) 1 package mergers 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/v2fly/v2ray-core/v5/common/cmdarg" 8 "github.com/v2fly/v2ray-core/v5/common/errors" 9 "github.com/v2fly/v2ray-core/v5/infra/conf/merge" 10 ) 11 12 type jsonConverter func(v []byte) ([]byte, error) 13 14 // makeMerger makes a merger who merge the format by converting it to JSON 15 func makeMerger(name string, extensions []string, converter jsonConverter) *Merger { 16 return &Merger{ 17 Name: name, 18 Extensions: extensions, 19 Merge: makeToJSONMergeFunc(converter), 20 } 21 } 22 23 // makeToJSONMergeFunc makes a merge func who merge the format by converting it to JSON 24 func makeToJSONMergeFunc(converter func(v []byte) ([]byte, error)) MergeFunc { 25 return func(input interface{}, target map[string]interface{}) error { 26 if input == nil { 27 return nil 28 } 29 if target == nil { 30 return errors.New("merge target is nil") 31 } 32 switch v := input.(type) { 33 case string: 34 err := loadFile(v, target, converter) 35 if err != nil { 36 return err 37 } 38 case []string: 39 err := loadFiles(v, target, converter) 40 if err != nil { 41 return err 42 } 43 case cmdarg.Arg: 44 err := loadFiles(v, target, converter) 45 if err != nil { 46 return err 47 } 48 case []byte: 49 err := loadBytes(v, target, converter) 50 if err != nil { 51 return err 52 } 53 case io.Reader: 54 err := loadReader(v, target, converter) 55 if err != nil { 56 return err 57 } 58 default: 59 return newError("unknown merge input type") 60 } 61 return nil 62 } 63 } 64 65 func loadFiles(files []string, target map[string]interface{}, converter func(v []byte) ([]byte, error)) error { 66 for _, file := range files { 67 err := loadFile(file, target, converter) 68 if err != nil { 69 return err 70 } 71 } 72 return nil 73 } 74 75 func loadFile(file string, target map[string]interface{}, converter func(v []byte) ([]byte, error)) error { 76 bs, err := cmdarg.LoadArgToBytes(file) 77 if err != nil { 78 return fmt.Errorf("fail to load %s: %s", file, err) 79 } 80 if converter != nil { 81 bs, err = converter(bs) 82 if err != nil { 83 return fmt.Errorf("error convert to json '%s': %s", file, err) 84 } 85 } 86 _, err = merge.ToMap(bs, target) 87 return err 88 } 89 90 func loadReader(reader io.Reader, target map[string]interface{}, converter func(v []byte) ([]byte, error)) error { 91 bs, err := io.ReadAll(reader) 92 if err != nil { 93 return err 94 } 95 return loadBytes(bs, target, converter) 96 } 97 98 func loadBytes(bs []byte, target map[string]interface{}, converter func(v []byte) ([]byte, error)) error { 99 var err error 100 if converter != nil { 101 bs, err = converter(bs) 102 if err != nil { 103 return fmt.Errorf("fail to convert to json: %s", err) 104 } 105 } 106 _, err = merge.ToMap(bs, target) 107 return err 108 }