github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/infra/conf/mergers/merge.go (about) 1 package mergers 2 3 import ( 4 "io" 5 "path/filepath" 6 "strings" 7 8 core "github.com/v2fly/v2ray-core/v5" 9 "github.com/v2fly/v2ray-core/v5/common/cmdarg" 10 ) 11 12 // MergeAs load input and merge as specified format into m 13 func MergeAs(formatName string, input interface{}, m map[string]interface{}) error { 14 f, found := mergersByName[formatName] 15 if !found { 16 return newError("format merger not found for: ", formatName) 17 } 18 return f.Merge(input, m) 19 } 20 21 // Merge loads inputs and merges them into m 22 // it detects extension for merger selecting, or try all mergers 23 // if no extension found 24 func Merge(input interface{}, m map[string]interface{}) error { 25 if input == nil { 26 return nil 27 } 28 switch v := input.(type) { 29 case string: 30 err := mergeSingleFile(v, m) 31 if err != nil { 32 return err 33 } 34 case []string: 35 for _, file := range v { 36 err := mergeSingleFile(file, m) 37 if err != nil { 38 return err 39 } 40 } 41 case cmdarg.Arg: 42 for _, file := range v { 43 err := mergeSingleFile(file, m) 44 if err != nil { 45 return err 46 } 47 } 48 case []byte: 49 err := mergeSingleFile(v, m) 50 if err != nil { 51 return err 52 } 53 case io.Reader: 54 // read to []byte incase it tries different mergers 55 bs, err := io.ReadAll(v) 56 if err != nil { 57 return err 58 } 59 err = mergeSingleFile(bs, m) 60 if err != nil { 61 return err 62 } 63 default: 64 return newError("unknown merge input type") 65 } 66 return nil 67 } 68 69 func mergeSingleFile(input interface{}, m map[string]interface{}) error { 70 if file, ok := input.(string); ok { 71 ext := getExtension(file) 72 if ext != "" { 73 lext := strings.ToLower(ext) 74 f, found := mergersByExt[lext] 75 if !found { 76 return newError("unmergeable format extension: ", ext) 77 } 78 return f.Merge(file, m) 79 } 80 } 81 // no extension, try all mergers 82 for _, f := range mergersByName { 83 if f.Name == core.FormatAuto { 84 continue 85 } 86 err := f.Merge(input, m) 87 if err == nil { 88 return nil 89 } 90 } 91 return newError("tried all mergers but failed for: ", input).AtWarning() 92 } 93 94 func getExtension(filename string) string { 95 ext := filepath.Ext(filename) 96 return strings.ToLower(ext) 97 }