-
Notifications
You must be signed in to change notification settings - Fork 1
/
gofmt.go
154 lines (132 loc) · 3.01 KB
/
gofmt.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
package main
import (
"fmt"
"log"
"math"
"os"
"reflect"
"sort"
"github.com/pkg/errors"
)
// alignSize return the required size for aligning all numbers in nums
func alignSize(nums []int) int {
size := 0
for _, n := range nums {
if s := int(math.Log10(float64(n))) + 1; s > size {
size = s
}
}
return size
}
// Point is a 2D point
type Point struct {
X int
Y int
}
// Fields in AuthInfo struct
var authInfoFields []string
// ACL bits
const (
ReadACL = 1 << iota
WriteACL
AdminACL
keyMask = "*****"
)
// AuthInfo is authentication information
type AuthInfo struct {
Login string // Login user
ACL uint // ACL bitmask
APIKey string // API key
}
// String implements Stringer interface
func (ai *AuthInfo) String() string {
key := ai.APIKey
if key != "" {
key = keyMask
}
return fmt.Sprintf("Login:%s, ACL:%08b, APIKey: %s", ai.Login, ai.ACL, key)
}
// Format implements fmt.Formatter
func (ai *AuthInfo) Format(state fmt.State, verb rune) {
switch verb {
case 's', 'q':
val := ai.String()
if verb == 'q' {
val = fmt.Sprintf("%q", val)
}
fmt.Fprint(state, val)
case 'v':
if state.Flag('#') {
// Emit type before
fmt.Fprintf(state, "%T", ai)
}
fmt.Fprint(state, "{")
val := reflect.ValueOf(*ai)
for i, name := range authInfoFields {
if state.Flag('#') || state.Flag('+') {
fmt.Fprintf(state, "%s:", name)
}
fld := val.FieldByName(name)
if name == "APIKey" && fld.Len() > 0 {
fmt.Fprint(state, keyMask)
} else {
fmt.Fprint(state, fld)
}
if i < len(authInfoFields)-1 {
fmt.Fprint(state, " ")
}
}
fmt.Fprint(state, "}")
}
}
func init() {
typ := reflect.TypeOf(AuthInfo{})
authInfoFields = make([]string, typ.NumField())
for i := 0; i < typ.NumField(); i++ {
authInfoFields[i] = typ.Field(i).Name
}
sort.Strings(authInfoFields) // People are better with sorted data
}
// Config is a configuration
type Config struct{}
// loadConfig loads configuration from path
func loadConfig(path string) (*Config, error) {
file, err := os.Open(path)
if err != nil {
return nil, errors.Wrap(err, "can't open config file")
}
defer file.Close()
// TODO: Parse configuration
return &Config{}, nil
}
func main() {
var e interface{} = 2.7182
fmt.Printf("e = %v (%T)\n", e, e)
fmt.Printf("%10d\n", 353)
fmt.Printf("%*d\n", 10, 353)
nums := []int{12, 237, 3878, 3}
size := alignSize(nums)
for i, n := range nums {
fmt.Printf("%02d %*d\n", i, size, n)
}
fmt.Printf("The price of %[1]s was $%[2]d. $%[2]d! imagine that.\n", "carrot", 23)
p := &Point{1, 2}
fmt.Printf("%v %+v %#v \n", p, p, p)
cfg, err := loadConfig("/no/such/config.toml")
if err != nil {
fmt.Printf("error: %s\n", err)
log.Printf("can't load config\n%+v", err)
}
fmt.Println("cfg", cfg)
ai := &AuthInfo{
Login: "daffy",
ACL: ReadACL | WriteACL,
APIKey: "duck season",
}
fmt.Println(ai.String())
fmt.Printf("ai %%s: %s\n", ai)
fmt.Printf("ai %%q: %q\n", ai)
fmt.Printf("ai %%v: %v\n", ai)
fmt.Printf("ai %%+v: %+v\n", ai)
fmt.Printf("ai %%#v: %#v\n", ai)
}