forked from GolangUnited/golang-united-school-homework-8
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
161 lines (136 loc) · 3.15 KB
/
main.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
package main
import (
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"os"
)
type Arguments map[string]string
type User struct {
ID string `json:"id"`
Email string `json:"email"`
Age int `json:"age"`
}
var (
errorIdFlagIsMissing = errors.New("-id flag has to be specified")
errorItemFlagIsMissing = errors.New("-item flag has to be specified")
errorFileNameFlagIsMissing = errors.New("-fileName flag has to be specified")
errorOperationFlagIsMissing = errors.New("-operation flag has to be specified")
)
func Perform(args Arguments, writer io.Writer) error {
if args["fileName"] == "" {
return errorFileNameFlagIsMissing
}
file, err := os.OpenFile(args["fileName"], os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return err
}
defer file.Close()
data, err := io.ReadAll(file)
if err != nil {
return err
}
users := []User{}
if len(data) != 0 {
if err := json.Unmarshal(data, &users); err != nil {
return err
}
}
switch args["operation"] {
case "":
return errorOperationFlagIsMissing
case "list":
if len(users) == 0 {
return nil
}
list, err := json.Marshal(users)
if err != nil {
return err
}
writer.Write(list)
case "add":
if args["item"] == "" {
return errorItemFlagIsMissing
}
var item User
if err := json.Unmarshal([]byte(args["item"]), &item); err != nil {
return err
}
for _, user := range users {
if user.ID == item.ID {
writer.Write([]byte("Item with id " + item.ID + " already exists"))
return nil
}
}
users = append(users, item)
newUsers, err := json.Marshal(users)
if err != nil {
return err
}
if err := os.WriteFile(args["fileName"], newUsers, 0644); err != nil {
return err
}
case "remove":
if args["id"] == "" {
return errorIdFlagIsMissing
}
for i, user := range users {
if args["id"] == user.ID {
users = append(users[:i], users[i+1:]...)
newUsers, err := json.Marshal(users)
if err != nil {
return err
}
if err := os.WriteFile(args["fileName"], newUsers, 0644); err != nil {
return err
}
return nil
}
}
writer.Write([]byte(fmt.Sprintf("Item with id %s not found", args["id"])))
case "findById":
if args["id"] == "" {
return errorIdFlagIsMissing
}
for _, user := range users {
if args["id"] == user.ID {
u, err := json.Marshal(user)
if err != nil {
return err
}
writer.Write(u)
return nil
}
}
writer.Write([]byte(""))
return nil
default:
//! It has to be like that due to the task requirement
return fmt.Errorf("Operation %s not allowed!", args["operation"])
}
return nil
}
func parseArgs() Arguments {
var (
id = flag.String("id", "", "user id")
item = flag.String("item", "", "valid json object with the id, email and age fields")
fileName = flag.String("fileName", "", "name of a JSON file")
operation = flag.String("operation", "", "supported operations: add, list, findById, remove")
)
flag.Parse()
return Arguments{
"id": *id,
"item": *item,
"operation": *operation,
"fileName": *fileName,
}
}
func main() {
err := Perform(parseArgs(), os.Stdout)
if err != nil {
panic(err)
}
fmt.Println()
}