/
args.go
107 lines (94 loc) · 2.38 KB
/
args.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
package main
import "fmt"
import "log"
import "strconv"
import "strings"
import "github.com/golang/geo/s2"
import "github.com/pwiecz/portal_patterns/lib"
type portalValue struct {
LatLngString string
LatLng s2.LatLng
}
func (p *portalValue) Set(latLngStr string) error {
parts := strings.Split(latLngStr, ",")
if len(parts) != 2 {
return fmt.Errorf("cannot parse \"%s\" as lat,lng", latLngStr)
}
lat, err := strconv.ParseFloat(parts[0], 64)
if err != nil {
return err
}
lng, err := strconv.ParseFloat(parts[1], 64)
if err != nil {
return err
}
p.LatLng = s2.LatLngFromDegrees(lat, lng)
p.LatLngString = latLngStr
return nil
}
func (p portalValue) String() string {
return p.LatLngString
}
func portalToIndex(arg portalValue, portals []lib.Portal) int {
if arg.LatLngString == "" {
return -1
}
result := -1
found := false
for j, portal := range portals {
if s2.PointFromLatLng(arg.LatLng).ApproxEqual(s2.PointFromLatLng(portal.LatLng)) {
if found {
log.Fatalf("found more than one portal matching the specified corner portal: %s", arg.LatLngString)
}
result = j
found = true
}
}
if !found {
log.Fatalf("cound not find portal %s on the provided list of portals", arg.LatLngString)
}
return result
}
type portalsValue []portalValue
func (p *portalsValue) Set(latLngStr string) error {
var portal portalValue
if err := portal.Set(latLngStr); err != nil {
return err
}
*p = append(*p, portal)
return nil
}
func (p portalsValue) String() string {
var portalStrings []string
for _, portal := range p {
portalStrings = append(portalStrings, portal.String())
}
return strings.Join(portalStrings, ";")
}
func portalsToIndices(arg portalsValue, portals []lib.Portal) []int {
var indices []int
for _, portal := range arg {
indices = append(indices, portalToIndex(portal, portals))
}
return indices
}
type numberLimitValue struct {
Value int
Exactly bool
}
func (n *numberLimitValue) Set(numLimitStr string) error {
numStr := strings.TrimPrefix(numLimitStr, "<=")
num, err := strconv.ParseUint(numStr, 10, 16)
if err != nil {
return fmt.Errorf("cannot parse \"%s\" as a 16bit unsigned int", numStr)
}
n.Value = int(num)
n.Exactly = len(numStr) == len(numLimitStr)
return nil
}
func (n numberLimitValue) String() string {
if n.Exactly {
return strconv.FormatUint(uint64(n.Value), 10)
}
return "<=" + strconv.FormatUint(uint64(n.Value), 10)
}