mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
improve gstr/gjson/gconv
This commit is contained in:
@ -21,7 +21,7 @@ addons:
|
||||
- local
|
||||
|
||||
before_install:
|
||||
- pwd
|
||||
- mysql -e 'CREATE DATABASE IF NOT EXISTS test;'
|
||||
|
||||
install:
|
||||
- cat /etc/hosts
|
||||
|
||||
@ -10,6 +10,8 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/g/util/gutil"
|
||||
|
||||
"github.com/gogf/gf/g/container/gvar"
|
||||
"github.com/gogf/gf/g/os/gtime"
|
||||
"github.com/gogf/gf/g/util/gconv"
|
||||
@ -22,6 +24,13 @@ func (j *Json) Value() interface{} {
|
||||
return *(j.p)
|
||||
}
|
||||
|
||||
// IsNil checks whether the value pointed by <j> is nil.
|
||||
func (j *Json) IsNil() bool {
|
||||
j.mu.RLock()
|
||||
defer j.mu.RUnlock()
|
||||
return j.p == nil || *(j.p) == nil
|
||||
}
|
||||
|
||||
// Get returns value by specified <pattern>.
|
||||
// It returns all values of current Json object, if <pattern> is empty or not specified.
|
||||
// It returns nil if no value found by <pattern>.
|
||||
@ -67,11 +76,7 @@ func (j *Json) GetMap(pattern string, def ...interface{}) map[string]interface{}
|
||||
// GetJson gets the value by specified <pattern>,
|
||||
// and converts it to a un-concurrent-safe Json object.
|
||||
func (j *Json) GetJson(pattern string, def ...interface{}) *Json {
|
||||
result := j.Get(pattern, def...)
|
||||
if result != nil {
|
||||
return New(result, true)
|
||||
}
|
||||
return nil
|
||||
return New(j.Get(pattern, def...), true)
|
||||
}
|
||||
|
||||
// GetJsons gets the value by specified <pattern>,
|
||||
@ -257,6 +262,7 @@ func (j *Json) Append(pattern string, value interface{}) error {
|
||||
// GetToVar gets the value by specified <pattern>,
|
||||
// and converts it to specified golang variable <v>.
|
||||
// The <pointer> should be a pointer type.
|
||||
// Deprecated.
|
||||
func (j *Json) GetToVar(pattern string, pointer interface{}) error {
|
||||
r := j.Get(pattern)
|
||||
if r != nil {
|
||||
@ -342,13 +348,15 @@ func (j *Json) ToStructsDeep(pointer interface{}) error {
|
||||
}
|
||||
|
||||
// Dump prints current Json object with more manually readable.
|
||||
func (j *Json) Dump() error {
|
||||
func (j *Json) Dump() {
|
||||
j.mu.RLock()
|
||||
defer j.mu.RUnlock()
|
||||
if b, err := j.ToJsonIndent(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
fmt.Println(string(b))
|
||||
}
|
||||
return nil
|
||||
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)
|
||||
}
|
||||
|
||||
@ -7,10 +7,11 @@
|
||||
package gjson_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gogf/gf/g"
|
||||
"github.com/gogf/gf/g/encoding/gjson"
|
||||
"github.com/gogf/gf/g/test/gtest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_New(t *testing.T) {
|
||||
@ -361,7 +362,7 @@ func Test_Convert2(t *testing.T) {
|
||||
err := j.ToStruct(&name)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(name.Name, "gf")
|
||||
err = j.Dump()
|
||||
j.Dump()
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
j = gjson.New(`{"person":{"name":"gf"}}`)
|
||||
@ -370,7 +371,7 @@ func Test_Convert2(t *testing.T) {
|
||||
gtest.Assert(name.Name, "gf")
|
||||
|
||||
j = gjson.New(`{"name":"gf""}`)
|
||||
err = j.Dump()
|
||||
j.Dump()
|
||||
gtest.Assert(err, nil)
|
||||
|
||||
j = gjson.New(`[1,2,3]`)
|
||||
@ -459,3 +460,10 @@ func Test_Basic(t *testing.T) {
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func Test_IsNil(t *testing.T) {
|
||||
gtest.Case(t, func() {
|
||||
j := gjson.New(nil)
|
||||
gtest.Assert(j.IsNil(), true)
|
||||
})
|
||||
}
|
||||
|
||||
@ -7,9 +7,10 @@
|
||||
package gparser
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/g/container/gvar"
|
||||
"github.com/gogf/gf/g/os/gtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Val returns the value.
|
||||
@ -141,6 +142,7 @@ func (p *Parser) GetGTime(pattern string, format ...string) *gtime.Time {
|
||||
// GetToVar gets the value by specified <pattern>,
|
||||
// and converts it to specified golang variable <v>.
|
||||
// The <v> should be a pointer type.
|
||||
// Deprecated.
|
||||
func (p *Parser) GetToVar(pattern string, pointer interface{}) error {
|
||||
return p.json.GetToVar(pattern, pointer)
|
||||
}
|
||||
@ -216,7 +218,23 @@ func (p *Parser) ToStruct(pointer interface{}) error {
|
||||
return p.json.ToStruct(pointer)
|
||||
}
|
||||
|
||||
// Dump prints current Json object with more manually readable.
|
||||
func (p *Parser) Dump() error {
|
||||
return p.json.Dump()
|
||||
func (p *Parser) ToStructDeep(pointer interface{}) error {
|
||||
return p.json.ToStructDeep(pointer)
|
||||
}
|
||||
|
||||
func (p *Parser) ToStructs(pointer interface{}) error {
|
||||
return p.json.ToStructs(pointer)
|
||||
}
|
||||
|
||||
func (p *Parser) ToStructsDeep(pointer interface{}) error {
|
||||
return p.json.ToStructsDeep(pointer)
|
||||
}
|
||||
|
||||
// Dump prints current Json object with more manually readable.
|
||||
func (p *Parser) Dump() {
|
||||
p.json.Dump()
|
||||
}
|
||||
|
||||
func (p *Parser) Export() string {
|
||||
return p.json.Export()
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
package gins_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -60,7 +59,7 @@ test = "v=2"
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
gtest.Case(t, func() {
|
||||
fmt.Println("gins Test_Database", gins.Config().Get("test"))
|
||||
//fmt.Println("gins Test_Database", gins.Config().Get("test"))
|
||||
|
||||
dbDefault := gins.Database()
|
||||
dbTest := gins.Database("test")
|
||||
|
||||
60
g/internal/strutils/strutils.go
Normal file
60
g/internal/strutils/strutils.go
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2019 gf Author(https://github.com/gogf/gf). 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 strutils provides some string functions for internal usage.
|
||||
package strutils
|
||||
|
||||
import "strings"
|
||||
|
||||
// IsLetterUpper tests whether the given byte b is in upper case.
|
||||
func IsLetterUpper(b byte) bool {
|
||||
if b >= byte('A') && b <= byte('Z') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsLetterLower tests whether the given byte b is in lower case.
|
||||
func IsLetterLower(b byte) bool {
|
||||
if b >= byte('a') && b <= byte('z') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsNumeric tests whether the given string s is numeric.
|
||||
func IsNumeric(s string) bool {
|
||||
length := len(s)
|
||||
if length == 0 {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] < byte('0') || s[i] > byte('9') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// UcFirst returns a copy of the string s with the first letter mapped to its upper case.
|
||||
func UcFirst(s string) string {
|
||||
if len(s) == 0 {
|
||||
return s
|
||||
}
|
||||
if IsLetterLower(s[0]) {
|
||||
return string(s[0]-32) + s[1:]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// ReplaceByMap returns a copy of <origin>,
|
||||
// which is replaced by a map in unordered way, case-sensitively.
|
||||
func ReplaceByMap(origin string, replaces map[string]string) string {
|
||||
for k, v := range replaces {
|
||||
origin = strings.Replace(origin, k, v, -1)
|
||||
}
|
||||
return origin
|
||||
}
|
||||
@ -8,10 +8,10 @@ package gtime
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/gogf/gf/g/text/gregex"
|
||||
"github.com/gogf/gf/g/text/gstr"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/g/text/gregex"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -110,9 +110,15 @@ func (t *Time) Format(format string) string {
|
||||
// 有几个转换的符号需要特殊处理
|
||||
switch runes[i] {
|
||||
case 'j':
|
||||
buffer.WriteString(gstr.ReplaceByArray(result, []string{"=j=0", "", "=j=", ""}))
|
||||
for _, s := range []string{"=j=0", "=j="} {
|
||||
result = strings.Replace(result, s, "", -1)
|
||||
}
|
||||
buffer.WriteString(result)
|
||||
case 'G':
|
||||
buffer.WriteString(gstr.ReplaceByArray(result, []string{"=G=0", "", "=G=", ""}))
|
||||
for _, s := range []string{"=G=0", "=G="} {
|
||||
result = strings.Replace(result, s, "", -1)
|
||||
}
|
||||
buffer.WriteString(result)
|
||||
case 'u':
|
||||
buffer.WriteString(strings.Replace(result, "=u=.", "", -1))
|
||||
case 'w':
|
||||
|
||||
@ -10,12 +10,17 @@ package gstr
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/g/util/grand"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/gogf/gf/g/internal/strutils"
|
||||
|
||||
"github.com/gogf/gf/g/util/gconv"
|
||||
|
||||
"github.com/gogf/gf/g/util/grand"
|
||||
)
|
||||
|
||||
// Replace returns a copy of the string <origin>
|
||||
@ -93,10 +98,7 @@ func ReplaceIByArray(origin string, array []string) string {
|
||||
// ReplaceByMap returns a copy of <origin>,
|
||||
// which is replaced by a map in unordered way, case-sensitively.
|
||||
func ReplaceByMap(origin string, replaces map[string]string) string {
|
||||
for k, v := range replaces {
|
||||
origin = Replace(origin, k, v)
|
||||
}
|
||||
return origin
|
||||
return strutils.ReplaceByMap(origin, replaces)
|
||||
}
|
||||
|
||||
// ReplaceIByMap returns a copy of <origin>,
|
||||
@ -120,13 +122,7 @@ func ToUpper(s string) string {
|
||||
|
||||
// UcFirst returns a copy of the string s with the first letter mapped to its upper case.
|
||||
func UcFirst(s string) string {
|
||||
if len(s) == 0 {
|
||||
return s
|
||||
}
|
||||
if IsLetterLower(s[0]) {
|
||||
return string(s[0]-32) + s[1:]
|
||||
}
|
||||
return s
|
||||
return strutils.UcFirst(s)
|
||||
}
|
||||
|
||||
// LcFirst returns a copy of the string s with the first letter mapped to its lower case.
|
||||
@ -147,40 +143,25 @@ func UcWords(str string) string {
|
||||
|
||||
// IsLetterLower tests whether the given byte b is in lower case.
|
||||
func IsLetterLower(b byte) bool {
|
||||
if b >= byte('a') && b <= byte('z') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return strutils.IsLetterLower(b)
|
||||
}
|
||||
|
||||
// IsLetterUpper tests whether the given byte b is in upper case.
|
||||
func IsLetterUpper(b byte) bool {
|
||||
if b >= byte('A') && b <= byte('Z') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return strutils.IsLetterUpper(b)
|
||||
}
|
||||
|
||||
// IsNumeric tests whether the given string s is numeric.
|
||||
func IsNumeric(s string) bool {
|
||||
length := len(s)
|
||||
if length == 0 {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] < byte('0') || s[i] > byte('9') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
return strutils.IsNumeric(s)
|
||||
}
|
||||
|
||||
// SubStr returns a portion of string <str> specified by the <start> and <length> parameters.
|
||||
func SubStr(str string, start int, length ...int) (substr string) {
|
||||
// 将字符串的转换成[]rune
|
||||
// Converting to []rune to support unicode.
|
||||
rs := []rune(str)
|
||||
lth := len(rs)
|
||||
// 简单的越界判断
|
||||
// Simple border checks.
|
||||
if start < 0 {
|
||||
start = 0
|
||||
}
|
||||
@ -197,7 +178,6 @@ func SubStr(str string, start int, length ...int) (substr string) {
|
||||
if end > lth {
|
||||
end = lth
|
||||
}
|
||||
// 返回子串
|
||||
return string(rs[start:end])
|
||||
}
|
||||
|
||||
@ -468,6 +448,14 @@ func Join(array []string, sep string) string {
|
||||
return strings.Join(array, sep)
|
||||
}
|
||||
|
||||
// JoinAny concatenates the elements of a to create a single string. The separator string
|
||||
// sep is placed between elements in the resulting string.
|
||||
//
|
||||
// The parameter <array> can be any type of slice.
|
||||
func JoinAny(array interface{}, sep string) string {
|
||||
return strings.Join(gconv.Strings(array), sep)
|
||||
}
|
||||
|
||||
// Explode splits string <str> by a string <delimiter>, to an array.
|
||||
// See http://php.net/manual/en/function.explode.php.
|
||||
func Explode(delimiter, str string) []string {
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/g/internal/empty"
|
||||
"github.com/gogf/gf/g/text/gstr"
|
||||
"github.com/gogf/gf/g/internal/strutils"
|
||||
)
|
||||
|
||||
// Map converts any variable <value> to map[string]interface{}.
|
||||
@ -116,7 +116,7 @@ func Map(value interface{}, tags ...string) map[string]interface{} {
|
||||
for i := 0; i < rv.NumField(); i++ {
|
||||
// Only convert the public attributes.
|
||||
fieldName := rt.Field(i).Name
|
||||
if !gstr.IsLetterUpper(fieldName[0]) {
|
||||
if !strutils.IsLetterUpper(fieldName[0]) {
|
||||
continue
|
||||
}
|
||||
name = ""
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/gogf/gf/g/text/gstr"
|
||||
"github.com/gogf/gf/g/internal/strutils"
|
||||
)
|
||||
|
||||
// SliceInt is alias of Ints.
|
||||
@ -357,7 +357,7 @@ func Interfaces(i interface{}) []interface{} {
|
||||
rt := rv.Type()
|
||||
for i := 0; i < rv.NumField(); i++ {
|
||||
// Only public attributes.
|
||||
if !gstr.IsLetterUpper(rt.Field(i).Name[0]) {
|
||||
if !strutils.IsLetterUpper(rt.Field(i).Name[0]) {
|
||||
continue
|
||||
}
|
||||
array = append(array, rv.Field(i).Interface())
|
||||
@ -447,6 +447,10 @@ func doStructs(params interface{}, pointer interface{}, deep bool, mapping ...ma
|
||||
}
|
||||
switch kind {
|
||||
case reflect.Slice, reflect.Array:
|
||||
// If <params> is an empty slice, no conversion.
|
||||
if rv.Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
array := reflect.MakeSlice(pointerRt.Elem(), rv.Len(), rv.Len())
|
||||
itemType := array.Index(0).Type()
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
|
||||
@ -13,7 +13,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gogf/gf/g/internal/structs"
|
||||
"github.com/gogf/gf/g/text/gstr"
|
||||
"github.com/gogf/gf/g/internal/strutils"
|
||||
)
|
||||
|
||||
// Struct maps the params key-value pairs to the corresponding struct object's properties.
|
||||
@ -92,7 +92,7 @@ func Struct(params interface{}, pointer interface{}, mapping ...map[string]strin
|
||||
elemType := elem.Type()
|
||||
for i := 0; i < elem.NumField(); i++ {
|
||||
// Only do converting to public attributes.
|
||||
if !gstr.IsLetterUpper(elemType.Field(i).Name[0]) {
|
||||
if !strutils.IsLetterUpper(elemType.Field(i).Name[0]) {
|
||||
continue
|
||||
}
|
||||
attrMap[elemType.Field(i).Name] = struct{}{}
|
||||
@ -100,8 +100,8 @@ func Struct(params interface{}, pointer interface{}, mapping ...map[string]strin
|
||||
for mapK, mapV := range paramsMap {
|
||||
name := ""
|
||||
for _, checkName := range []string{
|
||||
gstr.UcFirst(mapK),
|
||||
gstr.ReplaceByMap(mapK, map[string]string{
|
||||
strutils.UcFirst(mapK),
|
||||
strutils.ReplaceByMap(mapK, map[string]string{
|
||||
"_": "",
|
||||
"-": "",
|
||||
" ": "",
|
||||
@ -118,7 +118,7 @@ func Struct(params interface{}, pointer interface{}, mapping ...map[string]strin
|
||||
name = value
|
||||
break
|
||||
}
|
||||
if strings.EqualFold(checkName, gstr.Replace(value, "_", "")) {
|
||||
if strings.EqualFold(checkName, strings.Replace(value, "_", "", -1)) {
|
||||
name = value
|
||||
break
|
||||
}
|
||||
@ -159,7 +159,7 @@ func StructDeep(params interface{}, pointer interface{}, mapping ...map[string]s
|
||||
rt := rv.Type()
|
||||
for i := 0; i < rv.NumField(); i++ {
|
||||
// Only do converting to public attributes.
|
||||
if !gstr.IsLetterUpper(rt.Field(i).Name[0]) {
|
||||
if !strutils.IsLetterUpper(rt.Field(i).Name[0]) {
|
||||
continue
|
||||
}
|
||||
trv := rv.Field(i)
|
||||
|
||||
@ -7,9 +7,10 @@
|
||||
package gconv
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/g/os/gtime"
|
||||
"github.com/gogf/gf/g/text/gstr"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/g/internal/strutils"
|
||||
"github.com/gogf/gf/g/os/gtime"
|
||||
)
|
||||
|
||||
// Time converts <i> to time.Time.
|
||||
@ -22,7 +23,7 @@ func Time(i interface{}, format ...string) time.Time {
|
||||
// If <i> is numeric, then it converts <i> as nanoseconds.
|
||||
func Duration(i interface{}) time.Duration {
|
||||
s := String(i)
|
||||
if !gstr.IsNumeric(s) {
|
||||
if !strutils.IsNumeric(s) {
|
||||
d, _ := time.ParseDuration(s)
|
||||
return d
|
||||
}
|
||||
@ -43,7 +44,7 @@ func GTime(i interface{}, format ...string) *gtime.Time {
|
||||
t, _ := gtime.StrToTimeFormat(s, format[0])
|
||||
return t
|
||||
}
|
||||
if gstr.IsNumeric(s) {
|
||||
if strutils.IsNumeric(s) {
|
||||
return gtime.NewFromTimeStamp(Int64(s))
|
||||
} else {
|
||||
t, _ := gtime.StrToTime(s)
|
||||
|
||||
Reference in New Issue
Block a user