merge.go 2.0 KB

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