prevent wrapping into longer, general testing
This commit is contained in:
parent
612aa94f0a
commit
b1e3ada95c
21
debug_test.go
Normal file
21
debug_test.go
Normal file
@ -0,0 +1,21 @@
|
||||
package notation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDebugNode(t *testing.T) {
|
||||
const expect = `"foobarbaz"`
|
||||
o := "foobarbaz"
|
||||
n := reflectValue(none, reflect.ValueOf(o))
|
||||
s := fmt.Sprint(n)
|
||||
if s != expect {
|
||||
t.Fatalf(
|
||||
"failed to get debug string of node, got: %s, expected: %s",
|
||||
s,
|
||||
expect,
|
||||
)
|
||||
}
|
||||
}
|
51
env_test.go
Normal file
51
env_test.go
Normal file
@ -0,0 +1,51 @@
|
||||
package notation
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func withEnv(t *testing.T, e ...string) (revert func()) {
|
||||
var r []func()
|
||||
revert = func() {
|
||||
for i := range r {
|
||||
r[i]()
|
||||
}
|
||||
}
|
||||
|
||||
revertOne := func(key, value string, existed bool) func() {
|
||||
return func() {
|
||||
if existed {
|
||||
if err := os.Setenv(key, value); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if err := os.Unsetenv(key); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i := range e {
|
||||
var key, value string
|
||||
p := strings.Split(e[i], "=")
|
||||
key = p[0]
|
||||
if len(p) > 1 {
|
||||
value = p[1]
|
||||
}
|
||||
|
||||
prev, ok := os.LookupEnv(key)
|
||||
if err := os.Setenv(key, value); err != nil {
|
||||
revert()
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
r = append(r, revertOne(key, prev, ok))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
226
fprint.go
226
fprint.go
@ -1,118 +1,160 @@
|
||||
package notation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
type writer struct {
|
||||
w io.Writer
|
||||
n int
|
||||
err error
|
||||
func unwrappable(n node) bool {
|
||||
return n.len == n.wrapLen.max &&
|
||||
n.len == n.fullWrap.max
|
||||
}
|
||||
|
||||
func (w *writer) write(o interface{}) {
|
||||
if w.err != nil {
|
||||
func initialize(t *int, v int) {
|
||||
if *t > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
n, err := fmt.Fprint(w.w, o)
|
||||
w.n += n
|
||||
w.err = err
|
||||
*t = v
|
||||
}
|
||||
|
||||
func max(t *int, v int) {
|
||||
if *t >= v {
|
||||
return
|
||||
}
|
||||
|
||||
*t = v
|
||||
}
|
||||
|
||||
func nodeLen(t int, n node) node {
|
||||
var w int
|
||||
var w, f int
|
||||
for i, p := range n.parts {
|
||||
switch part := p.(type) {
|
||||
case string:
|
||||
n.len += len(part)
|
||||
w += len(part)
|
||||
f += len(part)
|
||||
case node:
|
||||
part = nodeLen(t, part)
|
||||
n.parts[i] = part
|
||||
n.len += part.len
|
||||
if part.len == part.wlen {
|
||||
if unwrappable(part) {
|
||||
w += part.len
|
||||
f += part.len
|
||||
continue
|
||||
}
|
||||
|
||||
if part.len == part.wrapLen.max {
|
||||
w += part.len
|
||||
} else {
|
||||
w += part.wlen0
|
||||
if w > n.wlen {
|
||||
n.wlen = w
|
||||
w += part.wrapLen.first
|
||||
initialize(&n.wrapLen.first, w)
|
||||
max(&n.wrapLen.max, w)
|
||||
w = part.wrapLen.last
|
||||
}
|
||||
|
||||
if part.wlen > n.wlen {
|
||||
n.wlen = part.wlen
|
||||
}
|
||||
|
||||
if n.wlen0 == 0 {
|
||||
n.wlen0 = w
|
||||
}
|
||||
|
||||
w = part.wlenLast
|
||||
}
|
||||
f += part.fullWrap.first
|
||||
initialize(&n.fullWrap.first, f)
|
||||
max(&n.fullWrap.max, f)
|
||||
f = part.fullWrap.last
|
||||
case wrapper:
|
||||
if len(part.items) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if w > n.wlen {
|
||||
n.wlen = w
|
||||
}
|
||||
|
||||
if n.wlen0 == 0 {
|
||||
n.wlen0 = w
|
||||
}
|
||||
|
||||
w = 0
|
||||
for j, ni := range part.items {
|
||||
ni = nodeLen(t, ni)
|
||||
part.items[j] = ni
|
||||
n.len += ni.len
|
||||
wni := t + ni.len + len(part.suffix)
|
||||
if wni > w {
|
||||
w = wni
|
||||
}
|
||||
}
|
||||
|
||||
if len(part.items) > 0 {
|
||||
initialize(&n.wrapLen.first, w)
|
||||
max(&n.wrapLen.max, w)
|
||||
initialize(&n.fullWrap.first, f)
|
||||
max(&n.fullWrap.max, f)
|
||||
w, f = 0, 0
|
||||
n.len += (len(part.items) - 1) * len(part.sep)
|
||||
if part.mode == line {
|
||||
w += (len(part.items) - 1) * len(part.sep)
|
||||
}
|
||||
|
||||
w = 0
|
||||
for j, item := range part.items {
|
||||
item = nodeLen(t, item)
|
||||
part.items[j] = item
|
||||
n.len += item.len
|
||||
switch part.mode {
|
||||
case line:
|
||||
w += item.len
|
||||
max(&f, item.len)
|
||||
default:
|
||||
wj := t + item.len + len(part.suffix)
|
||||
max(&w, wj)
|
||||
fj := t + item.fullWrap.max
|
||||
max(&f, fj)
|
||||
fj = t + item.fullWrap.last + len(part.suffix)
|
||||
max(&f, fj)
|
||||
}
|
||||
}
|
||||
|
||||
if w > n.wlen {
|
||||
n.wlen = w
|
||||
max(&n.wrapLen.max, w)
|
||||
max(&n.fullWrap.max, f)
|
||||
w, f = 0, 0
|
||||
}
|
||||
}
|
||||
|
||||
if n.wlen0 == 0 {
|
||||
n.wlen0 = w
|
||||
}
|
||||
|
||||
n.wlenLast = w
|
||||
initialize(&n.wrapLen.first, w)
|
||||
max(&n.wrapLen.max, w)
|
||||
n.wrapLen.last = w
|
||||
initialize(&n.fullWrap.first, f)
|
||||
max(&n.fullWrap.max, f)
|
||||
n.fullWrap.last = f
|
||||
return n
|
||||
}
|
||||
|
||||
func wrapNode(t, c0, c1 int, n node) node {
|
||||
if n.len <= c0 || n.wlen == n.len {
|
||||
if n.len <= c0 {
|
||||
return n
|
||||
}
|
||||
|
||||
if n.len <= c1 && n.len-c0 <= n.wlen {
|
||||
if n.wrapLen.max >= n.len && n.fullWrap.max >= n.len {
|
||||
return n
|
||||
}
|
||||
|
||||
if n.len <= c1 && n.len-c0 <= n.wrapLen.max {
|
||||
return n
|
||||
}
|
||||
|
||||
n.wrap = true
|
||||
if n.wlen <= c0 {
|
||||
return n
|
||||
}
|
||||
|
||||
cc0, cc1 := c0, c1
|
||||
for i, p := range n.parts {
|
||||
switch part := p.(type) {
|
||||
case node:
|
||||
n.parts[i] = wrapNode(t, c0, c1, part)
|
||||
part = wrapNode(t, cc0, cc1, part)
|
||||
n.parts[i] = part
|
||||
if part.wrap {
|
||||
cc0 -= part.wrapLen.last
|
||||
cc1 -= part.wrapLen.last
|
||||
} else {
|
||||
cc0 -= part.len
|
||||
cc1 -= part.len
|
||||
}
|
||||
case wrapper:
|
||||
if len(part.items) > 0 {
|
||||
cc0, cc1 = c0, c1
|
||||
}
|
||||
|
||||
switch part.mode {
|
||||
case line:
|
||||
c0, c1 = c0-t, c1-t
|
||||
var w int
|
||||
for j, ni := range part.items {
|
||||
if w > 0 && w+len(part.sep)+ni.len > c0 {
|
||||
w = 0
|
||||
part.lineWrappers = append(
|
||||
part.lineWrappers,
|
||||
j,
|
||||
)
|
||||
}
|
||||
|
||||
if w > 0 {
|
||||
w += len(part.sep)
|
||||
}
|
||||
|
||||
w += ni.len
|
||||
}
|
||||
|
||||
n.parts[i] = part
|
||||
c0, c1 = c0+t, c1+t
|
||||
default:
|
||||
for j := range part.items {
|
||||
part.items[j] = wrapNode(
|
||||
t,
|
||||
@ -123,6 +165,7 @@ func wrapNode(t, c0, c1 int, n node) node {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
@ -132,35 +175,60 @@ func fprint(w *writer, t int, n node) {
|
||||
return
|
||||
}
|
||||
|
||||
for i := 0; i < t; i++ {
|
||||
w.write("\t")
|
||||
}
|
||||
|
||||
for _, p := range n.parts {
|
||||
switch part := p.(type) {
|
||||
case node:
|
||||
fprint(w, 0, part)
|
||||
fprint(w, t, part)
|
||||
case wrapper:
|
||||
if len(part.items) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if n.wrap {
|
||||
w.write("\n")
|
||||
}
|
||||
|
||||
if !n.wrap {
|
||||
for i, ni := range part.items {
|
||||
if n.wrap {
|
||||
fprint(w, t+1, ni)
|
||||
w.write(part.suffix)
|
||||
w.write("\n")
|
||||
} else {
|
||||
fprint(w, 0, ni)
|
||||
fprint(w, t, ni)
|
||||
if i < len(part.items)-1 {
|
||||
w.write(part.sep)
|
||||
}
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
t++
|
||||
switch part.mode {
|
||||
case line:
|
||||
var (
|
||||
wi int
|
||||
lineStarted bool
|
||||
)
|
||||
|
||||
w.line(t)
|
||||
for i, ni := range part.items {
|
||||
if len(part.lineWrappers) > wi &&
|
||||
i == part.lineWrappers[wi] {
|
||||
wi++
|
||||
w.line(t)
|
||||
lineStarted = false
|
||||
}
|
||||
|
||||
if lineStarted {
|
||||
w.write(part.sep)
|
||||
}
|
||||
|
||||
fprint(w, 0, ni)
|
||||
lineStarted = true
|
||||
}
|
||||
default:
|
||||
for _, ni := range part.items {
|
||||
w.line(t)
|
||||
fprint(w, t, ni)
|
||||
w.write(part.suffix)
|
||||
}
|
||||
}
|
||||
|
||||
t--
|
||||
w.line(t)
|
||||
default:
|
||||
w.write(part)
|
||||
}
|
||||
|
206
fprint_test.go
Normal file
206
fprint_test.go
Normal file
@ -0,0 +1,206 @@
|
||||
package notation
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type failingWriter int
|
||||
|
||||
var errTest = errors.New("test")
|
||||
|
||||
func failAfter(n int) *failingWriter {
|
||||
w := failingWriter(n)
|
||||
return &w
|
||||
}
|
||||
|
||||
func (w *failingWriter) Write(p []byte) (int, error) {
|
||||
*w = failingWriter(int(*w) - len(p))
|
||||
if *w >= 0 {
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
return len(p) + int(*w), errTest
|
||||
}
|
||||
|
||||
func TestFailingWriter(t *testing.T) {
|
||||
t.Run("single object", func(t *testing.T) {
|
||||
o := struct{ fooBarBaz int }{42}
|
||||
w := failAfter(9)
|
||||
n, err := Fprint(w, o)
|
||||
if n == 9 && err == errTest {
|
||||
return
|
||||
}
|
||||
|
||||
if n != 9 {
|
||||
t.Fatalf("failed to writ the expected bytes; expected: 9, written: %d", n)
|
||||
}
|
||||
|
||||
if err != errTest {
|
||||
t.Fatalf("failed to receive the right error; expected: %v, received: %v", errTest, err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("multiple objects, fail first", func(t *testing.T) {
|
||||
o := struct{ fooBarBaz int }{42}
|
||||
w := failAfter(9)
|
||||
n, err := Fprint(w, o, o)
|
||||
if n == 9 && err == errTest {
|
||||
return
|
||||
}
|
||||
|
||||
if n != 9 {
|
||||
t.Fatalf("failed to writ the expected bytes; expected: 9, written: %d", n)
|
||||
}
|
||||
|
||||
if err != errTest {
|
||||
t.Fatalf("failed to receive the right error; expected: %v, received: %v", errTest, err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("multiple objects, fail second", func(t *testing.T) {
|
||||
o := struct{ fooBarBaz int }{42}
|
||||
w := failAfter(18)
|
||||
n, err := Fprint(w, o, o)
|
||||
if n == 9 && err == errTest {
|
||||
return
|
||||
}
|
||||
|
||||
if n != 18 {
|
||||
t.Fatalf("failed to writ the expected bytes; expected: 9, written: %d", n)
|
||||
}
|
||||
|
||||
if err != errTest {
|
||||
t.Fatalf("failed to receive the right error; expected: %v, received: %v", errTest, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestFprint(t *testing.T) {
|
||||
t.Run("Fprint", func(t *testing.T) {
|
||||
const expect = `{fooBarBaz: 42}`
|
||||
var b bytes.Buffer
|
||||
o := struct{ fooBarBaz int }{42}
|
||||
defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")()
|
||||
n, err := Fprint(&b, o)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n != len(expect) {
|
||||
t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n)
|
||||
}
|
||||
|
||||
if b.String() != expect {
|
||||
t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Fprintw", func(t *testing.T) {
|
||||
const expect = `{
|
||||
fooBarBaz: 42,
|
||||
}`
|
||||
|
||||
var b bytes.Buffer
|
||||
o := struct{ fooBarBaz int }{42}
|
||||
defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")()
|
||||
n, err := Fprintw(&b, o)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n != len(expect) {
|
||||
t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n)
|
||||
}
|
||||
|
||||
if b.String() != expect {
|
||||
t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Fprintt", func(t *testing.T) {
|
||||
const expect = `struct{fooBarBaz int}{fooBarBaz: 42}`
|
||||
var b bytes.Buffer
|
||||
o := struct{ fooBarBaz int }{42}
|
||||
defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")()
|
||||
n, err := Fprintt(&b, o)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n != len(expect) {
|
||||
t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n)
|
||||
}
|
||||
|
||||
if b.String() != expect {
|
||||
t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Fprintwt", func(t *testing.T) {
|
||||
const expect = `struct{
|
||||
fooBarBaz int
|
||||
}{
|
||||
fooBarBaz: 42,
|
||||
}`
|
||||
|
||||
var b bytes.Buffer
|
||||
o := struct{ fooBarBaz int }{42}
|
||||
defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")()
|
||||
n, err := Fprintwt(&b, o)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n != len(expect) {
|
||||
t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n)
|
||||
}
|
||||
|
||||
if b.String() != expect {
|
||||
t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Fprintv", func(t *testing.T) {
|
||||
const expect = `struct{fooBarBaz int}{fooBarBaz: int(42)}`
|
||||
var b bytes.Buffer
|
||||
o := struct{ fooBarBaz int }{42}
|
||||
defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")()
|
||||
n, err := Fprintv(&b, o)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n != len(expect) {
|
||||
t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n)
|
||||
}
|
||||
|
||||
if b.String() != expect {
|
||||
t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Fprintv", func(t *testing.T) {
|
||||
const expect = `struct{
|
||||
fooBarBaz int
|
||||
}{
|
||||
fooBarBaz: int(42),
|
||||
}`
|
||||
var b bytes.Buffer
|
||||
o := struct{ fooBarBaz int }{42}
|
||||
defer withEnv(t, "TABWIDTH=0", "LINEWIDTH=0", "LINEWIDTH1=0")()
|
||||
n, err := Fprintwv(&b, o)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n != len(expect) {
|
||||
t.Fatalf("invalid write length; expected: %d, got: %d", len(expect), n)
|
||||
}
|
||||
|
||||
if b.String() != expect {
|
||||
t.Fatalf("invalid output; expected: %s, got: %s", expect, b.String())
|
||||
}
|
||||
})
|
||||
}
|
58
notation.go
58
notation.go
@ -2,6 +2,7 @@ package notation
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
@ -18,17 +19,63 @@ const (
|
||||
types
|
||||
skipTypes
|
||||
allTypes
|
||||
randomMaps
|
||||
)
|
||||
|
||||
type wrapLen struct {
|
||||
first, max, last int
|
||||
}
|
||||
|
||||
type node struct {
|
||||
len, wlen, wlen0, wlenLast int
|
||||
len int
|
||||
wrapLen wrapLen
|
||||
fullWrap wrapLen
|
||||
wrap bool
|
||||
parts []interface{}
|
||||
}
|
||||
|
||||
type wrapMode int
|
||||
|
||||
const (
|
||||
block wrapMode = iota
|
||||
line
|
||||
)
|
||||
|
||||
type wrapper struct {
|
||||
mode wrapMode
|
||||
sep, suffix string
|
||||
items []node
|
||||
lineWrappers []int
|
||||
}
|
||||
|
||||
type writer struct {
|
||||
w io.Writer
|
||||
n int
|
||||
err error
|
||||
}
|
||||
|
||||
func (n node) String() string {
|
||||
var b bytes.Buffer
|
||||
w := &writer{w: &b}
|
||||
fprint(w, 0, n)
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func (w *writer) write(o interface{}) {
|
||||
if w.err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
n, err := fmt.Fprint(w.w, o)
|
||||
w.n += n
|
||||
w.err = err
|
||||
}
|
||||
|
||||
func (w *writer) line(t int) {
|
||||
w.write("\n")
|
||||
for i := 0; i < t; i++ {
|
||||
w.write("\t")
|
||||
}
|
||||
}
|
||||
|
||||
func nodeOf(parts ...interface{}) node {
|
||||
@ -55,8 +102,13 @@ func config(name string, dflt int) int {
|
||||
|
||||
func fprintValues(w io.Writer, o opts, v []interface{}) (int, error) {
|
||||
tab := config("TABWIDTH", 8)
|
||||
cols0 := config("LINEWIDTH", 80-8)
|
||||
cols1 := config("LINEWIDTH1", (cols0+8)*3/2-8)
|
||||
cols0 := config("LINEWIDTH", 80-tab)
|
||||
cols1 := config("LINEWIDTH1", (cols0+tab)*3/2-tab)
|
||||
sortMaps := config("MAPSORT", 1)
|
||||
if sortMaps == 0 {
|
||||
o |= randomMaps
|
||||
}
|
||||
|
||||
wr := &writer{w: w}
|
||||
for i, vi := range v {
|
||||
if wr.err != nil {
|
||||
|
46
reflect.go
46
reflect.go
@ -46,16 +46,32 @@ func reflectPrimitive(o opts, r reflect.Value, v interface{}, suppressType ...st
|
||||
return nodeOf(tn, "(", s, ")")
|
||||
}
|
||||
|
||||
func reflectNil(o opts, r reflect.Value) node {
|
||||
func reflectNil(o opts, groupUnnamedType bool, r reflect.Value) node {
|
||||
if _, _, a := withType(o); !a {
|
||||
return nodeOf("nil")
|
||||
}
|
||||
|
||||
return nodeOf(reflectType(r.Type()), "(nil)")
|
||||
rt := r.Type()
|
||||
if groupUnnamedType && rt.Name() == "" {
|
||||
return nodeOf("(", reflectType(rt), ")(nil)")
|
||||
}
|
||||
|
||||
return nodeOf(reflectType(rt), "(nil)")
|
||||
}
|
||||
|
||||
func reflectItems(o opts, prefix string, r reflect.Value) node {
|
||||
items := wrapper{sep: ", ", suffix: ","}
|
||||
typ := r.Type()
|
||||
var items wrapper
|
||||
if typ.Elem().Name() == "uint8" {
|
||||
items = wrapper{sep: " ", mode: line}
|
||||
for i := 0; i < r.Len(); i++ {
|
||||
items.items = append(
|
||||
items.items,
|
||||
nodeOf(fmt.Sprintf("%02x", r.Index(i).Uint())),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
items = wrapper{sep: ", ", suffix: ","}
|
||||
itemOpts := o | skipTypes
|
||||
for i := 0; i < r.Len(); i++ {
|
||||
items.items = append(
|
||||
@ -63,17 +79,18 @@ func reflectItems(o opts, prefix string, r reflect.Value) node {
|
||||
reflectValue(itemOpts, r.Index(i)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if _, t, _ := withType(o); !t {
|
||||
return nodeOf(prefix, "{", items, "}")
|
||||
}
|
||||
|
||||
return nodeOf(reflectType(r.Type()), "{", items, "}")
|
||||
return nodeOf(reflectType(typ), "{", items, "}")
|
||||
}
|
||||
|
||||
func reflectHidden(o opts, hidden string, r reflect.Value) node {
|
||||
if r.IsNil() {
|
||||
return reflectNil(o, r)
|
||||
return reflectNil(o, true, r)
|
||||
}
|
||||
|
||||
if _, t, _ := withType(o); !t {
|
||||
@ -97,7 +114,7 @@ func reflectFunc(o opts, r reflect.Value) node {
|
||||
|
||||
func reflectInterface(o opts, r reflect.Value) node {
|
||||
if r.IsNil() {
|
||||
return reflectNil(o, r)
|
||||
return reflectNil(o, false, r)
|
||||
}
|
||||
|
||||
e := reflectValue(o, r.Elem())
|
||||
@ -115,7 +132,7 @@ func reflectInterface(o opts, r reflect.Value) node {
|
||||
|
||||
func reflectMap(o opts, r reflect.Value) node {
|
||||
if r.IsNil() {
|
||||
return reflectNil(o, r)
|
||||
return reflectNil(o, true, r)
|
||||
}
|
||||
|
||||
var (
|
||||
@ -140,7 +157,10 @@ func reflectMap(o opts, r reflect.Value) node {
|
||||
sn[skey] = nk
|
||||
}
|
||||
|
||||
if o&randomMaps == 0 {
|
||||
sort.Strings(skeys)
|
||||
}
|
||||
|
||||
for _, skey := range skeys {
|
||||
items.items = append(
|
||||
items.items,
|
||||
@ -161,7 +181,7 @@ func reflectMap(o opts, r reflect.Value) node {
|
||||
|
||||
func reflectPointer(o opts, r reflect.Value) node {
|
||||
if r.IsNil() {
|
||||
return reflectNil(o, r)
|
||||
return reflectNil(o, true, r)
|
||||
}
|
||||
|
||||
e := reflectValue(o, r.Elem())
|
||||
@ -174,7 +194,7 @@ func reflectPointer(o opts, r reflect.Value) node {
|
||||
|
||||
func reflectList(o opts, r reflect.Value) node {
|
||||
if r.IsNil() {
|
||||
return reflectNil(o, r)
|
||||
return reflectNil(o, true, r)
|
||||
}
|
||||
|
||||
return reflectItems(o, "[]", r)
|
||||
@ -221,7 +241,7 @@ func reflectString(o opts, r reflect.Value) node {
|
||||
}
|
||||
|
||||
func reflectStruct(o opts, r reflect.Value) node {
|
||||
wr := wrapper{sep: ", "}
|
||||
wr := wrapper{sep: ", ", suffix: ","}
|
||||
|
||||
fieldOpts := o | skipTypes
|
||||
rt := r.Type()
|
||||
@ -249,7 +269,7 @@ func reflectStruct(o opts, r reflect.Value) node {
|
||||
|
||||
func reflectUnsafePointer(o opts, r reflect.Value) node {
|
||||
if r.IsNil() {
|
||||
return reflectNil(o, r)
|
||||
return reflectNil(o, false, r)
|
||||
}
|
||||
|
||||
if _, _, a := withType(o); !a {
|
||||
@ -298,11 +318,9 @@ func reflectValue(o opts, r reflect.Value) node {
|
||||
return reflectList(o, r)
|
||||
case reflect.String:
|
||||
return reflectString(o, r)
|
||||
case reflect.Struct:
|
||||
return reflectStruct(o, r)
|
||||
case reflect.UnsafePointer:
|
||||
return reflectUnsafePointer(o, r)
|
||||
default:
|
||||
return nodeOf("<invalid>")
|
||||
return reflectStruct(o, r)
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,17 @@
|
||||
package notation
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
import "reflect"
|
||||
|
||||
func reflectFuncBaseType(t reflect.Type) node {
|
||||
isVariadic := t.IsVariadic()
|
||||
args := func(num func() int, typ func(int) reflect.Type) []node {
|
||||
var t []node
|
||||
for i := 0; i < num(); i++ {
|
||||
if i == num()-1 && isVariadic {
|
||||
t = append(t, nodeOf("...", reflectType(typ(i).Elem())))
|
||||
continue
|
||||
}
|
||||
|
||||
t = append(t, reflectType(typ(i)))
|
||||
}
|
||||
|
||||
@ -21,14 +25,14 @@ func reflectFuncBaseType(t reflect.Type) node {
|
||||
if len(in) == 1 {
|
||||
n.parts = append(n.parts, in[0])
|
||||
} else if len(in) > 1 {
|
||||
n.parts = append(n.parts, wrapper{sep: ", ", items: in})
|
||||
n.parts = append(n.parts, wrapper{sep: ", ", suffix: ",", items: in})
|
||||
}
|
||||
|
||||
n.parts = append(n.parts, ")")
|
||||
if len(out) == 1 {
|
||||
n.parts = append(n.parts, " ", out[0])
|
||||
} else if len(out) > 1 {
|
||||
n.parts = append(n.parts, " (", wrapper{sep: ", ", items: out}, ")")
|
||||
n.parts = append(n.parts, " (", wrapper{sep: ", ", suffix: ",", items: out}, ")")
|
||||
}
|
||||
|
||||
return n
|
||||
@ -103,7 +107,12 @@ func reflectStructType(t reflect.Type) node {
|
||||
|
||||
func reflectType(t reflect.Type) node {
|
||||
if t.Name() != "" {
|
||||
return nodeOf(t.Name())
|
||||
name := t.Name()
|
||||
if name == "uint8" {
|
||||
name = "byte"
|
||||
}
|
||||
|
||||
return nodeOf(name)
|
||||
}
|
||||
|
||||
switch t.Kind() {
|
||||
@ -121,9 +130,7 @@ func reflectType(t reflect.Type) node {
|
||||
return reflectPointerType(t)
|
||||
case reflect.Slice:
|
||||
return reflectListType(t)
|
||||
case reflect.Struct:
|
||||
return reflectStructType(t)
|
||||
default:
|
||||
return nodeOf("<invalid>")
|
||||
return reflectStructType(t)
|
||||
}
|
||||
}
|
||||
|
1034
sprint_test.go
1034
sprint_test.go
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user