1package jsons
2
3import (
4 "fmt"
5 "io"
6 "os"
7)
8
9// LoadFunc load the input bytes to map[string]interface{}
10type LoadFunc func([]byte) (map[string]interface{}, error)
11
12// loader is a configurable loader for specific format files.
13type loader struct {
14 Name Format
15 Extensions []string
16 LoadFunc LoadFunc
17}
18
19// makeLoader makes a merger who merge the format by converting it to JSON
20func newLoader(name Format, extensions []string, fn LoadFunc) *loader {
21 return &loader{
22 Name: name,
23 Extensions: extensions,
24 LoadFunc: fn,
25 }
26}
27
28// makeLoadFunc makes a merge func who merge the input to
29func (l *loader) Load(input interface{}) ([]map[string]interface{}, error) {
30 if input == nil {
31 return nil, nil
32 }
33 switch v := input.(type) {
34 case string:
35 return l.loadFiles([]string{v})
36 case []string:
37 return l.loadFiles(v)
38 case []byte:
39 return l.loadSlices([][]byte{v})
40 case [][]byte:
41 return l.loadSlices(v)
42 case io.Reader:
43 return l.loadReaders([]io.Reader{v})
44 case []io.Reader:
45 return l.loadReaders(v)
46 default:
47 return nil, fmt.Errorf("unsupported input type: %T", input)
48 }
49}
50
51func (l *loader) loadFiles(files []string) ([]map[string]interface{}, error) {
52 maps := make([]map[string]interface{}, 0, len(files))
53 for _, file := range files {
54 m, err := l.loadFile(file)
55 if err != nil {
56 return nil, err
57 }
58 maps = append(maps, m)
59 }
60 return maps, nil
61}
62
63func (l *loader) loadReaders(readers []io.Reader) ([]map[string]interface{}, error) {
64 maps := make([]map[string]interface{}, 0, len(readers))
65 for _, r := range readers {
66 m, err := l.loadReader(r)
67 if err != nil {
68 return nil, err
69 }
70 maps = append(maps, m)
71 }
72 return maps, nil
73}
74
75func (l *loader) loadSlices(slices [][]byte) ([]map[string]interface{}, error) {
76 maps := make([]map[string]interface{}, 0, len(slices))
77 for _, slice := range slices {
78 m, err := l.LoadFunc(slice)
79 if err != nil {
80 return nil, err
81 }
82 maps = append(maps, m)
83 }
84 return maps, nil
85}
86
87func (l *loader) loadFile(file string) (map[string]interface{}, error) {
88 bs, err := os.ReadFile(file)
89 if err != nil {
90 return nil, err
91 }
92 return l.LoadFunc(bs)
93}
94
95func (l *loader) loadReader(reader io.Reader) (map[string]interface{}, error) {
96 bs, err := io.ReadAll(reader)
97 if err != nil {
98 return nil, err
99 }
100 return l.LoadFunc(bs)
101}