1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package pretty
21
22 import (
23 "fmt"
24 "io"
25 "reflect"
26 "sort"
27 "strings"
28 "time"
29 )
30
31
32 var Indent = " "
33
34
35
36
37
38
39
40
41 func Value(v interface{}) val { return val{v: v} }
42
43
44 type val struct{ v interface{} }
45
46
47 func (v val) Format(s fmt.State, c rune) {
48 if c == 'v' || c == 's' {
49 fprint(s, reflect.ValueOf(v.v), state{
50 defaults: s.Flag('+') || s.Flag('#'),
51 })
52 } else {
53 fmt.Fprintf(s, "%%!%c(pretty.val)", c)
54 }
55 }
56
57 type state struct {
58 level int
59 prefix, suffix string
60 defaults bool
61 }
62
63 const maxLevel = 100
64
65 var typeOfTime = reflect.TypeOf(time.Time{})
66
67 func fprint(w io.Writer, v reflect.Value, s state) {
68 if s.level > maxLevel {
69 fmt.Fprintln(w, "pretty: max nested depth exceeded")
70 return
71 }
72 indent := strings.Repeat(Indent, s.level)
73 fmt.Fprintf(w, "%s%s", indent, s.prefix)
74 if isNil(v) {
75 fmt.Fprintf(w, "nil%s", s.suffix)
76 return
77 }
78 if v.Type().Kind() == reflect.Interface {
79 v = v.Elem()
80 }
81 if v.Type() == typeOfTime {
82 fmt.Fprintf(w, "%s%s", v.Interface(), s.suffix)
83 return
84 }
85 for v.Type().Kind() == reflect.Ptr {
86 fmt.Fprintf(w, "&")
87 v = v.Elem()
88 }
89 switch v.Type().Kind() {
90 default:
91 fmt.Fprintf(w, "%s%s", short(v), s.suffix)
92
93 case reflect.Array:
94 fmt.Fprintf(w, "%s{\n", v.Type())
95 for i := 0; i < v.Len(); i++ {
96 fprint(w, v.Index(i), state{
97 level: s.level + 1,
98 prefix: "",
99 suffix: ",",
100 defaults: s.defaults,
101 })
102 fmt.Fprintln(w)
103 }
104 fmt.Fprintf(w, "%s}", indent)
105
106 case reflect.Slice:
107 fmt.Fprintf(w, "%s{", v.Type())
108 if v.Len() > 0 {
109 fmt.Fprintln(w)
110 for i := 0; i < v.Len(); i++ {
111 fprint(w, v.Index(i), state{
112 level: s.level + 1,
113 prefix: "",
114 suffix: ",",
115 defaults: s.defaults,
116 })
117 fmt.Fprintln(w)
118 }
119 }
120 fmt.Fprintf(w, "%s}%s", indent, s.suffix)
121
122 case reflect.Map:
123 fmt.Fprintf(w, "%s{", v.Type())
124 if v.Len() > 0 {
125 fmt.Fprintln(w)
126 keys := v.MapKeys()
127 maybeSort(keys, v.Type().Key())
128 for _, key := range keys {
129 val := v.MapIndex(key)
130 if s.defaults || !isDefault(val) {
131 fprint(w, val, state{
132 level: s.level + 1,
133 prefix: short(key) + ": ",
134 suffix: ",",
135 defaults: s.defaults,
136 })
137 fmt.Fprintln(w)
138 }
139 }
140 }
141 fmt.Fprintf(w, "%s}%s", indent, s.suffix)
142
143 case reflect.Struct:
144 t := v.Type()
145 fmt.Fprintf(w, "%s{\n", t)
146 for i := 0; i < t.NumField(); i++ {
147 f := v.Field(i)
148 if s.defaults || !isDefault(f) {
149 fprint(w, f, state{
150 level: s.level + 1,
151 prefix: t.Field(i).Name + ": ",
152 suffix: ",",
153 defaults: s.defaults,
154 })
155 fmt.Fprintln(w)
156 }
157 }
158 fmt.Fprintf(w, "%s}%s", indent, s.suffix)
159 }
160 }
161
162 func isNil(v reflect.Value) bool {
163 if !v.IsValid() {
164 return true
165 }
166 switch v.Type().Kind() {
167 case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
168 return v.IsNil()
169 default:
170 return false
171 }
172 }
173
174 func isDefault(v reflect.Value) bool {
175 if !v.IsValid() {
176 return true
177 }
178 t := v.Type()
179 switch t.Kind() {
180 case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
181 return v.IsNil()
182 default:
183 if !v.CanInterface() {
184 return false
185 }
186 return t.Comparable() && v.Interface() == reflect.Zero(t).Interface()
187 }
188 }
189
190
191 func short(v reflect.Value) string {
192 if !v.IsValid() {
193 return "nil"
194 }
195 if v.Type().Kind() == reflect.String {
196 return fmt.Sprintf("%q", v)
197 }
198 return fmt.Sprintf("%v", v)
199 }
200
201 func maybeSort(vs []reflect.Value, t reflect.Type) {
202 if less := lessFunc(t); less != nil {
203 sort.Sort(&sorter{vs, less})
204 }
205 }
206
207
208
209 func lessFunc(t reflect.Type) func(v1, v2 interface{}) bool {
210 switch t.Kind() {
211 case reflect.String:
212 return func(v1, v2 interface{}) bool { return v1.(string) < v2.(string) }
213 case reflect.Int:
214 return func(v1, v2 interface{}) bool { return v1.(int) < v2.(int) }
215 case reflect.Int8:
216 return func(v1, v2 interface{}) bool { return v1.(int8) < v2.(int8) }
217 case reflect.Int16:
218 return func(v1, v2 interface{}) bool { return v1.(int16) < v2.(int16) }
219 case reflect.Int32:
220 return func(v1, v2 interface{}) bool { return v1.(int32) < v2.(int32) }
221 case reflect.Int64:
222 return func(v1, v2 interface{}) bool { return v1.(int64) < v2.(int64) }
223 case reflect.Uint:
224 return func(v1, v2 interface{}) bool { return v1.(uint) < v2.(uint) }
225 case reflect.Uint8:
226 return func(v1, v2 interface{}) bool { return v1.(uint8) < v2.(uint8) }
227 case reflect.Uint16:
228 return func(v1, v2 interface{}) bool { return v1.(uint16) < v2.(uint16) }
229 case reflect.Uint32:
230 return func(v1, v2 interface{}) bool { return v1.(uint32) < v2.(uint32) }
231 case reflect.Uint64:
232 return func(v1, v2 interface{}) bool { return v1.(uint64) < v2.(uint64) }
233 case reflect.Float32:
234 return func(v1, v2 interface{}) bool { return v1.(float32) < v2.(float32) }
235 case reflect.Float64:
236 return func(v1, v2 interface{}) bool { return v1.(float64) < v2.(float64) }
237 default:
238 return nil
239 }
240 }
241
242 type sorter struct {
243 vs []reflect.Value
244 less func(v1, v2 interface{}) bool
245 }
246
247 func (s *sorter) Len() int { return len(s.vs) }
248 func (s *sorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
249 func (s *sorter) Less(i, j int) bool { return s.less(s.vs[i].Interface(), s.vs[j].Interface()) }
250
View as plain text