-
Notifications
You must be signed in to change notification settings - Fork 0
/
options.go
104 lines (94 loc) · 2.39 KB
/
options.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
package main
import (
"errors"
"os"
"strings"
"time"
)
const usage = `usage: loader -s <symbol> [options]
-s, --symbol The pair for which need to load the prices data
-n, --is-new The flag to init new instance for a symbol
-t, --start-time Date (UTC) from which to start downloading
(format like 2024-02-19 03:37:05)
--show-start Show the close date (UTC) of the first candle
--show-end Show the close date (UTC) of the last candle
`
var (
errReqSymbol = errors.New("symbol is required")
errReqStartTime = errors.New("start-time is required for a new instance")
// it is not clear what the user wanted, or start a new download
// or continue saved
errTimeWithoutNew = errors.New("start-time is required only for a new instance")
)
func help() {
os.Stdout.WriteString(usage)
os.Exit(exitOk)
}
type options struct {
IsNew bool
ShowStart bool
ShowEnd bool
Symbol string
StartTimestamp int64
}
func convertTimeToTimestamp(date string) (int64, error) {
layout := "2006-01-02 15:04:05"
t, err := time.Parse(layout, date)
if err != nil {
return 0, err
}
return t.UnixMilli(), nil
}
func validateOptions(opts *options) error {
if opts.Symbol == "" {
return errReqSymbol
}
if opts.StartTimestamp == 0 && opts.IsNew {
return errReqStartTime
}
if opts.StartTimestamp != 0 && !opts.IsNew {
return errTimeWithoutNew
}
return nil
}
func parseOptions(args []string) (*options, error) {
if len(args) < 2 {
help()
}
opts := &options{}
for i := 1; i < len(args); i++ {
arg := args[i]
switch arg {
case "-h", "--help":
help()
case "-n", "--is-new":
opts.IsNew = true
case "-s", "--symbol":
j := i + 1
// during validation there will be a check for an empty string
// it is not necessary to check it here
if len(args) > j && !strings.HasPrefix(args[j], "-") {
opts.Symbol = strings.ToUpper(args[j])
i++
}
case "-t", "--start-time":
j := i + 1
if len(args) > j && !strings.HasPrefix(args[j], "-") {
t, err := convertTimeToTimestamp(args[j])
if err != nil {
return nil, errorWrap("parse options start time", err)
}
opts.StartTimestamp = t
i++
}
case "--show-start":
opts.ShowStart = true
case "--show-end":
opts.ShowEnd = true
}
}
if err := validateOptions(opts); err != nil {
return nil, err
}
return opts, nil
}