/
types.go
163 lines (130 loc) · 4.43 KB
/
types.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package types
import (
"encoding/json"
"fmt"
"go.mongodb.org/mongo-driver/bson/bsontype"
"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
)
// QBase is a struct that contains common fields for all types of questions.
type QBase struct {
// Placeholder is a placeholder text.
// Validations:
// - optional
// - min length: 1
Placeholder *string `json:"placeholder,omitempty" bson:"placeholder,omitempty" validate:"omitempty,min=1"`
}
// QuestionType represents the different types of questions that can exist in a survey.
type QuestionType string
// Any new type, depending on the type of question, should be added to the following:
// - QTypeChoiceTypes if type is a choice type
// - QTypeTextTypes if type is a text type
// if the new type cant be added to either of the above, then:
// - create a new slice of QuestionType and add the new type to it
// - append the new slice to AllQuestionTypes
// - add a new function to check if the new type is of the new slice (e.g. IsChoiceType or IsTextType)
// - update this comment to include the new type :)
const (
//------ Choice types ------//
// QTypeSingleSelect represents a single select field type
QTypeSingleSelect QuestionType = "single_select"
// QTypeMultipleSelect represents a multiple select field type
QTypeMultipleSelect = "multi_select"
// QTypeRadio represents a radio field type
QTypeRadio = "radio"
// QTypeCheckbox represents a checkbox field type
QTypeCheckbox = "checkbox"
//------ Text types ------//
// QTypeTextArea represents a text area field type
QTypeTextArea = "text_area"
// QTypeInputText represents a text input field type
QTypeInputText = "input_text"
// QTypeEmail represents an email input field type
QTypeEmail = "email"
// QTypeTelephone represents a telephone input field type
QTypeTelephone = "telephone"
// QTypeInformation represents an information field type
QTypeInformation = "information"
//------ External types ------//
// QTypeExternalQuestion represents a external question field type
QTypeExternalQuestion = "external_question"
)
// UnmarshalJSON implements the json.Unmarshaler interface.
func (s *QuestionType) UnmarshalJSON(b []byte) error {
var st string
if err := json.Unmarshal(b, &st); err != nil {
return fmt.Errorf("unmarshal error, %s", err)
}
t, err := ParseToQuestionType(st)
if err != nil {
return fmt.Errorf("parse error, %s", err)
}
*s = t
return nil
}
func (s *QuestionType) UnmarshalBSONValue(typ bsontype.Type, raw []byte) error {
if typ != bsontype.String {
return fmt.Errorf("invalid bson value type '%s'", typ.String())
}
c, _, ok := bsoncore.ReadString(raw)
if !ok {
return fmt.Errorf("invalid bson value '%s'", string(raw))
}
t, err := ParseToQuestionType(c)
if err != nil {
return fmt.Errorf("parse error, %s", err)
}
*s = t
return nil
}
// MarshalJSON implements the json.Marshaler interface.
func (s *QuestionType) MarshalJSON() ([]byte, error) {
if s == nil {
return json.Marshal(nil)
}
return json.Marshal(string(*s))
}
// QTypeChoiceTypes groups all choice types.
var QTypeChoiceTypes = map[QuestionType]bool{
QTypeSingleSelect: true,
QTypeMultipleSelect: true,
QTypeRadio: true,
QTypeCheckbox: true,
}
// QTypeTextTypes groups all text types.
var QTypeTextTypes = map[QuestionType]bool{
QTypeTextArea: true,
QTypeInputText: true,
QTypeEmail: true,
QTypeTelephone: true,
QTypeInformation: true,
}
// QTypeExternalQuestions groups all external types.
var QTypeExternalQuestions = map[QuestionType]bool{
QTypeExternalQuestion: true,
}
// IsChoiceType returns true if the question type is a choice type, false otherwise.
func IsChoiceType(qt QuestionType) bool {
return QTypeChoiceTypes[qt]
}
// IsTextType returns true if the question type is a text type, false otherwise.
func IsTextType(qt QuestionType) bool {
return QTypeTextTypes[qt]
}
// IsExternalType returns true if the question type is an external type, false otherwise.
func IsExternalType(qt QuestionType) bool {
return QTypeExternalQuestions[qt]
}
// ParseToQuestionType takes a string and returns the corresponding QuestionType, or an error if the string is invalid.
func ParseToQuestionType(v string) (QuestionType, error) {
tmpQT := QuestionType(v)
if _, ok := QTypeChoiceTypes[tmpQT]; ok {
return tmpQT, nil
}
if _, ok := QTypeTextTypes[tmpQT]; ok {
return tmpQT, nil
}
if _, ok := QTypeExternalQuestions[tmpQT]; ok {
return tmpQT, nil
}
return "", fmt.Errorf("invalid question type '%s'", v)
}