mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
303 lines
6.3 KiB
Go
303 lines
6.3 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 (
|
||
"reflect"
|
||
"strconv"
|
||
"strings"
|
||
)
|
||
|
||
// Converts map[string]string into map[string]interface{}
|
||
func ConvertMapValStrIf(inMap map[string]string) map[string]interface{} {
|
||
outMap := make(map[string]interface{})
|
||
for field, val := range inMap {
|
||
outMap[field] = val
|
||
}
|
||
return outMap
|
||
}
|
||
|
||
// Mirrors key/val
|
||
func MirrorMap(mapIn map[string]string) map[string]string {
|
||
mapOut := make(map[string]string, len(mapIn))
|
||
for key, val := range mapIn {
|
||
mapOut[val] = key
|
||
}
|
||
return mapOut
|
||
}
|
||
|
||
// Returns mising keys in a map
|
||
func MissingMapKeys(inMap map[string]string, requiredKeys []string) []string {
|
||
missingKeys := []string{}
|
||
for _, reqKey := range requiredKeys {
|
||
if val, hasKey := inMap[reqKey]; !hasKey || val == "" {
|
||
missingKeys = append(missingKeys, reqKey)
|
||
}
|
||
}
|
||
return missingKeys
|
||
}
|
||
|
||
// Return map keys
|
||
func MapKeys(m map[string]string) []string {
|
||
n := make([]string, len(m))
|
||
i := 0
|
||
for k := range m {
|
||
n[i] = k
|
||
i++
|
||
}
|
||
return n
|
||
}
|
||
|
||
type StringMap map[string]bool
|
||
|
||
func NewStringMap(s ...string) StringMap {
|
||
result := make(StringMap)
|
||
for _, v := range s {
|
||
v = strings.TrimSpace(v)
|
||
if v != "" {
|
||
if strings.HasPrefix(v, "!") {
|
||
result[v[1:]] = false
|
||
} else {
|
||
result[v] = true
|
||
}
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
func ParseStringMap(s string) StringMap {
|
||
if s == ZERO {
|
||
return make(StringMap)
|
||
}
|
||
return StringMapFromSlice(strings.Split(s, INFIELD_SEP))
|
||
}
|
||
|
||
func (sm StringMap) Equal(om StringMap) bool {
|
||
if sm == nil && om != nil {
|
||
return false
|
||
}
|
||
if len(sm) != len(om) {
|
||
return false
|
||
}
|
||
for key := range sm {
|
||
if !om[key] {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
func (sm StringMap) Includes(om StringMap) bool {
|
||
if len(sm) < len(om) {
|
||
return false
|
||
}
|
||
for key := range om {
|
||
if !sm[key] {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
func (sm StringMap) Slice() []string {
|
||
result := make([]string, len(sm))
|
||
i := 0
|
||
for k := range sm {
|
||
result[i] = k
|
||
i++
|
||
}
|
||
return result
|
||
}
|
||
|
||
func (sm StringMap) IsEmpty() bool {
|
||
return sm == nil ||
|
||
len(sm) == 0 ||
|
||
sm[ANY] == true
|
||
}
|
||
|
||
func StringMapFromSlice(s []string) StringMap {
|
||
result := make(StringMap, len(s))
|
||
for _, v := range s {
|
||
v = strings.TrimSpace(v)
|
||
if v != "" {
|
||
if strings.HasPrefix(v, "!") {
|
||
result[v[1:]] = false
|
||
} else {
|
||
result[v] = true
|
||
}
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
func (sm StringMap) Copy(o StringMap) {
|
||
for k, v := range o {
|
||
sm[k] = v
|
||
}
|
||
}
|
||
|
||
func (sm StringMap) Clone() StringMap {
|
||
result := make(StringMap, len(sm))
|
||
result.Copy(sm)
|
||
return result
|
||
}
|
||
|
||
func (sm StringMap) String() string {
|
||
return strings.Join(sm.Slice(), INFIELD_SEP)
|
||
}
|
||
|
||
func (sm StringMap) GetOne() string {
|
||
for key := range sm {
|
||
return key
|
||
}
|
||
return ""
|
||
}
|
||
|
||
func (sm StringMap) Join(mps ...StringMap) {
|
||
for _, mp := range mps {
|
||
for k, v := range mp {
|
||
sm[k] = v
|
||
}
|
||
}
|
||
}
|
||
|
||
func (sm StringMap) HasKey(key string) (has bool) {
|
||
_, has = sm[key]
|
||
return
|
||
}
|
||
|
||
func (sm StringMap) GetSlice() (result []string) {
|
||
result = make([]string, len(sm))
|
||
i := 0
|
||
for k := range sm {
|
||
result[i] = k
|
||
i += 1
|
||
}
|
||
return
|
||
}
|
||
|
||
/*
|
||
func NoDots(m map[string]struct{}) map[string]struct{} {
|
||
return MapKeysReplace(m, ".", ".")
|
||
}
|
||
|
||
func YesDots(m map[string]struct{}) map[string]struct{} {
|
||
return MapKeysReplace(m, ".", ".")
|
||
}
|
||
|
||
func MapKeysReplace(m map[string]struct{}, old, new string) map[string]struct{} {
|
||
for key, val := range m {
|
||
delete(m, key)
|
||
key = strings.Replace(key, old, new, -1)
|
||
m[key] = val
|
||
}
|
||
return m
|
||
}
|
||
*/
|
||
// Used to merge multiple maps (eg: output of struct having ExtraFields)
|
||
func MergeMapsStringIface(mps ...map[string]interface{}) (outMp map[string]interface{}) {
|
||
outMp = make(map[string]interface{})
|
||
for i, mp := range mps {
|
||
if i == 0 {
|
||
outMp = mp
|
||
continue
|
||
}
|
||
for k, v := range mp {
|
||
outMp[k] = v
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// FieldMultiplyFactor defines multiply factors for different field values
|
||
// original defined for CDRE component
|
||
type FieldMultiplyFactor map[string]float64
|
||
|
||
func (fmp FieldMultiplyFactor) Clone() (cln FieldMultiplyFactor) {
|
||
cln = make(FieldMultiplyFactor, len(fmp))
|
||
for k, v := range fmp {
|
||
cln[k] = v
|
||
}
|
||
return
|
||
}
|
||
|
||
func MapStringToInt64(in map[string]string) (out map[string]int64, err error) {
|
||
mapout := make(map[string]int64, len(in))
|
||
for key, val := range in {
|
||
x, err := strconv.Atoi(val)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
mapout[key] = int64(x)
|
||
}
|
||
return mapout, nil
|
||
}
|
||
|
||
func FlagsWithParamsFromSlice(s []string) (FlagsWithParams, error) {
|
||
result := make(FlagsWithParams, len(s))
|
||
for _, v := range s {
|
||
subsystemWithIDs := strings.Split(v, InInFieldSep)
|
||
result[subsystemWithIDs[0]] = []string{}
|
||
if len(subsystemWithIDs) == 2 {
|
||
result[subsystemWithIDs[0]] = strings.Split(subsystemWithIDs[1], INFIELD_SEP)
|
||
} else if len(subsystemWithIDs) > 2 {
|
||
return nil, ErrUnsupportedFormat
|
||
}
|
||
}
|
||
return result, nil
|
||
}
|
||
|
||
type FlagsWithParams map[string]interface{}
|
||
|
||
func (fWp FlagsWithParams) HasKey(key string) (has bool) {
|
||
_, has = fWp[key]
|
||
return
|
||
}
|
||
|
||
func (fWp FlagsWithParams) ParamsSlice(subs string) (ps []string) {
|
||
if psIfc, has := fWp[subs]; has {
|
||
ps, _ = psIfc.([]string)
|
||
}
|
||
return ps
|
||
}
|
||
|
||
//func to convert from FlagsWithParams back to []string
|
||
func (fWp FlagsWithParams) SliceFlags() (sls []string) {
|
||
for key, _ := range fWp {
|
||
if prmSlice := fWp.ParamsSlice(key); !reflect.DeepEqual(prmSlice, []string{}) {
|
||
sls = append(sls, ConcatenatedKey(key, strings.Join(prmSlice, INFIELD_SEP)))
|
||
} else {
|
||
sls = append(sls, key)
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// GetBool returns the flag as boolean
|
||
func (fWp FlagsWithParams) GetBool(key string) (b bool) {
|
||
var v interface{}
|
||
if _, b = fWp[key]; !b {
|
||
return // not present means false
|
||
}
|
||
if v.(string) != "" && v.(string) != "true" {
|
||
return // not empty nor true means false again
|
||
}
|
||
return true
|
||
}
|