Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}