From 9194c7e8722a692b2f95d394dbdc9eef8f5048e1 Mon Sep 17 00:00:00 2001 From: seekwe Date: Thu, 14 Nov 2024 12:27:38 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9A=99=EF=B8=8F=20refactor:=20Refactor=20env?= =?UTF-8?q?=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zarray/slice.go | 45 ------------------------------- zarray/slice_test.go | 19 ------------- zarray/string.go | 51 +++++++++++++++++++++++++++++++++++ zarray/string_test.go | 30 +++++++++++++++++++++ zstring/s_109.go | 14 ++++++++++ zstring/s_118.go | 12 ++------- zutil/env.go | 62 +++++++++++++++++++++++++++++++++++++++---- zutil/env_test.go | 5 +++- 8 files changed, 158 insertions(+), 80 deletions(-) create mode 100644 zarray/string.go create mode 100644 zarray/string_test.go create mode 100644 zstring/s_109.go diff --git a/zarray/slice.go b/zarray/slice.go index 8f5d9d4..c2ade29 100644 --- a/zarray/slice.go +++ b/zarray/slice.go @@ -5,11 +5,9 @@ package zarray import ( "math/rand" - "strings" "github.com/sohaha/zlsgo/zstring" "github.com/sohaha/zlsgo/zsync" - "github.com/sohaha/zlsgo/ztype" "github.com/sohaha/zlsgo/zutil" ) @@ -197,46 +195,3 @@ func Shift[T comparable](list *[]T) (v T) { *list = (*list)[1:] return } - -// Slice converts a string to a slice. -// If n is not empty, the string will be split into n parts. -func Slice[T comparable](s string, n ...int) []T { - if s == "" { - return []T{} - } - - var ss []string - if len(n) > 0 { - ss = strings.SplitN(s, ",", n[0]) - } else { - ss = strings.Split(s, ",") - } - res := make([]T, len(ss)) - for i := range ss { - ztype.To(zstring.TrimSpace(ss[i]), &res[i]) - } - - return res -} - -// Join slice to string. -// If n is not empty, the string will be split into n parts. -func Join[T comparable](s []T, sep string) string { - if len(s) == 0 { - return "" - } - - b := zstring.Buffer(len(s)) - for i := 0; i < len(s); i++ { - v := ztype.ToString(s[i]) - if v == "" { - continue - } - b.WriteString(v) - if i < len(s)-1 { - b.WriteString(sep) - } - } - - return b.String() -} diff --git a/zarray/slice_test.go b/zarray/slice_test.go index 9666369..3cc095f 100644 --- a/zarray/slice_test.go +++ b/zarray/slice_test.go @@ -130,22 +130,3 @@ func TestFind(t *testing.T) { tt.EqualTrue(!ok) tt.Equal("", v["name"]) } - -func TestSlice(t *testing.T) { - tt := zlsgo.NewTest(t) - tt.Equal([]string{"a", "b", "c"}, zarray.Slice[string]("a,b,c")) - tt.Equal([]int{1, 2, 3}, zarray.Slice[int]("1,2,3")) - tt.Equal([]float64{1.1, 2.2, 3.3}, zarray.Slice[float64]("1.1,2.2,3.3")) - tt.Equal([]string{"1.1", "2.2,3.3"}, zarray.Slice[string]("1.1,2.2,3.3", 2)) - tt.Equal([]int{}, zarray.Slice[int]("")) -} - -func TestJoin(t *testing.T) { - tt := zlsgo.NewTest(t) - tt.Equal("a,b,c", zarray.Join([]string{"a", "b", "c"}, ",")) - tt.Equal("1,2,3", zarray.Join([]int{1, 2, 3}, ",")) - tt.Equal("1.1,2.2,3.3", zarray.Join([]float64{1.1, 2.2, 3.3}, ",")) - tt.Equal("1.1,2.2,3.3", zarray.Join([]string{"1.1", "2.2", "3.3"}, ",")) - tt.Equal("1.1,3.3", zarray.Join([]string{"1.1", "", "3.3"}, ",")) - tt.Equal("", zarray.Join([]string{}, ",")) -} diff --git a/zarray/string.go b/zarray/string.go new file mode 100644 index 0000000..8dea0e3 --- /dev/null +++ b/zarray/string.go @@ -0,0 +1,51 @@ +package zarray + +import ( + "strings" + + "github.com/sohaha/zlsgo/zstring" + "github.com/sohaha/zlsgo/ztype" +) + +// Slice converts a string to a slice. +// If n is not empty, the string will be split into n parts. +func Slice[T comparable](s string, n ...int) []T { + if s == "" { + return []T{} + } + + var ss []string + if len(n) > 0 { + ss = strings.SplitN(s, ",", n[0]) + } else { + ss = strings.Split(s, ",") + } + res := make([]T, len(ss)) + for i := range ss { + ztype.To(zstring.TrimSpace(ss[i]), &res[i]) + } + + return res +} + +// Join slice to string. +// If n is not empty, the string will be split into n parts. +func Join[T comparable](s []T, sep string) string { + if len(s) == 0 { + return "" + } + + b := zstring.Buffer(len(s)) + for i := 0; i < len(s); i++ { + v := ztype.ToString(s[i]) + if v == "" { + continue + } + b.WriteString(v) + if i < len(s)-1 { + b.WriteString(sep) + } + } + + return b.String() +} diff --git a/zarray/string_test.go b/zarray/string_test.go new file mode 100644 index 0000000..4867366 --- /dev/null +++ b/zarray/string_test.go @@ -0,0 +1,30 @@ +//go:build go1.18 +// +build go1.18 + +package zarray_test + +import ( + "testing" + + "github.com/sohaha/zlsgo" + "github.com/sohaha/zlsgo/zarray" +) + +func TestSlice(t *testing.T) { + tt := zlsgo.NewTest(t) + tt.Equal([]string{"a", "b", "c"}, zarray.Slice[string]("a,b,c")) + tt.Equal([]int{1, 2, 3}, zarray.Slice[int]("1,2,3")) + tt.Equal([]float64{1.1, 2.2, 3.3}, zarray.Slice[float64]("1.1,2.2,3.3")) + tt.Equal([]string{"1.1", "2.2,3.3"}, zarray.Slice[string]("1.1,2.2,3.3", 2)) + tt.Equal([]int{}, zarray.Slice[int]("")) +} + +func TestJoin(t *testing.T) { + tt := zlsgo.NewTest(t) + tt.Equal("a,b,c", zarray.Join([]string{"a", "b", "c"}, ",")) + tt.Equal("1,2,3", zarray.Join([]int{1, 2, 3}, ",")) + tt.Equal("1.1,2.2,3.3", zarray.Join([]float64{1.1, 2.2, 3.3}, ",")) + tt.Equal("1.1,2.2,3.3", zarray.Join([]string{"1.1", "2.2", "3.3"}, ",")) + tt.Equal("1.1,3.3", zarray.Join([]string{"1.1", "", "3.3"}, ",")) + tt.Equal("", zarray.Join([]string{}, ",")) +} diff --git a/zstring/s_109.go b/zstring/s_109.go new file mode 100644 index 0000000..906cb50 --- /dev/null +++ b/zstring/s_109.go @@ -0,0 +1,14 @@ +//go:build !go1.10 +// +build !go1.10 + +package zstring + +import ( + "bytes" +) + +// Buffer Buffer +func Buffer(size ...int) *bytes.Buffer { + b := bytes.NewBufferString("") + return &b +} diff --git a/zstring/s_118.go b/zstring/s_118.go index ec05126..6fcead8 100644 --- a/zstring/s_118.go +++ b/zstring/s_118.go @@ -1,12 +1,4 @@ -//go:build !go1.10 -// +build !go1.10 +//go:build go1.18 +// +build go1.18 package zstring - -import "bytes" - -// Buffer Buffer -func Buffer(size ...int) *bytes.Buffer { - b := bytes.NewBufferString("") - return &b -} diff --git a/zutil/env.go b/zutil/env.go index c353fa4..b20550d 100644 --- a/zutil/env.go +++ b/zutil/env.go @@ -1,9 +1,13 @@ package zutil import ( + "bytes" + "errors" + "fmt" "os" "runtime" "strings" + "unicode" "github.com/sohaha/zlsgo/zfile" "github.com/sohaha/zlsgo/zstring" @@ -37,10 +41,12 @@ func Getenv(name string, def ...string) string { return val } +// GOROOT return go root path func GOROOT() string { return zfile.RealPath(runtime.GOROOT()) } +// Loadenv load env from file func Loadenv(filenames ...string) (err error) { filenames = filenamesOrDefault(filenames) @@ -60,15 +66,61 @@ func filenamesOrDefault(filenames []string) []string { return filenames } +func locateKeyName(src []byte) (key string, cutset []byte, err error) { + src = bytes.TrimLeftFunc(src, isSpace) + offset := 0 +loop: + for i, char := range src { + rchar := rune(char) + if isSpace(rchar) { + continue + } + + switch char { + case '=', ':': + key = string(src[0:i]) + offset = i + 1 + break loop + case '_': + default: + if unicode.IsLetter(rchar) || unicode.IsNumber(rchar) || rchar == '.' { + continue + } + + return "", nil, fmt.Errorf(`unexpected character %q in variable name near %q`, char, src) + } + } + + if len(src) == 0 { + return "", nil, errors.New("zero length string") + } + + key = strings.TrimRightFunc(key, unicode.IsSpace) + cutset = bytes.TrimLeftFunc(src[offset:], isSpace) + return key, cutset, nil +} + +func isSpace(r rune) bool { + switch r { + case '\t', '\v', '\f', '\r', ' ', 0x85, 0xA0: + return true + } + return false +} + func loadFile(filename string) error { return zfile.ReadLineFile(filename, func(line int, data []byte) error { - e := strings.Split(zstring.Bytes2String(data), "=") - var value string - if len(e) > 1 { - value = e[1] + key, value, err := locateKeyName(data) + if err != nil { + return nil + } + + value = bytes.TrimSpace(value) + if len(value) > 0 && (value[0] == '"' || value[0] == '\'' && value[0] == value[len(value)-1]) { + value = value[1 : len(value)-1] } - _ = os.Setenv(zstring.TrimSpace(e[0]), strings.TrimSpace(value)) + _ = os.Setenv(key, zstring.Bytes2String(value)) return nil }) } diff --git a/zutil/env_test.go b/zutil/env_test.go index 8825913..31f2d84 100644 --- a/zutil/env_test.go +++ b/zutil/env_test.go @@ -34,11 +34,14 @@ func TestGOROOT(t *testing.T) { func TestLoadenv(t *testing.T) { tt := zlsgo.NewTest(t) - _ = zfile.WriteFile(".env", []byte("myos=linux\n name=zls ")) + _ = zfile.WriteFile(".env", []byte("myos=linux\n name=zls \n\n time=\"2024-11-14 23:59:01\" \n#comment='comment'\n description=\"hello world\"")) defer zfile.Rmdir(".env") tt.NoError(zutil.Loadenv()) tt.Equal("linux", zutil.Getenv("myos")) tt.Equal("zls", zutil.Getenv("name")) + tt.Equal("2024-11-14 23:59:01", zutil.Getenv("time")) + tt.Equal("", zutil.Getenv("comment")) + tt.Equal("hello world", zutil.Getenv("description")) }