summaryrefslogtreecommitdiff
path: root/lib/instance.go
blob: d2f5e00b7b31704e8bd183eab845cd9b3e5be059 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package lib

import (
	"encoding/json"
	"errors"
	"os"
	"strings"

	"github.com/tailscale/hujson"
)

type Instance interface {
	InitConfig(configFile string) error
	InitConfigFromBytes(content []byte) error
	AddInput(InputConverter)
	AddOutput(OutputConverter)
	ResetInput()
	ResetOutput()
	RunInput(Container) error
	RunOutput(Container) error
	Run() error
}

type instance struct {
	input  []InputConverter
	output []OutputConverter
}

func NewInstance() (Instance, error) {
	return &instance{
		input:  make([]InputConverter, 0),
		output: make([]OutputConverter, 0),
	}, nil
}

func (i *instance) InitConfig(configFile string) error {
	var content []byte
	var err error
	configFile = strings.TrimSpace(configFile)
	if strings.HasPrefix(strings.ToLower(configFile), "http://") || strings.HasPrefix(strings.ToLower(configFile), "https://") {
		content, err = GetRemoteURLContent(configFile)
	} else {
		content, err = os.ReadFile(configFile)
	}
	if err != nil {
		return err
	}

	return i.InitConfigFromBytes(content)
}

func (i *instance) InitConfigFromBytes(content []byte) error {
	config := new(config)

	// Support JSON with comments and trailing commas
	content, _ = hujson.Standardize(content)

	if err := json.Unmarshal(content, &config); err != nil {
		return err
	}

	for _, input := range config.Input {
		i.input = append(i.input, input.converter)
	}

	for _, output := range config.Output {
		i.output = append(i.output, output.converter)
	}

	return nil
}

func (i *instance) AddInput(ic InputConverter) {
	i.input = append(i.input, ic)
}

func (i *instance) AddOutput(oc OutputConverter) {
	i.output = append(i.output, oc)
}

func (i *instance) ResetInput() {
	i.input = make([]InputConverter, 0)
}

func (i *instance) ResetOutput() {
	i.output = make([]OutputConverter, 0)
}

func (i *instance) RunInput(container Container) error {
	var err error
	for _, ic := range i.input {
		container, err = ic.Input(container)
		if err != nil {
			return err
		}
	}

	return nil
}

func (i *instance) RunOutput(container Container) error {
	for _, oc := range i.output {
		if err := oc.Output(container); err != nil {
			return err
		}
	}

	return nil
}

func (i *instance) Run() error {
	if len(i.input) == 0 || len(i.output) == 0 {
		return errors.New("input type and output type must be specified")
	}

	container := NewContainer()

	if err := i.RunInput(container); err != nil {
		return err
	}

	if err := i.RunOutput(container); err != nil {
		return err
	}

	return nil
}