-
Notifications
You must be signed in to change notification settings - Fork 2
/
parse.go
123 lines (118 loc) · 2.88 KB
/
parse.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
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
// Use and distribution licensed under the Apache license version 2.
//
// See the COPYING file in the root project directory for full text.
package http
import (
"strings"
"github.com/gdt-dev/gdt/errors"
gdttypes "github.com/gdt-dev/gdt/types"
"github.com/samber/lo"
"gopkg.in/yaml.v3"
)
func (s *Spec) UnmarshalYAML(node *yaml.Node) error {
if node.Kind != yaml.MappingNode {
return errors.ExpectedMapAt(node)
}
// maps/structs are stored in a top-level Node.Content field which is a
// concatenated slice of Node pointers in pairs of key/values.
for i := 0; i < len(node.Content); i += 2 {
keyNode := node.Content[i]
if keyNode.Kind != yaml.ScalarNode {
return errors.ExpectedScalarAt(keyNode)
}
key := keyNode.Value
valNode := node.Content[i+1]
switch key {
case "url":
if valNode.Kind != yaml.ScalarNode {
return errors.ExpectedScalarAt(valNode)
}
s.URL = strings.TrimSpace(valNode.Value)
case "method":
if valNode.Kind != yaml.ScalarNode {
return errors.ExpectedScalarAt(valNode)
}
s.Method = strings.TrimSpace(valNode.Value)
case "GET":
if valNode.Kind != yaml.ScalarNode {
return errors.ExpectedScalarAt(valNode)
}
s.GET = strings.TrimSpace(valNode.Value)
case "POST":
if valNode.Kind != yaml.ScalarNode {
return errors.ExpectedScalarAt(valNode)
}
s.POST = strings.TrimSpace(valNode.Value)
case "PUT":
if valNode.Kind != yaml.ScalarNode {
return errors.ExpectedScalarAt(valNode)
}
s.PUT = strings.TrimSpace(valNode.Value)
case "DELETE":
if valNode.Kind != yaml.ScalarNode {
return errors.ExpectedScalarAt(valNode)
}
s.DELETE = strings.TrimSpace(valNode.Value)
case "PATCH":
if valNode.Kind != yaml.ScalarNode {
return errors.ExpectedScalarAt(valNode)
}
s.PATCH = strings.TrimSpace(valNode.Value)
case "data":
var data interface{}
if err := valNode.Decode(&data); err != nil {
return err
}
s.Data = data
case "assert":
if valNode.Kind != yaml.MappingNode {
return errors.ExpectedMapAt(valNode)
}
var exp *Expect
if err := valNode.Decode(&exp); err != nil {
return err
}
s.Assert = exp
default:
if lo.Contains(gdttypes.BaseSpecFields, key) {
continue
}
return errors.UnknownFieldAt(key, keyNode)
}
}
if err := validateMethodAndURL(s); err != nil {
return err
}
return nil
}
func validateMethodAndURL(s *Spec) error {
if s.URL == "" {
if s.GET != "" {
s.Method = "GET"
s.URL = s.GET
return nil
} else if s.POST != "" {
s.Method = "POST"
s.URL = s.POST
return nil
} else if s.PUT != "" {
s.Method = "PUT"
s.URL = s.PUT
return nil
} else if s.DELETE != "" {
s.Method = "DELETE"
s.URL = s.DELETE
return nil
} else if s.PATCH != "" {
s.Method = "PATCH"
s.URL = s.PATCH
return nil
} else {
return ErrAliasOrURL
}
}
if s.Method == "" {
return ErrAliasOrURL
}
return nil
}