-
Notifications
You must be signed in to change notification settings - Fork 33
/
parse.go
113 lines (94 loc) · 3.22 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
package owl
import (
"encoding/json"
"fmt"
"strings"
)
// Constants representing different specification names.
// These constants are of type SpecName and are assigned string values.
const (
SpecNameOpaque string = "Opaque" // SpecNameOpaque specifies an opaque specification.
SpecNamePlain string = "Plain" // SpecNamePlain specifies a plain specification.
SpecNameSecret string = "Secret" // SpecNameSecret specifies a secret specification.
SpecNamePassword string = "Password" // SpecNamePassword specifies a password specification.
SpecNameDefault = SpecNameOpaque
)
// Spec represents the available configuration options and their flags.
type Spec struct {
Name string
Required bool // Indicates whether the configuration is required.
Valid bool // Indicates whether the configuration is valid.
}
// Specs represents a collection of configuration specifications.
type Specs map[string]Spec
// Define the mapping between flags and their corresponding specifications.
var allowedSpecs = map[string]func(*Spec, string, map[string]interface{}){
SpecNameOpaque: handleParams,
SpecNamePlain: handleParams,
SpecNameSecret: handleParams,
SpecNamePassword: handleParams,
}
// Handler function to validate various types of input
func handleParams(spec *Spec, value string, params map[string]interface{}) {
if strings.TrimSpace(value) != "" {
spec.Valid = true
if spec.Required && params != nil {
if length, ok := params["length"].(float64); ok {
spec.Valid = len(value) == int(length)
}
}
}
}
// GenerateSpecsFromComments maps comments to configuration key specifications.
func ParseRawSpec(values map[string]string, comments map[string]string) Specs {
// Initialize a new Specs map to store configuration specifications.
specs := make(Specs)
// Iterate through each key-value pair in the comments map.
for key, value := range values {
// Initialize a new Spec instance.
spec := Spec{Name: SpecNameDefault}
comment := comments[key]
// Skip empty comments.
if comment == "" {
specs[key] = spec
continue
}
// Split the comment into name and parameter.
parts := strings.SplitN(comment, ":", 2)
name := upperFirstLetter(parts[0])
var params string
var jsonMap map[string]interface{}
if len(parts) > 1 {
params = parts[1]
bytes := []byte(params)
jsonMap = make(map[string]interface{})
if err := json.Unmarshal(bytes, &jsonMap); err != nil {
_, _ = fmt.Printf("Wrong params format for %s\n", key)
}
}
// Check if the comment ends with '!' to indicate that the configuration is required.
if strings.HasSuffix(name, "!") {
spec.Required = true
}
name = strings.TrimSuffix(name, "!")
if name != "" {
spec.Name = name
}
// Check if the name is recognized and apply its parameters.
if handler, ok := allowedSpecs[spec.Name]; ok {
handler(&spec, value, jsonMap)
}
// Assign the configuration specification to the key in the Specs map.
specs[key] = spec
}
// Return the populated Specs map.
return specs
}
func upperFirstLetter(s string) string {
if len(s) == 0 {
return s
}
// Convert the first character to uppercase
// Concatenate it with the rest of the string
return strings.ToUpper(string(s[0])) + strings.ToLower((s[1:]))
}