merge.go 2.0 KB

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