diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index d4ca188d2..781d0ff0c 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -57,7 +57,8 @@ jobs: run: | date find . -name "*.go" | xargs gofmt -w - git diff --name-only --exit-code || exit 1 + git diff --name-only --exit-code || if [ $? != 0 ];then echo "Notice: gofmt check failed,please gofmt before pr." && exit 1; fi + echo "gofmt check pass." sudo echo "127.0.0.1 local" | sudo tee -a /etc/hosts - name: Run i386 Arch Test diff --git a/encoding/gjson/gjson_api.go b/encoding/gjson/gjson_api.go index c08c75d15..f92b14564 100644 --- a/encoding/gjson/gjson_api.go +++ b/encoding/gjson/gjson_api.go @@ -179,10 +179,3 @@ func (j *Json) Dump() { defer j.mu.RUnlock() gutil.Dump(*j.p) } - -// Export returns `j` as a string with more manually readable. -func (j *Json) Export() string { - j.mu.RLock() - defer j.mu.RUnlock() - return gutil.Export(*j.p, gutil.ExportOption{}) -} diff --git a/frame/g/g_func.go b/frame/g/g_func.go index 4d90b9f79..f4a169325 100644 --- a/frame/g/g_func.go +++ b/frame/g/g_func.go @@ -8,6 +8,7 @@ package g import ( "context" + "io" "github.com/gogf/gf/v2/container/gvar" "github.com/gogf/gf/v2/internal/empty" @@ -39,12 +40,22 @@ func Dump(values ...interface{}) { gutil.Dump(values...) } +// DumpTo writes variables `values` as a string in to `writer` with more manually readable +func DumpTo(writer io.Writer, value interface{}, option gutil.DumpOption) { + gutil.DumpTo(writer, value, option) +} + // DumpWithType acts like Dump, but with type information. // Also see Dump. func DumpWithType(values ...interface{}) { gutil.DumpWithType(values...) } +// DumpWithOption returns variables `values` as a string with more manually readable. +func DumpWithOption(value interface{}, option gutil.DumpOption) { + gutil.DumpWithOption(value, option) +} + // Throw throws an exception, which can be caught by TryCatch function. func Throw(exception interface{}) { gutil.Throw(exception) diff --git a/os/gres/gres_z_unit_test.go b/os/gres/gres_z_unit_test.go index 06c61a1c6..0438013e2 100644 --- a/os/gres/gres_z_unit_test.go +++ b/os/gres/gres_z_unit_test.go @@ -7,6 +7,8 @@ package gres_test import ( + _ "github.com/gogf/gf/v2/os/gres/testdata/data" + "strings" "testing" @@ -20,22 +22,26 @@ import ( func Test_PackToGoFile(t *testing.T) { gtest.C(t, func(t *gtest.T) { - srcPath := gdebug.TestDataPath("files") - goFilePath := gdebug.TestDataPath("testdata.go") - pkgName := "testdata" - err := gres.PackToGoFile(srcPath, goFilePath, pkgName) + var ( + srcPath = gdebug.TestDataPath("files") + goFilePath = gfile.TempDir(gtime.TimestampNanoStr(), "testdata.go") + pkgName = "testdata" + err = gres.PackToGoFile(srcPath, goFilePath, pkgName) + ) t.Assert(err, nil) + _ = gfile.Remove(goFilePath) }) } func Test_Pack(t *testing.T) { gtest.C(t, func(t *gtest.T) { - srcPath := gdebug.TestDataPath("files") - data, err := gres.Pack(srcPath) + var ( + srcPath = gdebug.TestDataPath("files") + data, err = gres.Pack(srcPath) + ) t.Assert(err, nil) r := gres.New() - err = r.Add(string(data)) t.Assert(err, nil) t.Assert(r.Contains("files/"), true) @@ -44,9 +50,11 @@ func Test_Pack(t *testing.T) { func Test_PackToFile(t *testing.T) { gtest.C(t, func(t *gtest.T) { - srcPath := gdebug.TestDataPath("files") - dstPath := gfile.TempDir(gtime.TimestampNanoStr()) - err := gres.PackToFile(srcPath, dstPath) + var ( + srcPath = gdebug.TestDataPath("files") + dstPath = gfile.TempDir(gtime.TimestampNanoStr()) + err = gres.PackToFile(srcPath, dstPath) + ) t.Assert(err, nil) defer gfile.Remove(dstPath) @@ -60,33 +68,42 @@ func Test_PackToFile(t *testing.T) { func Test_PackMulti(t *testing.T) { gtest.C(t, func(t *gtest.T) { - srcPath := gdebug.TestDataPath("files") - goFilePath := gdebug.TestDataPath("data/data.go") - pkgName := "data" - array, err := gfile.ScanDir(srcPath, "*", false) + var ( + srcPath = gdebug.TestDataPath("files") + goFilePath = gfile.TempDir(gtime.TimestampNanoStr(), "data.go") + pkgName = "data" + array, err = gfile.ScanDir(srcPath, "*", false) + ) t.Assert(err, nil) err = gres.PackToGoFile(strings.Join(array, ","), goFilePath, pkgName) t.Assert(err, nil) + _ = gfile.Remove(goFilePath) }) } func Test_PackWithPrefix1(t *testing.T) { gtest.C(t, func(t *gtest.T) { - srcPath := gdebug.TestDataPath("files") - goFilePath := gfile.TempDir("testdata.go") - pkgName := "testdata" - err := gres.PackToGoFile(srcPath, goFilePath, pkgName, "www/gf-site/test") - t.Assert(err, nil) + var ( + srcPath = gdebug.TestDataPath("files") + goFilePath = gfile.TempDir(gtime.TimestampNanoStr(), "testdata.go") + pkgName = "testdata" + err = gres.PackToGoFile(srcPath, goFilePath, pkgName, "www/gf-site/test") + ) + t.AssertNil(err) + _ = gfile.Remove(goFilePath) }) } func Test_PackWithPrefix2(t *testing.T) { gtest.C(t, func(t *gtest.T) { - srcPath := gdebug.TestDataPath("files") - goFilePath := gfile.TempDir("testdata.go") - pkgName := "testdata" - err := gres.PackToGoFile(srcPath, goFilePath, pkgName, "/var/www/gf-site/test") + var ( + srcPath = gdebug.TestDataPath("files") + goFilePath = gfile.TempDir(gtime.TimestampNanoStr(), "testdata.go") + pkgName = "testdata" + err = gres.PackToGoFile(srcPath, goFilePath, pkgName, "/var/www/gf-site/test") + ) t.Assert(err, nil) + _ = gfile.Remove(goFilePath) }) } diff --git a/os/gres/testdata/data/data.go b/os/gres/testdata/data/data.go index a722d54ad..601b7f3ed 100644 --- a/os/gres/testdata/data/data.go +++ b/os/gres/testdata/data/data.go @@ -3,7 +3,7 @@ package data import "github.com/gogf/gf/v2/os/gres" func init() { - if err := gres.Add("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"); err != nil { + if err := gres.Add("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"); err != nil { panic("add binary content to resource manager failed: " + err.Error()) } } diff --git a/os/gres/testdata/testdata.go b/os/gres/testdata/testdata.go index 382cc18a8..c391ce058 100644 --- a/os/gres/testdata/testdata.go +++ b/os/gres/testdata/testdata.go @@ -3,7 +3,7 @@ package testdata import "github.com/gogf/gf/v2/os/gres" func init() { - if err := gres.Add("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"); err != nil { + if err := gres.Add("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"); err != nil { panic("add binary content to resource manager failed: " + err.Error()) } } diff --git a/os/gview/gview_buildin.go b/os/gview/gview_buildin.go index 2728b76ed..82ee14641 100644 --- a/os/gview/gview_buildin.go +++ b/os/gview/gview_buildin.go @@ -7,6 +7,7 @@ package gview import ( + "bytes" "context" "fmt" htmltpl "html/template" @@ -22,13 +23,15 @@ import ( ) // buildInFuncDump implements build-in template function: dump -func (view *View) buildInFuncDump(values ...interface{}) (result string) { - result += "\n" - return result + buffer.WriteString("-->\n") + return buffer.String() } // buildInFuncMap implements build-in template function: map diff --git a/os/gview/gview_z_unit_test.go b/os/gview/gview_z_unit_test.go index 6311f7ad7..680c129a6 100644 --- a/os/gview/gview_z_unit_test.go +++ b/os/gview/gview_z_unit_test.go @@ -8,7 +8,7 @@ package gview_test import ( "context" - "io/ioutil" + "fmt" "os" "strings" "testing" @@ -215,39 +215,39 @@ func Test_FuncNl2Br(t *testing.T) { func Test_FuncInclude(t *testing.T) { gtest.C(t, func(t *gtest.T) { - header := `

HEADER

` - main := `

hello gf

` - footer := `

FOOTER

` - layout := `{{include "header.html" .}} + var ( + header = `

HEADER

` + main = `

hello gf

` + footer = `

FOOTER

` + layout = `{{include "header.html" .}} {{include "main.html" .}} {{include "footer.html" .}}` - templatePath := gfile.Pwd() + gfile.Separator + "template" + templatePath = gfile.TempDir("template") + ) + gfile.Mkdir(templatePath) defer gfile.Remove(templatePath) - // headerFile, _ := gfile.Create(templatePath + gfile.Separator + "header.html") - err := ioutil.WriteFile(templatePath+gfile.Separator+"header.html", []byte(header), 0644) - if err != nil { - t.Error(err) - } - ioutil.WriteFile(templatePath+gfile.Separator+"main.html", []byte(main), 0644) - ioutil.WriteFile(templatePath+gfile.Separator+"footer.html", []byte(footer), 0644) - ioutil.WriteFile(templatePath+gfile.Separator+"layout.html", []byte(layout), 0644) + + t.AssertNil(gfile.PutContents(gfile.Join(templatePath, `header.html`), header)) + t.AssertNil(gfile.PutContents(gfile.Join(templatePath, `main.html`), main)) + t.AssertNil(gfile.PutContents(gfile.Join(templatePath, `footer.html`), footer)) + t.AssertNil(gfile.PutContents(gfile.Join(templatePath, `layout.html`), layout)) + view := gview.New(templatePath) result, err := view.Parse(context.TODO(), "notfound.html") - t.Assert(err != nil, true) + t.AssertNE(err, nil) t.Assert(result, ``) + result, err = view.Parse(context.TODO(), "layout.html") - t.Assert(err != nil, false) + t.AssertNil(err) t.Assert(result, `

HEADER

hello gf

FOOTER

`) - notfoundPath := templatePath + gfile.Separator + "template" + gfile.Separator + "notfound.html" - gfile.Mkdir(templatePath + gfile.Separator + "template") - gfile.Create(notfoundPath) - ioutil.WriteFile(notfoundPath, []byte("notfound"), 0644) + + t.AssertNil(gfile.PutContents(gfile.Join(templatePath, `notfound.html`), "notfound")) result, err = view.Parse(context.TODO(), "notfound.html") - t.Assert(err != nil, true) - t.Assert(result, ``) + t.AssertNil(err) + t.Assert(result, `notfound`) }) } @@ -411,6 +411,7 @@ func Test_BuildInFuncDump(t *testing.T) { }) r, err := v.ParseContent(context.TODO(), "{{dump .}}") t.Assert(err, nil) + fmt.Println(r) t.Assert(gstr.Contains(r, `"name": "john"`), true) t.Assert(gstr.Contains(r, `"score": 100`), true) }) diff --git a/text/gstr/gstr_case.go b/text/gstr/gstr_case.go index c09cacc2a..0f70f27b9 100644 --- a/text/gstr/gstr_case.go +++ b/text/gstr/gstr_case.go @@ -94,7 +94,7 @@ func CaseKebabScreaming(s string) string { } // CaseDelimited converts a string to snake.case.delimited. -func CaseDelimited(s string, del uint8) string { +func CaseDelimited(s string, del byte) string { return CaseDelimitedScreaming(s, del, false) } diff --git a/text/gstr/gstr_version.go b/text/gstr/gstr_version.go index e88c8c9e6..f5d478c63 100644 --- a/text/gstr/gstr_version.go +++ b/text/gstr/gstr_version.go @@ -7,8 +7,9 @@ package gstr import ( - "github.com/gogf/gf/v2/util/gconv" "strings" + + "github.com/gogf/gf/v2/util/gconv" ) // CompareVersion compares `a` and `b` as standard GNU version. @@ -71,12 +72,18 @@ func CompareVersion(a, b string) int { // v4.20.0+incompatible // etc. func CompareVersionGo(a, b string) int { + a = Trim(a) + b = Trim(b) if a != "" && a[0] == 'v' { a = a[1:] } if b != "" && b[0] == 'v' { b = b[1:] } + var ( + rawA = a + rawB = b + ) if Count(a, "-") > 1 { if i := PosR(a, "-"); i > 0 { a = a[:i] @@ -108,6 +115,7 @@ func CompareVersionGo(a, b string) int { if len(array1) <= 3 && len(array2) > 3 { return 1 } + diff = len(array2) - len(array1) for i := 0; i < diff; i++ { array1 = append(array1, "0") @@ -128,5 +136,13 @@ func CompareVersionGo(a, b string) int { return -1 } } + // Specially in Golang: + // "v4.20.1+incompatible" < "v4.20.1" + if Contains(rawA, "incompatible") { + return -1 + } + if Contains(rawB, "incompatible") { + return 1 + } return 0 } diff --git a/text/gstr/gstr_z_example_test.go b/text/gstr/gstr_z_example_test.go new file mode 100644 index 000000000..c21805713 --- /dev/null +++ b/text/gstr/gstr_z_example_test.go @@ -0,0 +1,1236 @@ +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gstr_test + +import ( + "fmt" + + "github.com/gogf/gf/v2/text/gstr" +) + +func ExampleAddSlashes() { + var ( + str = `'aa'"bb"cc\r\n\d\t` + result = gstr.AddSlashes(str) + ) + + fmt.Println(result) + + // Output: + // \'aa\'\"bb\"cc\\r\\n\\d\\t +} + +func ExampleCaseCamel() { + var ( + str = `hello world` + result = gstr.CaseCamel(str) + ) + fmt.Println(result) + + // Output: + // HelloWorld +} + +func ExampleCaseCamelLower() { + var ( + str = `hello world` + result = gstr.CaseCamelLower(str) + ) + fmt.Println(result) + + // Output: + // helloWorld +} + +func ExampleCaseDelimited() { + var ( + str = `hello world` + del = byte('-') + result = gstr.CaseDelimited(str, del) + ) + fmt.Println(result) + + // Output: + // hello-world +} + +func ExampleCaseDelimitedScreaming() { + { + var ( + str = `hello world` + del = byte('-') + result = gstr.CaseDelimitedScreaming(str, del, true) + ) + fmt.Println(result) + } + { + var ( + str = `hello world` + del = byte('-') + result = gstr.CaseDelimitedScreaming(str, del, false) + ) + fmt.Println(result) + } + + // Output: + // HELLO-WORLD + // hello-world +} + +func ExampleCaseKebab() { + var ( + str = `hello world` + result = gstr.CaseKebab(str) + ) + fmt.Println(result) + + // Output: + // hello-world +} + +func ExampleCaseKebabScreaming() { + var ( + str = `hello world` + result = gstr.CaseKebabScreaming(str) + ) + fmt.Println(result) + + // Output: + // HELLO-WORLD +} + +func ExampleCaseSnake() { + var ( + str = `hello world` + result = gstr.CaseSnake(str) + ) + fmt.Println(result) + + // Output: + // hello_world +} + +func ExampleCaseSnakeFirstUpper() { + var ( + str = `RGBCodeMd5` + result = gstr.CaseSnakeFirstUpper(str) + ) + fmt.Println(result) + + // Output: + // rgb_code_md5 +} + +func ExampleCaseSnakeScreaming() { + var ( + str = `hello world` + result = gstr.CaseSnakeScreaming(str) + ) + fmt.Println(result) + + // Output: + // HELLO_WORLD +} + +func ExampleChr() { + var ( + ascii = 65 // A + result = gstr.Chr(ascii) + ) + fmt.Println(result) + + // Output: + // A +} + +func ExampleChunkSplit() { + var ( + body = `1234567890` + chunkLen = 2 + end = "#" + result = gstr.ChunkSplit(body, chunkLen, end) + ) + fmt.Println(result) + + // Output: + // 12#34#56#78#90# +} + +func ExampleCompare() { + fmt.Println(gstr.Compare("c", "c")) + fmt.Println(gstr.Compare("a", "b")) + fmt.Println(gstr.Compare("c", "b")) + + // Output: + // 0 + // -1 + // 1 +} + +func ExampleCompareVersion() { + fmt.Println(gstr.CompareVersion("v2.11.9", "v2.10.8")) + fmt.Println(gstr.CompareVersion("1.10.8", "1.19.7")) + fmt.Println(gstr.CompareVersion("2.8.beta", "2.8")) + + // Output: + // 1 + // -1 + // 0 +} + +func ExampleCompareVersionGo() { + fmt.Println(gstr.CompareVersionGo("v2.11.9", "v2.10.8")) + fmt.Println(gstr.CompareVersionGo("v4.20.1", "v4.20.1+incompatible")) + fmt.Println(gstr.CompareVersionGo( + "v0.0.2-20180626092158-b2ccc119800e", + "v1.0.1-20190626092158-b2ccc519800e", + )) + + // Output: + // 1 + // 1 + // -1 +} + +func ExampleContains() { + { + var ( + str = `Hello World` + substr = `Hello` + result = gstr.Contains(str, substr) + ) + fmt.Println(result) + } + { + var ( + str = `Hello World` + substr = `hello` + result = gstr.Contains(str, substr) + ) + fmt.Println(result) + } + + // Output: + // true + // false +} + +func ExampleContainsAny() { + { + var ( + s = `goframe` + chars = "g" + result = gstr.ContainsAny(s, chars) + ) + fmt.Println(result) + } + { + var ( + s = `goframe` + chars = "G" + result = gstr.ContainsAny(s, chars) + ) + fmt.Println(result) + } + + // Output: + // true + // false +} + +func ExampleContainsI() { + var ( + str = `Hello World` + substr = "hello" + result1 = gstr.Contains(str, substr) + result2 = gstr.ContainsI(str, substr) + ) + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // false + // true +} + +func ExampleCount() { + var ( + str = `goframe is very, very easy to use` + substr1 = "goframe" + substr2 = "very" + result1 = gstr.Count(str, substr1) + result2 = gstr.Count(str, substr2) + ) + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1 + // 2 +} + +func ExampleCountChars() { + var ( + str = `goframe` + result = gstr.CountChars(str) + ) + fmt.Println(result) + + // May Output: + // map[a:1 e:1 f:1 g:1 m:1 o:1 r:1] + +} + +func ExampleCountI() { + var ( + str = `goframe is very, very easy to use` + substr1 = "GOFRAME" + substr2 = "VERY" + result1 = gstr.CountI(str, substr1) + result2 = gstr.CountI(str, substr2) + ) + fmt.Println(result1) + fmt.Println(result2) + + // Output: + // 1 + // 2 +} + +func ExampleCountWords() { + var ( + str = `goframe is very, very easy to use!` + result = gstr.CountWords(str) + ) + fmt.Printf(`%#v`, result) + + // Output: + // map[string]int{"easy":1, "goframe":1, "is":1, "to":1, "use!":1, "very":1, "very,":1} +} + +func ExampleEqual() { + fmt.Println(gstr.Equal(`A`, `a`)) + fmt.Println(gstr.Equal(`A`, `A`)) + fmt.Println(gstr.Equal(`A`, `B`)) + + // Output: + // true + // true + // false +} + +func ExampleExplode() { + var ( + str = `Hello World` + delimiter = " " + result = gstr.Explode(delimiter, str) + ) + fmt.Printf(`%#v`, result) + + // Output: + // []string{"Hello", "World"} +} + +func ExampleFields() { + var ( + str = `Hello World` + result = gstr.Fields(str) + ) + fmt.Printf(`%#v`, result) + + // Output: + // []string{"Hello", "World"} +} + +func ExampleHasPrefix() { + var ( + s = `Hello World` + prefix = "Hello" + result = gstr.HasPrefix(s, prefix) + ) + fmt.Println(result) + + // Output: + // true +} + +func ExampleHasSuffix() { + var ( + s = `my best love is goframe` + prefix = "goframe" + result = gstr.HasSuffix(s, prefix) + ) + fmt.Println(result) + + // Output: + // true +} + +func ExampleHideStr() { + var ( + str = `13800138000` + percent = 40 + hide = `*` + result = gstr.HideStr(str, percent, hide) + ) + fmt.Println(result) + + // Output: + // 138****8000 +} + +func ExampleImplode() { + var ( + pieces = []string{"goframe", "is", "very", "easy", "to", "use"} + glue = " " + result = gstr.Implode(glue, pieces) + ) + fmt.Println(result) + + // Output: + // goframe is very easy to use +} + +func ExampleInArray() { + var ( + a = []string{"goframe", "is", "very", "easy", "to", "use"} + s = "goframe" + result = gstr.InArray(a, s) + ) + fmt.Println(result) + + // Output: + // true +} + +func ExampleIsLetterLower() { + fmt.Println(gstr.IsLetterLower('a')) + fmt.Println(gstr.IsLetterLower('A')) + + // Output: + // true + // false +} + +func ExampleIsLetterUpper() { + fmt.Println(gstr.IsLetterUpper('A')) + fmt.Println(gstr.IsLetterUpper('a')) + + // Output: + // true + // false +} + +func ExampleIsNumeric() { + fmt.Println(gstr.IsNumeric("88")) + fmt.Println(gstr.IsNumeric("3.1415926")) + fmt.Println(gstr.IsNumeric("abc")) + // Output: + // true + // true + // false +} + +func ExampleIsSubDomain() { + var ( + subDomain = `s.goframe.org` + mainDomain = `goframe.org` + result = gstr.IsSubDomain(subDomain, mainDomain) + ) + fmt.Println(result) + + // Output: + // true +} + +func ExampleJoin() { + var ( + array = []string{"goframe", "is", "very", "easy", "to", "use"} + sep = ` ` + result = gstr.Join(array, sep) + ) + fmt.Println(result) + + // Output: + // goframe is very easy to use +} + +func ExampleJoinAny() { + var ( + sep = `,` + arr2 = []int{99, 73, 85, 66} + result = gstr.JoinAny(arr2, sep) + ) + fmt.Println(result) + + // Output: + // 99,73,85,66 +} + +func ExampleLcFirst() { + var ( + str = `Goframe` + result = gstr.LcFirst(str) + ) + fmt.Println(result) + + // Output: + // goframe +} + +func ExampleLenRune() { + var ( + str = `GoFrame框架` + result = gstr.LenRune(str) + ) + fmt.Println(result) + + // Output: + // 9 +} + +func ExampleLevenshtein() { + var ( + str1 = "Hello World" + str2 = "hallo World" + costIns = 1 + costRep = 1 + costDel = 1 + result = gstr.Levenshtein(str1, str2, costIns, costRep, costDel) + ) + fmt.Println(result) + + // Output: + // 2 +} + +func ExampleNl2Br() { + var ( + str = `goframe +is +very +easy +to +use` + result = gstr.Nl2Br(str) + ) + + fmt.Println(result) + + // Output: + // goframe
is
very
easy
to
use +} + +func ExampleNumberFormat() { + var ( + number float64 = 123456 + decimals = 2 + decPoint = "." + thousandsSep = "," + result = gstr.NumberFormat(number, decimals, decPoint, thousandsSep) + ) + fmt.Println(result) + + // Output: + // 123,456.00 +} + +func ExampleOctStr() { + var ( + str = `\346\200\241` + result = gstr.OctStr(str) + ) + fmt.Println(result) + + // Output: + // 怡 +} + +// '103' is the 'g' in ASCII +func ExampleOrd() { + var ( + str = `goframe` + result = gstr.Ord(str) + ) + + fmt.Println(result) + + // Output: + // 103 +} + +func ExampleParse() { + { + var ( + str = `v1=m&v2=n` + result, _ = gstr.Parse(str) + ) + fmt.Println(result) + } + { + var ( + str = `v[a][a]=m&v[a][b]=n` + result, _ = gstr.Parse(str) + ) + fmt.Println(result) + } + { + // The form of nested Slice is not yet supported. + var str = `v[][]=m&v[][]=n` + result, err := gstr.Parse(str) + if err != nil { + panic(err) + } + fmt.Println(result) + } + { + // This will produce an error. + var str = `v=m&v[a]=n` + result, err := gstr.Parse(str) + if err != nil { + println(err) + } + fmt.Println(result) + } + { + var ( + str = `a .[[b=c` + result, _ = gstr.Parse(str) + ) + fmt.Println(result) + } + + // May Output: + // map[v1:m v2:n] + // map[v:map[a:map[a:m b:n]]] + // map[v:map[]] + // Error: expected type 'map[string]interface{}' for key 'v', but got 'string' + // map[] + // map[a___[b:c] +} + +func ExamplePos() { + var ( + haystack = `Hello World` + needle = `World` + result = gstr.Pos(haystack, needle) + ) + fmt.Println(result) + + // Output: + // 6 +} + +func ExamplePosI() { + var ( + haystack = `goframe is very, very easy to use` + needle = `very` + posI = gstr.PosI(haystack, needle) + posR = gstr.PosR(haystack, needle) + ) + fmt.Println(posI) + fmt.Println(posR) + + // Output: + // 11 + // 17 +} + +func ExamplePosIRune() { + { + var ( + haystack = `GoFrame是一款模块化、高性能、企业级的Go基础开发框架` + needle = `高性能` + startOffset = 10 + result = gstr.PosIRune(haystack, needle, startOffset) + ) + fmt.Println(result) + } + { + var ( + haystack = `GoFrame是一款模块化、高性能、企业级的Go基础开发框架` + needle = `高性能` + startOffset = 30 + result = gstr.PosIRune(haystack, needle, startOffset) + ) + fmt.Println(result) + } + + // Output: + // 14 + // -1 +} + +func ExamplePosR() { + var ( + haystack = `goframe is very, very easy to use` + needle = `very` + posI = gstr.PosI(haystack, needle) + posR = gstr.PosR(haystack, needle) + ) + fmt.Println(posI) + fmt.Println(posR) + + // Output: + // 11 + // 17 +} + +func ExamplePosRI() { + var ( + haystack = `goframe is very, very easy to use` + needle = `VERY` + posI = gstr.PosI(haystack, needle) + posR = gstr.PosRI(haystack, needle) + ) + fmt.Println(posI) + fmt.Println(posR) + + // Output: + // 11 + // 17 +} + +func ExamplePosRIRune() { + var ( + haystack = `GoFrame是一款模块化、高性能、企业级的Go基础开发框架` + needle = `GO` + posI = gstr.PosIRune(haystack, needle) + posR = gstr.PosRIRune(haystack, needle) + ) + fmt.Println(posI) + fmt.Println(posR) + + // Output: + // 0 + // 22 +} + +func ExamplePosRRune() { + var ( + haystack = `GoFrame是一款模块化、高性能、企业级的Go基础开发框架` + needle = `Go` + posI = gstr.PosIRune(haystack, needle) + posR = gstr.PosRRune(haystack, needle) + ) + fmt.Println(posI) + fmt.Println(posR) + + // Output: + // 0 + // 22 +} + +func ExamplePosRune() { + var ( + haystack = `GoFrame是一款模块化、高性能、企业级的Go基础开发框架` + needle = `Go` + posI = gstr.PosRune(haystack, needle) + posR = gstr.PosRRune(haystack, needle) + ) + fmt.Println(posI) + fmt.Println(posR) + + // Output: + // 0 + // 22 +} + +func ExampleQuoteMeta() { + { + var ( + str = `.\+?[^]()` + result = gstr.QuoteMeta(str) + ) + fmt.Println(result) + } + { + var ( + str = `https://goframe.org/pages/viewpage.action?pageId=1114327` + result = gstr.QuoteMeta(str) + ) + fmt.Println(result) + } + + // Output: + // \.\\\+\?\[\^\]\(\) + // https://goframe\.org/pages/viewpage\.action\?pageId=1114327 + +} + +func ExampleRepeat() { + var ( + input = `goframe ` + multiplier = 3 + result = gstr.Repeat(input, multiplier) + ) + fmt.Println(result) + + // Output: + // goframe goframe goframe +} + +func ExampleReplace() { + var ( + origin = `golang is very nice!` + search = `golang` + replace = `goframe` + result = gstr.Replace(origin, search, replace) + ) + fmt.Println(result) + + // Output: + // goframe is very nice! +} + +func ExampleReplaceByArray() { + { + var ( + origin = `golang is very nice` + array = []string{"lang", "frame"} + result = gstr.ReplaceByArray(origin, array) + ) + fmt.Println(result) + } + { + var ( + origin = `golang is very good` + array = []string{"golang", "goframe", "good", "nice"} + result = gstr.ReplaceByArray(origin, array) + ) + fmt.Println(result) + } + + // Output: + // goframe is very nice + // goframe is very nice +} + +func ExampleReplaceByMap() { + { + var ( + origin = `golang is very nice` + replaces = map[string]string{ + "lang": "frame", + } + result = gstr.ReplaceByMap(origin, replaces) + ) + fmt.Println(result) + } + { + var ( + origin = `golang is very good` + replaces = map[string]string{ + "golang": "goframe", + "good": "nice", + } + result = gstr.ReplaceByMap(origin, replaces) + ) + fmt.Println(result) + } + + // Output: + // goframe is very nice + // goframe is very nice +} + +func ExampleReplaceI() { + var ( + origin = `golang is very nice!` + search = `GOLANG` + replace = `goframe` + result = gstr.ReplaceI(origin, search, replace) + ) + fmt.Println(result) + + // Output: + // goframe is very nice! +} + +func ExampleReplaceIByArray() { + var ( + origin = `golang is very Good` + array = []string{"Golang", "goframe", "GOOD", "nice"} + result = gstr.ReplaceIByArray(origin, array) + ) + + fmt.Println(result) + + // Output: + // goframe is very nice +} + +func ExampleReplaceIByMap() { + var ( + origin = `golang is very nice` + replaces = map[string]string{ + "Lang": "frame", + } + result = gstr.ReplaceIByMap(origin, replaces) + ) + fmt.Println(result) + + // Output: + // goframe is very nice +} + +func ExampleReverse() { + var ( + str = `123456` + result = gstr.Reverse(str) + ) + fmt.Println(result) + + // Output: + // 654321 +} + +func ExampleSearchArray() { + var ( + array = []string{"goframe", "is", "very", "nice"} + str = `goframe` + result = gstr.SearchArray(array, str) + ) + fmt.Println(result) + + // Output: + // 0 +} + +func ExampleShuffle() { + var ( + str = `123456` + result = gstr.Shuffle(str) + ) + fmt.Println(result) + + // May Output: + // 563214 +} + +func ExampleSimilarText() { + var ( + first = `AaBbCcDd` + second = `ad` + percent = 0.80 + result = gstr.SimilarText(first, second, &percent) + ) + fmt.Println(result) + + // Output: + // 2 +} + +func ExampleSoundex() { + var ( + str1 = `Hello` + str2 = `Hallo` + result1 = gstr.Soundex(str1) + result2 = gstr.Soundex(str2) + ) + fmt.Println(result1, result2) + + // Output: + // H400 H400 +} + +func ExampleSplit() { + var ( + str = `a|b|c|d` + delimiter = `|` + result = gstr.Split(str, delimiter) + ) + fmt.Printf(`%#v`, result) + + // Output: + // []string{"a", "b", "c", "d"} +} + +func ExampleSplitAndTrim() { + var ( + str = `a|b|||||c|d` + delimiter = `|` + result = gstr.SplitAndTrim(str, delimiter) + ) + fmt.Printf(`%#v`, result) + + // Output: + // []string{"a", "b", "c", "d"} +} + +func ExampleStr() { + var ( + haystack = `xxx.jpg` + needle = `.` + result = gstr.Str(haystack, needle) + ) + fmt.Println(result) + + // Output: + // .jpg +} + +func ExampleStrEx() { + var ( + haystack = `https://goframe.org/index.html?a=1&b=2` + needle = `?` + result = gstr.StrEx(haystack, needle) + ) + fmt.Println(result) + + // Output: + // a=1&b=2 +} + +func ExampleStrLimit() { + var ( + str = `123456789` + length = 3 + suffix = `...` + result = gstr.StrLimit(str, length, suffix) + ) + fmt.Println(result) + + // Output: + // 123... +} + +func ExampleStrLimitRune() { + var ( + str = `GoFrame是一款模块化、高性能、企业级的Go基础开发框架。` + length = 17 + suffix = "..." + result = gstr.StrLimitRune(str, length, suffix) + ) + fmt.Println(result) + + // Output: + // GoFrame是一款模块化、高性能... +} + +func ExampleStrTill() { + var ( + haystack = `https://goframe.org/index.html?test=123456` + needle = `?` + result = gstr.StrTill(haystack, needle) + ) + fmt.Println(result) + + // Output: + // https://goframe.org/index.html? +} + +func ExampleStrTillEx() { + var ( + haystack = `https://goframe.org/index.html?test=123456` + needle = `?` + result = gstr.StrTillEx(haystack, needle) + ) + fmt.Println(result) + + // Output: + // https://goframe.org/index.html +} + +func ExampleStripSlashes() { + var ( + str = `C:\\windows\\GoFrame\\test` + result = gstr.StripSlashes(str) + ) + fmt.Println(result) + + // Output: + // C:\windows\GoFrame\test +} + +func ExampleSubStr() { + var ( + str = `1234567890` + start = 0 + length = 4 + subStr = gstr.SubStr(str, start, length) + ) + fmt.Println(subStr) + + // Output: + // 1234 +} + +func ExampleSubStrRune() { + var ( + str = `GoFrame是一款模块化、高性能、企业级的Go基础开发框架。` + start = 14 + length = 3 + subStr = gstr.SubStrRune(str, start, length) + ) + fmt.Println(subStr) + + // Output: + // 高性能 +} + +func ExampleToLower() { + var ( + s = `GOFRAME` + result = gstr.ToLower(s) + ) + fmt.Println(result) + + // Output: + // goframe +} + +func ExampleToUpper() { + var ( + s = `goframe` + result = gstr.ToUpper(s) + ) + fmt.Println(result) + + // Output: + // GOFRAME +} + +func ExampleTrim() { + var ( + str = `*Hello World*` + characterMask = "*" + result = gstr.Trim(str, characterMask) + ) + fmt.Println(result) + + // Output: + // Hello World +} + +func ExampleTrimAll() { + var ( + str = `*Hello World*` + characterMask = "*" + result = gstr.TrimAll(str, characterMask) + ) + fmt.Println(result) + + // Output: + // HelloWorld +} + +func ExampleTrimLeft() { + var ( + str = `*Hello World*` + characterMask = "*" + result = gstr.TrimLeft(str, characterMask) + ) + fmt.Println(result) + + // Output: + // Hello World* +} + +func ExampleTrimLeftStr() { + var ( + str = `**Hello World**` + cut = "*" + count = 1 + result = gstr.TrimLeftStr(str, cut, count) + ) + fmt.Println(result) + + // Output: + // *Hello World** +} + +func ExampleTrimRight() { + var ( + str = `**Hello World**` + characterMask = "*def" // []byte{"*", "d", "e", "f"} + result = gstr.TrimRight(str, characterMask) + ) + fmt.Println(result) + + // Output: + // **Hello Worl +} + +func ExampleTrimRightStr() { + var ( + str = `Hello World!` + cut = "!" + count = -1 + result = gstr.TrimRightStr(str, cut, count) + ) + fmt.Println(result) + + // Output: + // Hello World +} + +func ExampleTrimStr() { + var ( + str = `Hello World` + cut = "World" + count = -1 + result = gstr.TrimStr(str, cut, count) + ) + fmt.Println(result) + + // Output: + // Hello +} + +func ExampleUcFirst() { + var ( + s = `hello` + result = gstr.UcFirst(s) + ) + fmt.Println(result) + + // Output: + // Hello +} + +func ExampleUcWords() { + var ( + str = `hello world` + result = gstr.UcWords(str) + ) + fmt.Println(result) + + // Output: + // Hello World +} + +func ExampleWordWrap() { + { + var ( + str = `A very long woooooooooooooooooord. and something` + width = 8 + br = "\n" + result = gstr.WordWrap(str, width, br) + ) + fmt.Println(result) + } + { + var ( + str = `The quick brown fox jumped over the lazy dog.` + width = 20 + br = "
\n" + result = gstr.WordWrap(str, width, br) + ) + fmt.Printf("%v", result) + } + + // Output: + // A very + // long + // woooooooooooooooooord. + // and + // something + // The quick brown fox
+ // jumped over the lazy
+ // dog. +} diff --git a/text/gstr/gstr_z_unit_version_test.go b/text/gstr/gstr_z_unit_version_test.go index 135d7093e..ff4475d6d 100644 --- a/text/gstr/gstr_z_unit_version_test.go +++ b/text/gstr/gstr_z_unit_version_test.go @@ -40,7 +40,7 @@ func Test_CompareVersionGo(t *testing.T) { t.AssertEQ(gstr.CompareVersionGo("1.0.0", "v1.0.0"), 0) t.AssertEQ(gstr.CompareVersionGo("v0.0.0-20190626092158-b2ccc519800e", "0.0.0-20190626092158"), 0) t.AssertEQ(gstr.CompareVersionGo("v0.0.0-20190626092159-b2ccc519800e", "0.0.0-20190626092158"), 1) - t.AssertEQ(gstr.CompareVersionGo("v4.20.0+incompatible", "4.20.0"), 0) + t.AssertEQ(gstr.CompareVersionGo("v4.20.0+incompatible", "4.20.0"), -1) t.AssertEQ(gstr.CompareVersionGo("v4.20.0+incompatible", "4.20.1"), -1) // Note that this comparison a < b. t.AssertEQ(gstr.CompareVersionGo("v1.12.2-0.20200413154443-b17e3a6804fa", "v1.12.2"), -1) diff --git a/util/gutil/gutil_dump.go b/util/gutil/gutil_dump.go index 7f264e36a..2e67c4ac6 100644 --- a/util/gutil/gutil_dump.go +++ b/util/gutil/gutil_dump.go @@ -27,19 +27,17 @@ type iMarshalJSON interface { MarshalJSON() ([]byte, error) } -// ExportOption specifies the behavior of function Export. -type ExportOption struct { - WithoutType bool // WithoutType specifies exported content has no type information. +// DumpOption specifies the behavior of function Export. +type DumpOption struct { + WithType bool // WithType specifies dumping content with type information. } // Dump prints variables `values` to stdout with more manually readable. func Dump(values ...interface{}) { for _, value := range values { - if s := Export(value, ExportOption{ - WithoutType: true, - }); s != "" { - fmt.Println(s) - } + DumpWithOption(value, DumpOption{ + WithType: false, + }) } } @@ -47,37 +45,35 @@ func Dump(values ...interface{}) { // Also see Dump. func DumpWithType(values ...interface{}) { for _, value := range values { - if s := Export(value, ExportOption{ - WithoutType: false, - }); s != "" { - fmt.Println(s) - } + DumpWithOption(value, DumpOption{ + WithType: true, + }) } } -// Export returns variables `values` as a string with more manually readable. -func Export(value interface{}, option ExportOption) string { +// DumpWithOption returns variables `values` as a string with more manually readable. +func DumpWithOption(value interface{}, option DumpOption) { buffer := bytes.NewBuffer(nil) - ExportTo(buffer, value, ExportOption{ - WithoutType: option.WithoutType, + DumpTo(buffer, value, DumpOption{ + WithType: option.WithType, }) - return buffer.String() + fmt.Println(buffer.String()) } -// ExportTo writes variables `values` as a string in to `writer` with more manually readable -func ExportTo(writer io.Writer, value interface{}, option ExportOption) { +// DumpTo writes variables `values` as a string in to `writer` with more manually readable +func DumpTo(writer io.Writer, value interface{}, option DumpOption) { buffer := bytes.NewBuffer(nil) - doExport(value, "", buffer, doExportOption{ - WithoutType: option.WithoutType, + doDump(value, "", buffer, doDumpOption{ + WithType: option.WithType, }) _, _ = writer.Write(buffer.Bytes()) } -type doExportOption struct { - WithoutType bool +type doDumpOption struct { + WithType bool } -func doExport(value interface{}, indent string, buffer *bytes.Buffer, option doExportOption) { +func doDump(value interface{}, indent string, buffer *bytes.Buffer, option doDumpOption) { if value == nil { buffer.WriteString(``) return @@ -89,186 +85,284 @@ func doExport(value interface{}, indent string, buffer *bytes.Buffer, option doE newIndent = indent + dumpIndent ) reflectTypeName = strings.ReplaceAll(reflectTypeName, `[]uint8`, `[]byte`) - if option.WithoutType { + if !option.WithType { reflectTypeName = "" } for reflectKind == reflect.Ptr { reflectValue = reflectValue.Elem() reflectKind = reflectValue.Kind() } + var ( + exportInternalInput = doDumpInternalInput{ + Value: value, + Indent: indent, + NewIndent: newIndent, + Buffer: buffer, + Option: option, + ReflectValue: reflectValue, + ReflectTypeName: reflectTypeName, + } + ) switch reflectKind { case reflect.Slice, reflect.Array: - if b, ok := value.([]byte); ok { - if option.WithoutType { - buffer.WriteString(fmt.Sprintf(`"%s"`, gstr.AddSlashes(string(b)))) - } else { - buffer.WriteString(fmt.Sprintf( - `%s(%d) "%s"`, - reflectTypeName, - len(reflectValue.String()), - string(b), - )) - } - return - } - if reflectValue.Len() == 0 { - if option.WithoutType { - buffer.WriteString("[]") - } else { - buffer.WriteString(fmt.Sprintf("%s(0) []", reflectTypeName)) - } - return - } - if option.WithoutType { - buffer.WriteString("[\n") - } else { - buffer.WriteString(fmt.Sprintf("%s(%d) [\n", reflectTypeName, reflectValue.Len())) - } - for i := 0; i < reflectValue.Len(); i++ { - buffer.WriteString(newIndent) - doExport(reflectValue.Index(i).Interface(), newIndent, buffer, option) - buffer.WriteString(",\n") - } - buffer.WriteString(fmt.Sprintf("%s]", indent)) + doDumpSlice(exportInternalInput) case reflect.Map: - var ( - mapKeys = reflectValue.MapKeys() - ) - if len(mapKeys) == 0 { - if option.WithoutType { - buffer.WriteString("{}") - } else { - buffer.WriteString(fmt.Sprintf("%s(0) {}", reflectTypeName)) - } - return - } - - var ( - maxSpaceNum = 0 - tmpSpaceNum = 0 - mapKeyStr = "" - ) - for _, key := range mapKeys { - tmpSpaceNum = len(fmt.Sprintf(`%v`, key.Interface())) - if tmpSpaceNum > maxSpaceNum { - maxSpaceNum = tmpSpaceNum - } - } - if option.WithoutType { - buffer.WriteString("{\n") - } else { - buffer.WriteString(fmt.Sprintf("%s(%d) {\n", reflectTypeName, len(mapKeys))) - } - for _, mapKey := range mapKeys { - tmpSpaceNum = len(fmt.Sprintf(`%v`, mapKey.Interface())) - if mapKey.Kind() == reflect.String { - mapKeyStr = fmt.Sprintf(`"%v"`, mapKey.Interface()) - } else { - mapKeyStr = fmt.Sprintf(`%v`, mapKey.Interface()) - } - if option.WithoutType { - buffer.WriteString(fmt.Sprintf( - "%s%v:%s", - newIndent, - mapKeyStr, - strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1), - )) - } else { - buffer.WriteString(fmt.Sprintf( - "%s%s(%v):%s", - newIndent, - mapKey.Type().String(), - mapKeyStr, - strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1), - )) - } - doExport(reflectValue.MapIndex(mapKey).Interface(), newIndent, buffer, option) - buffer.WriteString(",\n") - } - buffer.WriteString(fmt.Sprintf("%s}", indent)) + doDumpMap(exportInternalInput) case reflect.Struct: - structFields, _ := structs.Fields(structs.FieldsInput{ - Pointer: value, - RecursiveOption: structs.RecursiveOptionEmbeddedNoTag, - }) - if len(structFields) == 0 { - var ( - structContentStr = "" - attributeCountStr = "0" - ) - if v, ok := value.(iString); ok { - structContentStr = v.String() - } else if v, ok := value.(iMarshalJSON); ok { - b, _ := v.MarshalJSON() - structContentStr = string(b) - } - if structContentStr == "" { - structContentStr = "{}" - } else { - structContentStr = fmt.Sprintf(`"%s"`, gstr.AddSlashes(structContentStr)) - attributeCountStr = fmt.Sprintf(`%d`, len(structContentStr)-2) - } - if option.WithoutType { - buffer.WriteString(structContentStr) - } else { - buffer.WriteString(fmt.Sprintf( - "%s(%s) %s", - reflectTypeName, - attributeCountStr, - structContentStr, - )) - } - return - } - - var ( - maxSpaceNum = 0 - tmpSpaceNum = 0 - ) - for _, field := range structFields { - tmpSpaceNum = len(field.Name()) - if tmpSpaceNum > maxSpaceNum { - maxSpaceNum = tmpSpaceNum - } - } - if option.WithoutType { - buffer.WriteString("{\n") - } else { - buffer.WriteString(fmt.Sprintf("%s(%d) {\n", reflectTypeName, len(structFields))) - } - for _, field := range structFields { - tmpSpaceNum = len(fmt.Sprintf(`%v`, field.Name())) - buffer.WriteString(fmt.Sprintf( - "%s%s:%s", - newIndent, - field.Name(), - strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1), - )) - doExport(field.Value.Interface(), newIndent, buffer, option) - buffer.WriteString(",\n") - } - buffer.WriteString(fmt.Sprintf("%s}", indent)) + doDumpStruct(exportInternalInput) case reflect.String: - s, _ := value.(string) - if option.WithoutType { - buffer.WriteString(fmt.Sprintf(`"%v"`, gstr.AddSlashes(s))) + doDumpString(exportInternalInput) + + case reflect.Bool: + if reflectValue.Bool() { + buffer.WriteString(`true`) } else { - buffer.WriteString(fmt.Sprintf( - `%s(%d) "%v"`, - reflectTypeName, - len(reflectValue.String()), - gstr.AddSlashes(s), - )) + buffer.WriteString(`false`) } + case + reflect.Int, + reflect.Int8, + reflect.Int16, + reflect.Int32, + reflect.Int64, + reflect.Uint, + reflect.Uint8, + reflect.Uint16, + reflect.Uint32, + reflect.Uint64, + reflect.Float32, + reflect.Float64, + reflect.Complex64, + reflect.Complex128: + doDumpNumber(exportInternalInput) + + case reflect.Chan: + buffer.WriteString(``) + + case reflect.Func: + buffer.WriteString(``) + default: - if option.WithoutType { - buffer.WriteString(fmt.Sprintf("%v", value)) - } else { - buffer.WriteString(fmt.Sprintf("%s(%v)", reflectTypeName, value)) - } + doDumpDefault(exportInternalInput) } } + +type doDumpInternalInput struct { + Value interface{} + Indent string + NewIndent string + Buffer *bytes.Buffer + Option doDumpOption + ReflectValue reflect.Value + ReflectTypeName string +} + +func doDumpSlice(in doDumpInternalInput) { + if b, ok := in.Value.([]byte); ok { + if !in.Option.WithType { + in.Buffer.WriteString(fmt.Sprintf(`"%s"`, addSlashesForString(string(b)))) + } else { + in.Buffer.WriteString(fmt.Sprintf( + `%s(%d) "%s"`, + in.ReflectTypeName, + len(string(b)), + string(b), + )) + } + return + } + if in.ReflectValue.Len() == 0 { + if !in.Option.WithType { + in.Buffer.WriteString("[]") + } else { + in.Buffer.WriteString(fmt.Sprintf("%s(0) []", in.ReflectTypeName)) + } + return + } + if !in.Option.WithType { + in.Buffer.WriteString("[\n") + } else { + in.Buffer.WriteString(fmt.Sprintf("%s(%d) [\n", in.ReflectTypeName, in.ReflectValue.Len())) + } + for i := 0; i < in.ReflectValue.Len(); i++ { + in.Buffer.WriteString(in.NewIndent) + doDump(in.ReflectValue.Index(i).Interface(), in.NewIndent, in.Buffer, in.Option) + in.Buffer.WriteString(",\n") + } + in.Buffer.WriteString(fmt.Sprintf("%s]", in.Indent)) +} + +func doDumpMap(in doDumpInternalInput) { + var ( + mapKeys = in.ReflectValue.MapKeys() + ) + if len(mapKeys) == 0 { + if !in.Option.WithType { + in.Buffer.WriteString("{}") + } else { + in.Buffer.WriteString(fmt.Sprintf("%s(0) {}", in.ReflectTypeName)) + } + return + } + var ( + maxSpaceNum = 0 + tmpSpaceNum = 0 + mapKeyStr = "" + ) + for _, key := range mapKeys { + tmpSpaceNum = len(fmt.Sprintf(`%v`, key.Interface())) + if tmpSpaceNum > maxSpaceNum { + maxSpaceNum = tmpSpaceNum + } + } + if !in.Option.WithType { + in.Buffer.WriteString("{\n") + } else { + in.Buffer.WriteString(fmt.Sprintf("%s(%d) {\n", in.ReflectTypeName, len(mapKeys))) + } + for _, mapKey := range mapKeys { + tmpSpaceNum = len(fmt.Sprintf(`%v`, mapKey.Interface())) + if mapKey.Kind() == reflect.String { + mapKeyStr = fmt.Sprintf(`"%v"`, mapKey.Interface()) + } else { + mapKeyStr = fmt.Sprintf(`%v`, mapKey.Interface()) + } + if !in.Option.WithType { + in.Buffer.WriteString(fmt.Sprintf( + "%s%v:%s", + in.NewIndent, + mapKeyStr, + strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1), + )) + } else { + in.Buffer.WriteString(fmt.Sprintf( + "%s%s(%v):%s", + in.NewIndent, + mapKey.Type().String(), + mapKeyStr, + strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1), + )) + } + doDump(in.ReflectValue.MapIndex(mapKey).Interface(), in.NewIndent, in.Buffer, in.Option) + in.Buffer.WriteString(",\n") + } + in.Buffer.WriteString(fmt.Sprintf("%s}", in.Indent)) +} + +func doDumpStruct(in doDumpInternalInput) { + structFields, _ := structs.Fields(structs.FieldsInput{ + Pointer: in.Value, + RecursiveOption: structs.RecursiveOptionEmbedded, + }) + if len(structFields) == 0 { + var ( + structContentStr = "" + attributeCountStr = "0" + ) + if v, ok := in.Value.(iString); ok { + structContentStr = v.String() + } else if v, ok := in.Value.(iMarshalJSON); ok { + b, _ := v.MarshalJSON() + structContentStr = string(b) + } + if structContentStr == "" { + structContentStr = "{}" + } else { + structContentStr = fmt.Sprintf(`"%s"`, addSlashesForString(structContentStr)) + attributeCountStr = fmt.Sprintf(`%d`, len(structContentStr)-2) + } + if !in.Option.WithType { + in.Buffer.WriteString(structContentStr) + } else { + in.Buffer.WriteString(fmt.Sprintf( + "%s(%s) %s", + in.ReflectTypeName, + attributeCountStr, + structContentStr, + )) + } + return + } + var ( + maxSpaceNum = 0 + tmpSpaceNum = 0 + ) + for _, field := range structFields { + tmpSpaceNum = len(field.Name()) + if tmpSpaceNum > maxSpaceNum { + maxSpaceNum = tmpSpaceNum + } + } + if !in.Option.WithType { + in.Buffer.WriteString("{\n") + } else { + in.Buffer.WriteString(fmt.Sprintf("%s(%d) {\n", in.ReflectTypeName, len(structFields))) + } + for _, field := range structFields { + tmpSpaceNum = len(fmt.Sprintf(`%v`, field.Name())) + in.Buffer.WriteString(fmt.Sprintf( + "%s%s:%s", + in.NewIndent, + field.Name(), + strings.Repeat(" ", maxSpaceNum-tmpSpaceNum+1), + )) + doDump(field.Value.Interface(), in.NewIndent, in.Buffer, in.Option) + in.Buffer.WriteString(",\n") + } + in.Buffer.WriteString(fmt.Sprintf("%s}", in.Indent)) +} + +func doDumpNumber(in doDumpInternalInput) { + if v, ok := in.Value.(iString); ok { + s := v.String() + if !in.Option.WithType { + in.Buffer.WriteString(fmt.Sprintf(`"%v"`, addSlashesForString(s))) + } else { + in.Buffer.WriteString(fmt.Sprintf( + `%s(%d) "%v"`, + in.ReflectTypeName, + len(s), + addSlashesForString(s), + )) + } + } else { + doDumpDefault(in) + } +} + +func doDumpString(in doDumpInternalInput) { + s := in.ReflectValue.String() + if !in.Option.WithType { + in.Buffer.WriteString(fmt.Sprintf(`"%v"`, addSlashesForString(s))) + } else { + in.Buffer.WriteString(fmt.Sprintf( + `%s(%d) "%v"`, + in.ReflectTypeName, + len(s), + addSlashesForString(s), + )) + } +} + +func doDumpDefault(in doDumpInternalInput) { + s := fmt.Sprintf("%v", in.Value) + s = gstr.Trim(s, `<>`) + if !in.Option.WithType { + in.Buffer.WriteString(s) + } else { + in.Buffer.WriteString(fmt.Sprintf("%s(%s)", in.ReflectTypeName, s)) + } +} + +func addSlashesForString(s string) string { + return gstr.ReplaceByMap(s, map[string]string{ + `"`: `\"`, + "\r": `\r`, + "\t": `\t`, + "\n": `\n`, + }) +}