1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159 |
- // Copyright 2021-2023 EMQ Technologies Co., Ltd.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package cast
- import (
- "encoding/base64"
- "fmt"
- "github.com/mitchellh/mapstructure"
- "reflect"
- "strconv"
- "sync"
- )
- type Strictness int8
- const (
- STRICT Strictness = iota
- CONVERT_SAMEKIND
- CONVERT_ALL
- )
- /*********** Type Cast Utilities *****/
- // TODO datetime type
- func ToStringAlways(input interface{}) string {
- if input == nil {
- return ""
- }
- return fmt.Sprintf("%v", input)
- }
- func ToString(input interface{}, sn Strictness) (string, error) {
- switch s := input.(type) {
- case string:
- return s, nil
- case []byte:
- return string(s), nil
- default:
- if sn == CONVERT_ALL {
- switch s := input.(type) {
- case string:
- return s, nil
- case bool:
- return strconv.FormatBool(s), nil
- case float64:
- return strconv.FormatFloat(s, 'f', -1, 64), nil
- case float32:
- return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
- case int:
- return strconv.Itoa(s), nil
- case int64:
- return strconv.FormatInt(s, 10), nil
- case int32:
- return strconv.Itoa(int(s)), nil
- case int16:
- return strconv.FormatInt(int64(s), 10), nil
- case int8:
- return strconv.FormatInt(int64(s), 10), nil
- case uint:
- return strconv.FormatUint(uint64(s), 10), nil
- case uint64:
- return strconv.FormatUint(s, 10), nil
- case uint32:
- return strconv.FormatUint(uint64(s), 10), nil
- case uint16:
- return strconv.FormatUint(uint64(s), 10), nil
- case uint8:
- return strconv.FormatUint(uint64(s), 10), nil
- case nil:
- return "", nil
- case fmt.Stringer:
- return s.String(), nil
- case error:
- return s.Error(), nil
- }
- }
- }
- return "", fmt.Errorf("cannot convert %[1]T(%[1]v) to string", input)
- }
- func ToInt(input interface{}, sn Strictness) (int, error) {
- switch s := input.(type) {
- case int:
- return s, nil
- case int64:
- return int(s), nil
- case int32:
- return int(s), nil
- case int16:
- return int(s), nil
- case int8:
- return int(s), nil
- case uint:
- return int(s), nil
- case uint64:
- return int(s), nil
- case uint32:
- return int(s), nil
- case uint16:
- return int(s), nil
- case uint8:
- return int(s), nil
- case float64:
- if sn != STRICT || isIntegral64(s) {
- return int(s), nil
- }
- case float32:
- if sn != STRICT || isIntegral32(s) {
- return int(s), nil
- }
- case string:
- if sn == CONVERT_ALL {
- v, err := strconv.ParseInt(s, 0, 0)
- if err == nil {
- return int(v), nil
- }
- }
- case bool:
- if sn == CONVERT_ALL {
- if s {
- return 1, nil
- }
- return 0, nil
- }
- case nil:
- if sn == CONVERT_ALL {
- return 0, nil
- }
- }
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to int", input)
- }
- func ToInt8(input interface{}, sn Strictness) (int8, error) {
- switch s := input.(type) {
- case int:
- return int8(s), nil
- case int64:
- return int8(s), nil
- case int32:
- return int8(s), nil
- case int16:
- return int8(s), nil
- case int8:
- return s, nil
- case uint:
- return int8(s), nil
- case uint64:
- return int8(s), nil
- case uint32:
- return int8(s), nil
- case uint16:
- return int8(s), nil
- case uint8:
- return int8(s), nil
- case float64:
- if sn != STRICT || isIntegral64(s) {
- return int8(s), nil
- }
- case float32:
- if sn != STRICT || isIntegral32(s) {
- return int8(s), nil
- }
- case string:
- if sn == CONVERT_ALL {
- v, err := strconv.ParseInt(s, 0, 0)
- if err == nil {
- return int8(v), nil
- }
- }
- case bool:
- if sn == CONVERT_ALL {
- if s {
- return 1, nil
- }
- return 0, nil
- }
- case nil:
- if sn == CONVERT_ALL {
- return 0, nil
- }
- }
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to int", input)
- }
- func ToInt16(input interface{}, sn Strictness) (int16, error) {
- switch s := input.(type) {
- case int:
- return int16(s), nil
- case int64:
- return int16(s), nil
- case int32:
- return int16(s), nil
- case int16:
- return int16(s), nil
- case int8:
- return int16(s), nil
- case uint:
- return int16(s), nil
- case uint64:
- return int16(s), nil
- case uint32:
- return int16(s), nil
- case uint16:
- return int16(s), nil
- case uint8:
- return int16(s), nil
- case float64:
- if sn != STRICT || isIntegral64(s) {
- return int16(s), nil
- }
- case float32:
- if sn != STRICT || isIntegral32(s) {
- return int16(s), nil
- }
- case string:
- if sn == CONVERT_ALL {
- v, err := strconv.ParseInt(s, 0, 0)
- if err == nil {
- return int16(v), nil
- }
- }
- case bool:
- if sn == CONVERT_ALL {
- if s {
- return 1, nil
- }
- return 0, nil
- }
- case nil:
- if sn == CONVERT_ALL {
- return 0, nil
- }
- }
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to int", input)
- }
- func ToInt32(input interface{}, sn Strictness) (int32, error) {
- switch s := input.(type) {
- case int:
- return int32(s), nil
- case int64:
- return int32(s), nil
- case int32:
- return s, nil
- case int16:
- return int32(s), nil
- case int8:
- return int32(s), nil
- case uint:
- return int32(s), nil
- case uint64:
- return int32(s), nil
- case uint32:
- return int32(s), nil
- case uint16:
- return int32(s), nil
- case uint8:
- return int32(s), nil
- case float64:
- if sn != STRICT || isIntegral64(s) {
- return int32(s), nil
- }
- case float32:
- if sn != STRICT || isIntegral32(s) {
- return int32(s), nil
- }
- case string:
- if sn == CONVERT_ALL {
- v, err := strconv.ParseInt(s, 0, 0)
- if err == nil {
- return int32(v), nil
- }
- }
- case bool:
- if sn == CONVERT_ALL {
- if s {
- return 1, nil
- }
- return 0, nil
- }
- case nil:
- if sn == CONVERT_ALL {
- return 0, nil
- }
- }
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to int", input)
- }
- func ToInt64(input interface{}, sn Strictness) (int64, error) {
- switch s := input.(type) {
- case int:
- return int64(s), nil
- case int64:
- return s, nil
- case int32:
- return int64(s), nil
- case int16:
- return int64(s), nil
- case int8:
- return int64(s), nil
- case uint:
- return int64(s), nil
- case uint64:
- return int64(s), nil
- case uint32:
- return int64(s), nil
- case uint16:
- return int64(s), nil
- case uint8:
- return int64(s), nil
- case float64:
- if sn != STRICT || isIntegral64(s) {
- return int64(s), nil
- }
- case float32:
- if sn != STRICT || isIntegral32(s) {
- return int64(s), nil
- }
- case string:
- if sn == CONVERT_ALL {
- v, err := strconv.ParseInt(s, 0, 0)
- if err == nil {
- return int64(v), nil
- }
- }
- case bool:
- if sn == CONVERT_ALL {
- if s {
- return 1, nil
- }
- return 0, nil
- }
- case nil:
- if sn == CONVERT_ALL {
- return 0, nil
- }
- }
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to int64", input)
- }
- func ToFloat64(input interface{}, sn Strictness) (float64, error) {
- switch s := input.(type) {
- case float64:
- return s, nil
- case float32:
- return float64(s), nil
- case int:
- if sn != STRICT {
- return float64(s), nil
- }
- case int64:
- if sn != STRICT {
- return float64(s), nil
- }
- case int32:
- if sn != STRICT {
- return float64(s), nil
- }
- case int16:
- if sn != STRICT {
- return float64(s), nil
- }
- case int8:
- if sn != STRICT {
- return float64(s), nil
- }
- case uint:
- if sn != STRICT {
- return float64(s), nil
- }
- case uint64:
- if sn != STRICT {
- return float64(s), nil
- }
- case uint32:
- if sn != STRICT {
- return float64(s), nil
- }
- case uint16:
- if sn != STRICT {
- return float64(s), nil
- }
- case uint8:
- if sn != STRICT {
- return float64(s), nil
- }
- case string:
- if sn == CONVERT_ALL {
- v, err := strconv.ParseFloat(s, 64)
- if err == nil {
- return v, nil
- }
- }
- case bool:
- if sn == CONVERT_ALL {
- if s {
- return 1, nil
- }
- return 0, nil
- }
- }
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to float64", input)
- }
- func ToFloat32(input interface{}, sn Strictness) (float32, error) {
- switch s := input.(type) {
- case float64:
- return float32(s), nil
- case float32:
- return s, nil
- case int:
- if sn != STRICT {
- return float32(s), nil
- }
- case int64:
- if sn != STRICT {
- return float32(s), nil
- }
- case int32:
- if sn != STRICT {
- return float32(s), nil
- }
- case int16:
- if sn != STRICT {
- return float32(s), nil
- }
- case int8:
- if sn != STRICT {
- return float32(s), nil
- }
- case uint:
- if sn != STRICT {
- return float32(s), nil
- }
- case uint64:
- if sn != STRICT {
- return float32(s), nil
- }
- case uint32:
- if sn != STRICT {
- return float32(s), nil
- }
- case uint16:
- if sn != STRICT {
- return float32(s), nil
- }
- case uint8:
- if sn != STRICT {
- return float32(s), nil
- }
- case string:
- if sn == CONVERT_ALL {
- v, err := strconv.ParseFloat(s, 32)
- if err == nil {
- return float32(v), nil
- }
- }
- case bool:
- if sn == CONVERT_ALL {
- if s {
- return 1, nil
- }
- return 0, nil
- }
- }
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to float64", input)
- }
- func ToUint64(i interface{}, sn Strictness) (uint64, error) {
- switch s := i.(type) {
- case string:
- if sn == CONVERT_ALL {
- v, err := strconv.ParseUint(s, 0, 64)
- if err == nil {
- return v, nil
- }
- }
- case int:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint64(s), nil
- case int64:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint64(s), nil
- case int32:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint64(s), nil
- case int16:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint64(s), nil
- case int8:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint64(s), nil
- case uint:
- return uint64(s), nil
- case uint64:
- return s, nil
- case uint32:
- return uint64(s), nil
- case uint16:
- return uint64(s), nil
- case uint8:
- return uint64(s), nil
- case float32:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- if sn != STRICT || isIntegral32(s) {
- return uint64(s), nil
- }
- case float64:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- if sn != STRICT || isIntegral64(s) {
- return uint64(s), nil
- }
- case bool:
- if sn == CONVERT_ALL {
- if s {
- return 1, nil
- }
- return 0, nil
- }
- case nil:
- if sn == CONVERT_ALL {
- return 0, nil
- }
- }
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint", i)
- }
- func ToUint8(i interface{}, sn Strictness) (uint8, error) {
- switch s := i.(type) {
- case string:
- if sn == CONVERT_ALL {
- v, err := strconv.ParseUint(s, 0, 64)
- if err == nil {
- return uint8(v), nil
- }
- }
- case int:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint8(s), nil
- case int64:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint8(s), nil
- case int32:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint8(s), nil
- case int16:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint8(s), nil
- case int8:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint8(s), nil
- case uint:
- return uint8(s), nil
- case uint64:
- return uint8(s), nil
- case uint32:
- return uint8(s), nil
- case uint16:
- return uint8(s), nil
- case uint8:
- return s, nil
- case float32:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- if sn != STRICT || isIntegral32(s) {
- return uint8(s), nil
- }
- case float64:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- if sn != STRICT || isIntegral64(s) {
- return uint8(s), nil
- }
- case bool:
- if sn == CONVERT_ALL {
- if s {
- return 1, nil
- }
- return 0, nil
- }
- case nil:
- if sn == CONVERT_ALL {
- return 0, nil
- }
- }
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint", i)
- }
- func ToUint16(i interface{}, sn Strictness) (uint16, error) {
- switch s := i.(type) {
- case string:
- if sn == CONVERT_ALL {
- v, err := strconv.ParseUint(s, 0, 64)
- if err == nil {
- return uint16(v), nil
- }
- }
- case int:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint16(s), nil
- case int64:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint16(s), nil
- case int32:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint16(s), nil
- case int16:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint16(s), nil
- case int8:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint16(s), nil
- case uint:
- return uint16(s), nil
- case uint64:
- return uint16(s), nil
- case uint32:
- return uint16(s), nil
- case uint16:
- return s, nil
- case uint8:
- return uint16(s), nil
- case float32:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- if sn != STRICT || isIntegral32(s) {
- return uint16(s), nil
- }
- case float64:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- if sn != STRICT || isIntegral64(s) {
- return uint16(s), nil
- }
- case bool:
- if sn == CONVERT_ALL {
- if s {
- return 1, nil
- }
- return 0, nil
- }
- case nil:
- if sn == CONVERT_ALL {
- return 0, nil
- }
- }
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint", i)
- }
- func ToUint32(i interface{}, sn Strictness) (uint32, error) {
- switch s := i.(type) {
- case string:
- if sn == CONVERT_ALL {
- v, err := strconv.ParseUint(s, 0, 64)
- if err == nil {
- return uint32(v), nil
- }
- }
- case int:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint32(s), nil
- case int64:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint32(s), nil
- case int32:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint32(s), nil
- case int16:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint32(s), nil
- case int8:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- return uint32(s), nil
- case uint:
- return uint32(s), nil
- case uint64:
- return uint32(s), nil
- case uint32:
- return s, nil
- case uint16:
- return uint32(s), nil
- case uint8:
- return uint32(s), nil
- case float32:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- if sn != STRICT || isIntegral32(s) {
- return uint32(s), nil
- }
- case float64:
- if s < 0 {
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint, negative not allowed", i)
- }
- if sn != STRICT || isIntegral64(s) {
- return uint32(s), nil
- }
- case bool:
- if sn == CONVERT_ALL {
- if s {
- return 1, nil
- }
- return 0, nil
- }
- case nil:
- if sn == CONVERT_ALL {
- return 0, nil
- }
- }
- return 0, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint", i)
- }
- func ToBool(input interface{}, sn Strictness) (bool, error) {
- switch b := input.(type) {
- case bool:
- return b, nil
- case nil:
- if sn == CONVERT_ALL {
- return false, nil
- }
- case int:
- if sn == CONVERT_ALL {
- if b != 0 {
- return true, nil
- }
- return false, nil
- }
- case string:
- if sn == CONVERT_ALL {
- return strconv.ParseBool(b)
- }
- case float64:
- if sn == CONVERT_ALL {
- if b != 0 {
- return true, nil
- }
- return false, nil
- }
- }
- return false, fmt.Errorf("cannot convert %[1]T(%[1]v) to bool", input)
- }
- func ToBytes(input interface{}, sn Strictness) ([]byte, error) {
- switch b := input.(type) {
- case []byte:
- return b, nil
- case string:
- if sn != STRICT {
- return []byte(b), nil
- }
- }
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to bytes", input)
- }
- // ToByteA converts to eKuiper internal byte array
- func ToByteA(input interface{}, _ Strictness) ([]byte, error) {
- switch b := input.(type) {
- case []byte:
- return b, nil
- case string:
- r, err := base64.StdEncoding.DecodeString(b)
- if err != nil {
- return nil, fmt.Errorf("illegal string %s, must be base64 encoded string", b)
- }
- return r, nil
- }
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to bytes", input)
- }
- func ToStringMap(input interface{}) (map[string]interface{}, error) {
- var m = map[string]interface{}{}
- switch v := input.(type) {
- case map[interface{}]interface{}:
- for k, val := range v {
- m[ToStringAlways(k)] = val
- }
- return m, nil
- case map[string]interface{}:
- return v, nil
- //case string:
- // err := jsonStringToObject(v, &m)
- // return m, err
- default:
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to map", input)
- }
- }
- func ToTypedSlice(input interface{}, conv func(interface{}, Strictness) (interface{}, error), eleType string, sn Strictness) (interface{}, error) {
- s := reflect.ValueOf(input)
- if s.Kind() != reflect.Slice {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to %s slice)", input, eleType)
- }
- if s.Len() == 0 {
- result := reflect.MakeSlice(reflect.TypeOf([]interface{}{}), s.Len(), s.Len())
- return result.Interface(), nil
- }
- ele, err := conv(s.Index(0).Interface(), sn)
- et := reflect.TypeOf(ele)
- if err != nil || et == nil {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to %s slice for the %d element: %v", input, eleType, 0, err)
- }
- result := reflect.MakeSlice(reflect.SliceOf(et), s.Len(), s.Len())
- result.Index(0).Set(reflect.ValueOf(ele))
- for i := 1; i < s.Len(); i++ {
- ele, err := conv(s.Index(i).Interface(), sn)
- if err != nil {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to int slice for the %d element: %v", input, i, err)
- }
- result.Index(i).Set(reflect.ValueOf(ele))
- }
- return result.Interface(), nil
- }
- func ToInt64Slice(input interface{}, sn Strictness) ([]int64, error) {
- s := reflect.ValueOf(input)
- if s.Kind() != reflect.Slice {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to int slice)", input)
- }
- var result []int64
- for i := 0; i < s.Len(); i++ {
- ele, err := ToInt64(s.Index(i).Interface(), sn)
- if err != nil {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to int slice for the %d element: %v", input, i, err)
- }
- result = append(result, ele)
- }
- return result, nil
- }
- func ToUint64Slice(input interface{}, sn Strictness) ([]uint64, error) {
- s := reflect.ValueOf(input)
- if s.Kind() != reflect.Slice {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint slice)", input)
- }
- var result []uint64
- for i := 0; i < s.Len(); i++ {
- ele, err := ToUint64(s.Index(i).Interface(), sn)
- if err != nil {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to uint slice for the %d element: %v", input, i, err)
- }
- result = append(result, ele)
- }
- return result, nil
- }
- func ToFloat64Slice(input interface{}, sn Strictness) ([]float64, error) {
- s := reflect.ValueOf(input)
- if s.Kind() != reflect.Slice {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to float slice)", input)
- }
- var result []float64
- for i := 0; i < s.Len(); i++ {
- ele, err := ToFloat64(s.Index(i).Interface(), sn)
- if err != nil {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to float slice for the %d element: %v", input, i, err)
- }
- result = append(result, ele)
- }
- return result, nil
- }
- func ToFloat32Slice(input interface{}, sn Strictness) ([]float32, error) {
- s := reflect.ValueOf(input)
- if s.Kind() != reflect.Slice {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to float slice)", input)
- }
- var result []float32
- for i := 0; i < s.Len(); i++ {
- ele, err := ToFloat32(s.Index(i).Interface(), sn)
- if err != nil {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to float slice for the %d element: %v", input, i, err)
- }
- result = append(result, ele)
- }
- return result, nil
- }
- func ToBoolSlice(input interface{}, sn Strictness) ([]bool, error) {
- s := reflect.ValueOf(input)
- if s.Kind() != reflect.Slice {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to bool slice)", input)
- }
- var result []bool
- for i := 0; i < s.Len(); i++ {
- ele, err := ToBool(s.Index(i).Interface(), sn)
- if err != nil {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to bool slice for the %d element: %v", input, i, err)
- }
- result = append(result, ele)
- }
- return result, nil
- }
- func ToStringSlice(input interface{}, sn Strictness) ([]string, error) {
- s := reflect.ValueOf(input)
- if s.Kind() != reflect.Slice {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to string slice)", input)
- }
- var result []string
- for i := 0; i < s.Len(); i++ {
- ele, err := ToString(s.Index(i).Interface(), sn)
- if err != nil {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to string slice for the %d element: %v", input, i, err)
- }
- result = append(result, ele)
- }
- return result, nil
- }
- func ToBytesSlice(input interface{}, sn Strictness) ([][]byte, error) {
- s := reflect.ValueOf(input)
- if s.Kind() != reflect.Slice {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to string slice)", input)
- }
- var result [][]byte
- for i := 0; i < s.Len(); i++ {
- ele, err := ToBytes(s.Index(i).Interface(), sn)
- if err != nil {
- return nil, fmt.Errorf("cannot convert %[1]T(%[1]v) to bytes slice for the %d element: %v", input, i, err)
- }
- result = append(result, ele)
- }
- return result, nil
- }
- //MapToStruct
- /*
- * Convert a map into a struct. The output parameter must be a pointer to a struct
- * The struct can have the json metadata
- */
- func MapToStruct(input, output interface{}) error {
- config := &mapstructure.DecoderConfig{
- TagName: "json",
- Result: output,
- }
- decoder, err := mapstructure.NewDecoder(config)
- if err != nil {
- return err
- }
- return decoder.Decode(input)
- }
- // MapToStructStrict
- /*
- * Convert a map into a struct. The output parameter must be a pointer to a struct
- * If the input have key/value pair output do not defined, will report error
- */
- func MapToStructStrict(input, output interface{}) error {
- config := &mapstructure.DecoderConfig{
- ErrorUnused: true,
- TagName: "json",
- Result: output,
- }
- decoder, err := mapstructure.NewDecoder(config)
- if err != nil {
- return err
- }
- return decoder.Decode(input)
- }
- func ConvertMap(s map[interface{}]interface{}) map[string]interface{} {
- r := make(map[string]interface{})
- for k, v := range s {
- switch t := v.(type) {
- case map[interface{}]interface{}:
- v = ConvertMap(t)
- case []interface{}:
- v = ConvertArray(t)
- }
- r[fmt.Sprintf("%v", k)] = v
- }
- return r
- }
- func ConvertArray(s []interface{}) []interface{} {
- r := make([]interface{}, len(s))
- for i, e := range s {
- switch t := e.(type) {
- case map[interface{}]interface{}:
- e = ConvertMap(t)
- case []interface{}:
- e = ConvertArray(t)
- }
- r[i] = e
- }
- return r
- }
- func SyncMapToMap(sm *sync.Map) map[string]interface{} {
- m := make(map[string]interface{})
- sm.Range(func(k interface{}, v interface{}) bool {
- m[fmt.Sprintf("%v", k)] = v
- return true
- })
- return m
- }
- func MapToSyncMap(m map[string]interface{}) *sync.Map {
- sm := new(sync.Map)
- for k, v := range m {
- sm.Store(k, v)
- }
- return sm
- }
- func isIntegral64(val float64) bool {
- return val == float64(int(val))
- }
- func isIntegral32(val float32) bool {
- return val == float32(int(val))
- }
- func ConvertToInterfaceArr(orig map[string]interface{}) map[string]interface{} {
- result := make(map[string]interface{})
- for k, v := range orig {
- vt := reflect.TypeOf(v)
- if vt == nil {
- result[k] = nil
- continue
- }
- switch vt.Kind() {
- case reflect.Slice:
- result[k] = ConvertSlice(v)
- case reflect.Map:
- result[k] = ConvertToInterfaceArr(v.(map[string]interface{}))
- default:
- result[k] = v
- }
- }
- return result
- }
- func ConvertSlice(v interface{}) []interface{} {
- value := reflect.ValueOf(v)
- tempArr := make([]interface{}, value.Len())
- for i := 0; i < value.Len(); i++ {
- item := value.Index(i)
- if item.Kind() == reflect.Map {
- tempArr[i] = ConvertToInterfaceArr(item.Interface().(map[string]interface{}))
- } else if item.Kind() == reflect.Slice {
- tempArr[i] = ConvertSlice(item.Interface())
- } else {
- tempArr[i] = item.Interface()
- }
- }
- return tempArr
- }
- // ToType cast value into newType type
- // newType support bigint, float, string, boolean, datetime
- func ToType(value interface{}, newType interface{}) (interface{}, bool) {
- if v, ok := newType.(string); ok {
- switch v {
- case "bigint":
- r, e := ToInt(value, CONVERT_ALL)
- if e != nil {
- return fmt.Errorf("not supported type conversion, got error %v", e), false
- } else {
- return r, true
- }
- case "float":
- r, e := ToFloat64(value, CONVERT_ALL)
- if e != nil {
- return fmt.Errorf("not supported type conversion, got error %v", e), false
- } else {
- return r, true
- }
- case "string":
- r, e := ToString(value, CONVERT_ALL)
- if e != nil {
- return fmt.Errorf("not supported type conversion, got error %v", e), false
- } else {
- return r, true
- }
- case "boolean":
- r, e := ToBool(value, CONVERT_ALL)
- if e != nil {
- return fmt.Errorf("not supported type conversion, got error %v", e), false
- } else {
- return r, true
- }
- case "datetime":
- dt, err := InterfaceToTime(value, "")
- if err != nil {
- return err, false
- } else {
- return dt, true
- }
- default:
- return fmt.Errorf("unknow type, only support bigint, float, string, boolean and datetime"), false
- }
- } else {
- return fmt.Errorf("expect string type for type parameter"), false
- }
- }
|