-
Notifications
You must be signed in to change notification settings - Fork 1
/
questions.go
78 lines (65 loc) · 1.74 KB
/
questions.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
package questions
import "errors"
var ErrQuestionNotAnswered = errors.New("question.Answer() called without the question having been successfully asked")
type Questioner interface {
NewOpenEndedQuestion(question *OpenEndedQuestion) Question
NewClosedQuestion(question *ClosedQuestion) Question
}
// AskQuestions takes a list of questions and asks each one in sequence, returning the list of answers
func AskQuestions(questions []Question) error {
for _, question := range questions {
err := question.Ask()
if err != nil {
return err
}
}
return nil
}
type Answer string
// Question represents a generic user prompt
type Question interface {
Ask() error
Answer() Answer
}
// OpenEndedQuestion is a prompt where the user can provide any answer
type OpenEndedQuestion struct {
Question string
Default string
AllowEdit bool
Validate func(string) error
}
// ClosedQuestion is a prompt where the user can choose from a fixed set of answers
type ClosedQuestion struct {
Question string
Items []string
}
// QuestionBranch is a sort of "meta-question" whose Ask method will delegate to ConditionQuestion and execute BranchA
// if ConditionAnswer is met, otherwise execute BranchB
type QuestionBranch struct {
ConditionQuestion Question
ConditionAnswer Answer
BranchA []Question
BranchB []Question
}
func (q *QuestionBranch) Ask() error {
err := q.ConditionQuestion.Ask()
if err != nil {
return err
}
answer := q.ConditionQuestion.Answer()
if answer == q.ConditionAnswer {
err := AskQuestions(q.BranchA)
if err != nil {
return err
}
} else {
err := AskQuestions(q.BranchB)
if err != nil {
return err
}
}
return nil
}
func (q *QuestionBranch) Answer() Answer {
return q.ConditionQuestion.Answer()
}