-
Notifications
You must be signed in to change notification settings - Fork 0
/
io.go
92 lines (77 loc) · 2.17 KB
/
io.go
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
package subject
import (
"fmt"
"reflect"
)
// IO is a type which can describe input/output fields
type IO struct {
reflect.Value `json:"-"`
Name string `json:"name"`
TypeStr string `json:"type"`
}
// NewIO return a new IO type
func NewIO(field reflect.StructField, value reflect.Value) IO {
return IO{
Value: value,
Name: field.Name,
TypeStr: field.Type.String(),
}
}
// Compatible returns whether or not this output is compatible with another.
// Two outputs are compatible if they have the same name and the same type
func (io *IO) Compatible(other Output) bool {
return io.Name == other.Name && io.TypeStr == other.TypeStr
}
// Key returns the key uniqely describing the input/output
func (io *IO) Key(name string) string {
return fmt.Sprintf("%s:%s", name, io.Name)
}
// Input describes the type of input and the ingredients used
type Input struct {
IO
Recipe []*Ingredient `json:"recipe"`
}
// NewInput returns a new input object from a struct field and value
func NewInput(field reflect.StructField, value reflect.Value) *Input {
return &Input{
IO: NewIO(field, value),
Recipe: make([]*Ingredient, 0),
}
}
// CopyRecipe assigns the recipe from raw json data
func (i *Input) CopyRecipe(input *Input) error {
if i.Name != input.Name {
return fmt.Errorf("Input name %s does not match %s", i.Name, input.Name)
}
if i.TypeStr != input.TypeStr {
return fmt.Errorf("Input type %s does not match %s", input.TypeStr, i.TypeStr)
}
i.Recipe = input.Recipe
return nil
}
// AddIngredient adds an ingredient to the input
func (i *Input) AddIngredient(ingr *Ingredient) {
i.Recipe = append(i.Recipe, ingr)
}
// Validate makes sure that ingredients are given
func (i *Input) Validate() error {
if len(i.Recipe) == 0 {
return fmt.Errorf("Missing ingredient for input '%s'", i.Name)
}
for _, ingr := range i.Recipe {
if err := ingr.Validate(); err != nil {
return err
}
}
return nil
}
// Output describes the name and type of an output
type Output struct {
IO
}
// NewOutput returns a new output object from a struct field and value
func NewOutput(field reflect.StructField, value reflect.Value) *Output {
return &Output{
NewIO(field, value),
}
}