merge.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package mergers
  2. import (
  3. "io"
  4. "path/filepath"
  5. "strings"
  6. core "github.com/v2fly/v2ray-core/v4"
  7. "github.com/v2fly/v2ray-core/v4/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. switch v := input.(type) {
  22. case string:
  23. err := mergeSingleFile(v, m)
  24. if err != nil {
  25. return err
  26. }
  27. case []string:
  28. for _, file := range v {
  29. err := mergeSingleFile(file, m)
  30. if err != nil {
  31. return err
  32. }
  33. }
  34. case cmdarg.Arg:
  35. for _, file := range v {
  36. err := mergeSingleFile(file, m)
  37. if err != nil {
  38. return err
  39. }
  40. }
  41. case []byte:
  42. err := mergeSingleFile(v, m)
  43. if err != nil {
  44. return err
  45. }
  46. case io.Reader:
  47. // read to []byte incase it tries different mergers
  48. bs, err := io.ReadAll(v)
  49. if err != nil {
  50. return err
  51. }
  52. err = mergeSingleFile(bs, m)
  53. if err != nil {
  54. return err
  55. }
  56. default:
  57. return newError("unknow merge input type")
  58. }
  59. return nil
  60. }
  61. func mergeSingleFile(input interface{}, m map[string]interface{}) error {
  62. if file, ok := input.(string); ok {
  63. ext := getExtension(file)
  64. if ext != "" {
  65. lext := strings.ToLower(ext)
  66. f, found := mergersByExt[lext]
  67. if !found {
  68. return newError("unmergeable format extension: ", ext)
  69. }
  70. return f.Merge(file, m)
  71. }
  72. }
  73. // no extension, try all mergers
  74. for _, f := range mergersByName {
  75. if f.Name == core.FormatAuto {
  76. continue
  77. }
  78. err := f.Merge(input, m)
  79. if err == nil {
  80. return nil
  81. }
  82. }
  83. return newError("tried all mergers but failed for: ", input).AtWarning()
  84. }
  85. func getExtension(filename string) string {
  86. ext := filepath.Ext(filename)
  87. return strings.ToLower(ext)
  88. }