-
Notifications
You must be signed in to change notification settings - Fork 0
/
coffee.go
184 lines (156 loc) · 4.26 KB
/
coffee.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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
package buna
import (
"context"
"errors"
"fmt"
"os"
"github.com/jedib0t/go-pretty/table"
"golang.org/x/crypto/ssh/terminal"
)
type coffee struct {
name string
roaster string
region string
variety string
method string
decaf bool
}
// Returns the added coffee
func addCoffee(ctx context.Context, db DB) (coffee, error) {
fmt.Println("Adding new coffee (Enter # to quit):")
fmt.Print("Enter coffee name: ")
name, quit := validateStrInput(quitStr, false, nil, nil)
if quit {
fmt.Println(quitMsg)
return coffee{}, nil
}
fmt.Print("Enter roaster/producer name: ")
roaster, quit := validateStrInput(quitStr, false, nil, nil)
if quit {
fmt.Println(quitMsg)
return coffee{}, nil
}
fmt.Print("Enter origin/region (Format: Region, Country): ")
region, quit := validateStrInput(quitStr, true, nil, nil)
if quit {
fmt.Println(quitMsg)
return coffee{}, nil
}
fmt.Print("Enter variety (Format: Variety 1, Variety 2, ...): ")
variety, quit := validateStrInput(quitStr, true, nil, nil)
if quit {
fmt.Println(quitMsg)
return coffee{}, nil
}
fmt.Print("Enter processing method: ")
method, quit := validateStrInput(quitStr, true, nil, nil)
if quit {
fmt.Println(quitMsg)
return coffee{}, nil
}
fmt.Print("Is decaf (true or false): ")
decaf, quit := validateBoolInput(quitStr, true)
if quit {
fmt.Println(quitMsg)
return coffee{}, nil
}
newCoffee := coffee{
name: name,
roaster: roaster,
region: region,
variety: variety,
method: method,
decaf: decaf,
}
if err := db.insertCoffee(ctx, newCoffee); err != nil {
return coffee{}, fmt.Errorf("buna: coffee: failed to insert coffee: %w", err)
}
fmt.Println("Added coffee successfully")
return newCoffee, nil
}
func retrieveCoffee(ctx context.Context, db DB) error {
options := map[int]string{
0: "Retrieve coffees ordered by last added",
// 1: "Retrieve coffee by name",
// 2: "Retrieve coffees ordered alphabetically",
// 3: "Retrieve coffees by origin",
// 4: "Retrieve coffees by roaster",
// 5: "Retrieve coffees by processing method",
// 6: "Retrieve decaf coffees ordered by last added",
// 7: "Retrieve decaf coffees ordered alphabetically",
}
fmt.Println("Retrieving coffee (Enter # to quit):")
if err := displayIntOptions(options); err != nil {
return fmt.Errorf("buna: coffee: failed to display int options: %w", err)
}
selection, quit, err := getIntSelection(options, quitStr)
if err != nil {
return fmt.Errorf("buna: coffee: failed to get int selection: %w", err)
}
if quit {
fmt.Println(quitMsg)
return nil
}
if err := runRetrieveCoffeeSelection(ctx, selection, db); err != nil {
return fmt.Errorf("buna: coffee: failed to run the retrieve selection: %w", err)
}
return nil
}
func runRetrieveCoffeeSelection(ctx context.Context, selection int, db DB) error {
switch selection {
case 0:
if err := displayCoffeesByLastAdded(ctx, db); err != nil {
return fmt.Errorf("buna: coffee: failed to display coffees by last added: %w", err)
}
default:
return errors.New("buna: coffee: invalid retrieve selection")
}
return nil
}
// Promts user for an optional limit.
func displayCoffeesByLastAdded(ctx context.Context, db DB) error {
const defaultDisplayAmount = 15
const maxDisplayAmount = 60
fmt.Println("Displaying coffees by last added (Enter # to quit):")
fmt.Print("Enter a limit for the number of coffees to display: ")
limit, quit := validateIntInput(quitStr, true, 1, maxDisplayAmount, []int{})
if quit {
fmt.Println(quitMsg)
return nil
}
if limit == 0 {
limit = defaultDisplayAmount
}
coffees, err := db.getCoffeesByLastAdded(ctx, limit)
if err != nil {
return fmt.Errorf("buna: coffee: failed to get coffees by last added: %w", err)
}
t := table.NewWriter()
t.AppendHeader(table.Row{
"Name",
"Roaster",
"Region/Origin",
"Variety",
"Processing method",
"Decaf",
})
for _, coffee := range coffees {
t.AppendRow(table.Row{
coffee.name,
coffee.roaster,
coffee.region,
coffee.variety,
coffee.method,
coffee.decaf,
})
t.AppendSeparator()
}
terminalWidth, _, err := terminal.GetSize(int(os.Stdin.Fd()))
if err != nil {
return fmt.Errorf("buna: coffee: failed to get terminal width: %w", err)
}
t.SetAllowedRowLength(terminalWidth)
t.SetOutputMirror(os.Stdout)
t.Render()
return nil
}