loader.go

  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}