123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167 |
- // 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"
- "reflect"
- "strconv"
- "sync"
- "github.com/mitchellh/mapstructure"
- )
- 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 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 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 bytea", input)
- }
- func ToStringMap(input interface{}) (map[string]interface{}, error) {
- 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, bytea
- 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
- }
- case "bytea":
- r, e := ToByteA(value, CONVERT_ALL)
- if e != nil {
- return e, false
- } else {
- return r, 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
- }
- }
|