validate.gno
3.00 Kb ยท 148 lines
1package forms
2
3import (
4 "strings"
5
6 "gno.land/p/onbloc/json"
7)
8
9func validateBooleanField(node *json.Node, field Field) bool {
10 if node.IsBool() == false {
11 return false
12 }
13
14 answer, err := node.GetBool()
15 if err != nil {
16 return false
17 }
18
19 // If the field is required, checkbox must be checked
20 if field.Required == true && answer == false {
21 return false
22 }
23
24 return true
25}
26
27func validateStringField(node *json.Node, field Field) bool {
28 if node.IsString() == false {
29 return false
30 }
31
32 answer, err := node.GetString()
33 if err != nil {
34 return false
35 }
36
37 // If the field is required, the answer must not be empty
38 if field.Required == true && answer == "" {
39 return false
40 }
41
42 return true
43}
44
45func validateNumberField(node *json.Node, field Field) bool {
46 if node.IsNumber() == false {
47 return false
48 }
49
50 _, err := node.GetNumeric()
51 if err != nil {
52 return false
53 }
54
55 return true
56}
57
58func validateMultiChoiceField(node *json.Node, field Field) bool {
59 choices := strings.Split(field.FieldType[1:len(field.FieldType)-1], "|")
60
61 if node.IsArray() == false {
62 return false
63 }
64
65 if field.Required == true && node.Size() == 0 {
66 return false
67 }
68
69 if node.Size() > len(choices) {
70 return false
71 }
72
73 for i := 0; i < node.Size(); i++ {
74 choiceNode, err := node.GetIndex(i)
75 if err != nil {
76 return false
77 }
78
79 choiceIdx := choiceNode.MustNumeric()
80 if choiceIdx < 0 || int(choiceIdx) >= len(choices) {
81 return false
82 }
83 }
84
85 return true
86}
87
88func validateChoiceField(node *json.Node, field Field) bool {
89 choices := strings.Split(field.FieldType[1:len(field.FieldType)-1], "|")
90
91 if node.IsNumber() == false {
92 return false
93 }
94
95 choiceIdx := node.MustNumeric()
96 if choiceIdx < 0 || int(choiceIdx) >= len(choices) {
97 return false
98 }
99
100 return true
101}
102
103func ValidateAnswer(answer *json.Node, field Field) bool {
104 if field.FieldType == "boolean" {
105 return validateBooleanField(answer, field)
106 } else if field.FieldType == "string" {
107 return validateStringField(answer, field)
108 } else if field.FieldType == "number" {
109 return validateNumberField(answer, field)
110 } else if strings.HasPrefix(field.FieldType, "{") && strings.HasSuffix(field.FieldType, "}") {
111 return validateMultiChoiceField(answer, field)
112 } else if strings.HasPrefix(field.FieldType, "[") && strings.HasSuffix(field.FieldType, "]") {
113 return validateChoiceField(answer, field)
114 }
115
116 return false
117}
118
119// ValidateAnswers checks if the given answers are valid for the given fields
120func ValidateAnswers(answers string, fields []Field) bool {
121 unmarshalled, err := json.Unmarshal([]byte(answers))
122 if err != nil {
123 return false
124 }
125
126 // If the number of answers is different from the number of fields, it's invalid
127 if len(fields) != unmarshalled.Size() {
128 return false
129 }
130
131 for i, field := range fields {
132 answer, err := unmarshalled.GetIndex(i)
133 if err != nil {
134 return false
135 }
136
137 // If the answer is empty and the field is not required, it's valid
138 if answer.IsNull() && !field.Required {
139 return true
140 }
141
142 if !ValidateAnswer(answer, field) {
143 return false
144 }
145 }
146
147 return true
148}