mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
124 lines
3.6 KiB
Go
124 lines
3.6 KiB
Go
/*
|
|
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
|
Copyright (C) ITsysCOM GmbH
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
*/
|
|
|
|
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"strconv"
|
|
)
|
|
|
|
func CastFieldIfToString(fld interface{}) (string, bool) {
|
|
var strVal string
|
|
var converted bool
|
|
switch fld.(type) {
|
|
case string:
|
|
strVal = fld.(string)
|
|
converted = true
|
|
case int:
|
|
strVal = strconv.Itoa(fld.(int))
|
|
converted = true
|
|
case int64:
|
|
strVal = strconv.FormatInt(fld.(int64), 10)
|
|
converted = true
|
|
case bool:
|
|
strVal = strconv.FormatBool(fld.(bool))
|
|
case float64:
|
|
strVal = strconv.FormatFloat(fld.(float64), 'f', -1, 64)
|
|
converted = true
|
|
case []uint8:
|
|
var byteVal []byte
|
|
if byteVal, converted = fld.([]byte); converted {
|
|
strVal = string(byteVal)
|
|
}
|
|
default: // Maybe we are lucky and the value converts to string
|
|
strVal, converted = fld.(string)
|
|
}
|
|
return strVal, converted
|
|
}
|
|
|
|
// ReflectFieldAsString parses intf and attepting to return the field as string or error otherwise
|
|
// Supports "ExtraFields" where additional fields are dynamically inserted in map with field name: extraFieldsLabel
|
|
func ReflectFieldAsString(intf interface{}, fldName, extraFieldsLabel string) (string, error) {
|
|
v := reflect.ValueOf(intf)
|
|
if v.Kind() == reflect.Ptr {
|
|
v = v.Elem()
|
|
}
|
|
var field reflect.Value
|
|
switch v.Kind() {
|
|
case reflect.Struct:
|
|
field = v.FieldByName(fldName)
|
|
case reflect.Map:
|
|
field = v.MapIndex(reflect.ValueOf(fldName))
|
|
if !field.IsValid() { // Not looking in extra fields anymore
|
|
return "", ErrNotFound
|
|
}
|
|
default:
|
|
return "", fmt.Errorf("Unsupported field kind: %v", v.Kind())
|
|
}
|
|
|
|
if !field.IsValid() {
|
|
if extraFieldsLabel == "" {
|
|
return "", ErrNotFound
|
|
}
|
|
mpVal := v.FieldByName(extraFieldsLabel)
|
|
if !mpVal.IsValid() || mpVal.Kind() != reflect.Map {
|
|
return "", ErrNotFound
|
|
}
|
|
field = mpVal.MapIndex(reflect.ValueOf(fldName))
|
|
if !field.IsValid() {
|
|
return "", ErrNotFound
|
|
}
|
|
}
|
|
switch field.Kind() {
|
|
case reflect.String:
|
|
return field.String(), nil
|
|
case reflect.Int, reflect.Int64:
|
|
return strconv.FormatInt(field.Int(), 10), nil
|
|
case reflect.Float64:
|
|
return strconv.FormatFloat(field.Float(), 'f', -1, 64), nil
|
|
case reflect.Interface:
|
|
strVal, converted := CastFieldIfToString(field.Interface())
|
|
if !converted {
|
|
return "", fmt.Errorf("Cannot convert to string field type: %s", field.Kind().String())
|
|
} else {
|
|
return strVal, nil
|
|
}
|
|
default:
|
|
return "", fmt.Errorf("Cannot convert to string field type: %s", field.Kind().String())
|
|
}
|
|
}
|
|
|
|
// AsMapStringIface converts an item (mostly struct) as map[string]interface{}
|
|
func AsMapStringIface(item interface{}) (map[string]interface{}, error) {
|
|
out := make(map[string]interface{})
|
|
v := reflect.ValueOf(item)
|
|
if v.Kind() == reflect.Ptr {
|
|
v = v.Elem()
|
|
}
|
|
if v.Kind() != reflect.Struct { // Only structs for now
|
|
return nil, fmt.Errorf("AsMapStringIface only accepts structs; got %T", v)
|
|
}
|
|
typ := v.Type()
|
|
for i := 0; i < v.NumField(); i++ {
|
|
out[typ.Field(i).Name] = v.Field(i).Interface()
|
|
}
|
|
return out, nil
|
|
}
|