2024-03-26 08:45:18 +01:00
|
|
|
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
|
|
|
// All rights reserved.
|
|
|
|
|
2024-03-26 07:00:53 +01:00
|
|
|
// utils.go
|
|
|
|
package expr
|
|
|
|
|
2024-05-01 05:45:10 +02:00
|
|
|
import (
|
2024-05-01 07:07:36 +02:00
|
|
|
"fmt"
|
2024-05-01 05:45:10 +02:00
|
|
|
"reflect"
|
|
|
|
)
|
2024-03-28 06:26:20 +01:00
|
|
|
|
2024-05-08 07:53:01 +02:00
|
|
|
func IsString(v any) (ok bool) {
|
2024-03-26 07:00:53 +01:00
|
|
|
_, ok = v.(string)
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
2024-05-08 07:53:01 +02:00
|
|
|
func IsInteger(v any) (ok bool) {
|
2024-03-26 07:00:53 +01:00
|
|
|
_, ok = v.(int64)
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
2024-05-08 07:53:01 +02:00
|
|
|
func IsFloat(v any) (ok bool) {
|
2024-03-26 07:00:53 +01:00
|
|
|
_, ok = v.(float64)
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
2024-05-10 04:48:13 +02:00
|
|
|
func IsBool(v any) (ok bool) {
|
|
|
|
_, ok = v.(bool)
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
2024-05-08 07:53:01 +02:00
|
|
|
func IsList(v any) (ok bool) {
|
2024-05-01 21:44:55 +02:00
|
|
|
_, ok = v.(*ListType)
|
2024-03-30 06:50:49 +01:00
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
2024-05-08 07:53:01 +02:00
|
|
|
func IsDict(v any) (ok bool) {
|
2024-04-21 14:24:56 +02:00
|
|
|
_, ok = v.(map[any]any)
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
2024-05-10 04:48:13 +02:00
|
|
|
func IsFract(v any) (ok bool) {
|
|
|
|
_, ok = v.(*fraction)
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
2024-05-08 07:53:01 +02:00
|
|
|
func IsNumber(v any) (ok bool) {
|
|
|
|
return IsFloat(v) || IsInteger(v)
|
2024-03-26 07:00:53 +01:00
|
|
|
}
|
|
|
|
|
2024-05-06 17:31:12 +02:00
|
|
|
func isNumOrFract(v any) (ok bool) {
|
2024-05-08 07:53:01 +02:00
|
|
|
return IsFloat(v) || IsInteger(v) || isFraction(v)
|
2024-05-06 17:31:12 +02:00
|
|
|
}
|
|
|
|
|
2024-03-26 07:00:53 +01:00
|
|
|
func isNumberString(v any) (ok bool) {
|
2024-05-08 07:53:01 +02:00
|
|
|
return IsString(v) || IsNumber(v)
|
2024-03-26 07:00:53 +01:00
|
|
|
}
|
|
|
|
|
2024-04-28 06:43:57 +02:00
|
|
|
func isFunctor(v any) (ok bool) {
|
|
|
|
_, ok = v.(Functor)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-05-01 05:45:10 +02:00
|
|
|
func isIterator(v any) (ok bool) {
|
|
|
|
_, ok = v.(Iterator)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-03-26 07:00:53 +01:00
|
|
|
func numAsFloat(v any) (f float64) {
|
|
|
|
var ok bool
|
|
|
|
if f, ok = v.(float64); !ok {
|
2024-05-01 21:44:55 +02:00
|
|
|
if fract, ok := v.(*fraction); ok {
|
|
|
|
f = fract.toFloat()
|
|
|
|
} else {
|
|
|
|
i, _ := v.(int64)
|
|
|
|
f = float64(i)
|
|
|
|
}
|
2024-03-26 07:00:53 +01:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func toBool(v any) (b bool, ok bool) {
|
|
|
|
ok = true
|
|
|
|
switch x := v.(type) {
|
|
|
|
case string:
|
|
|
|
b = len(x) > 0
|
|
|
|
case float64:
|
|
|
|
b = x != 0.0
|
|
|
|
case int64:
|
|
|
|
b = x != 0
|
|
|
|
case bool:
|
|
|
|
b = x
|
|
|
|
default:
|
|
|
|
ok = false
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2024-03-28 06:26:20 +01:00
|
|
|
|
|
|
|
func isFunc(v any) bool {
|
|
|
|
return reflect.TypeOf(v).Kind() == reflect.Func
|
|
|
|
}
|
|
|
|
|
|
|
|
func anyInteger(v any) (i int64, ok bool) {
|
|
|
|
ok = true
|
|
|
|
switch intval := v.(type) {
|
|
|
|
case int:
|
|
|
|
i = int64(intval)
|
|
|
|
case uint8:
|
|
|
|
i = int64(intval)
|
|
|
|
case uint16:
|
|
|
|
i = int64(intval)
|
2024-04-09 07:12:22 +02:00
|
|
|
case uint64:
|
|
|
|
i = int64(intval)
|
2024-03-28 06:26:20 +01:00
|
|
|
case uint32:
|
|
|
|
i = int64(intval)
|
|
|
|
case int8:
|
|
|
|
i = int64(intval)
|
|
|
|
case int16:
|
|
|
|
i = int64(intval)
|
|
|
|
case int32:
|
|
|
|
i = int64(intval)
|
|
|
|
case int64:
|
|
|
|
i = intval
|
|
|
|
default:
|
|
|
|
ok = false
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-04-09 07:12:22 +02:00
|
|
|
func fromGenericAny(v any) (exprAny any, ok bool) {
|
|
|
|
if exprAny, ok = v.(bool); ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if exprAny, ok = v.(string); ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if exprAny, ok = anyInteger(v); ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if exprAny, ok = anyFloat(v); ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-03-28 06:26:20 +01:00
|
|
|
func anyFloat(v any) (float float64, ok bool) {
|
|
|
|
ok = true
|
|
|
|
switch floatval := v.(type) {
|
|
|
|
case float32:
|
|
|
|
float = float64(floatval)
|
|
|
|
case float64:
|
|
|
|
float = floatval
|
|
|
|
default:
|
|
|
|
ok = false
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2024-04-02 04:36:03 +02:00
|
|
|
|
|
|
|
func CopyMap[K comparable, V any](dest, source map[K]V) map[K]V {
|
|
|
|
for k, v := range source {
|
|
|
|
dest[k] = v
|
|
|
|
}
|
|
|
|
return dest
|
|
|
|
}
|
|
|
|
|
|
|
|
func CloneMap[K comparable, V any](source map[K]V) map[K]V {
|
|
|
|
dest := make(map[K]V, len(source))
|
|
|
|
return CopyMap(dest, source)
|
|
|
|
}
|
2024-05-01 05:45:10 +02:00
|
|
|
|
|
|
|
func CopyFilteredMap[K comparable, V any](dest, source map[K]V, filter func(key K) (accept bool)) map[K]V {
|
|
|
|
// fmt.Printf("--- Clone with filter %p\n", filter)
|
|
|
|
if filter == nil {
|
|
|
|
return CopyMap(dest, source)
|
|
|
|
} else {
|
|
|
|
for k, v := range source {
|
|
|
|
if filter(k) {
|
|
|
|
// fmt.Printf("\tClone var %q\n", k)
|
|
|
|
dest[k] = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return dest
|
|
|
|
}
|
|
|
|
|
|
|
|
func CloneFilteredMap[K comparable, V any](source map[K]V, filter func(key K) (accept bool)) map[K]V {
|
|
|
|
dest := make(map[K]V, len(source))
|
|
|
|
return CopyFilteredMap(dest, source, filter)
|
|
|
|
}
|
2024-05-01 07:07:36 +02:00
|
|
|
|
|
|
|
func toInt(value any, description string) (i int, err error) {
|
|
|
|
if valueInt64, ok := value.(int64); ok {
|
|
|
|
i = int(valueInt64)
|
|
|
|
} else {
|
|
|
|
err = fmt.Errorf("%s expected integer, got %T (%v)", description, value, value)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|