1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
package logql
import (
"fmt"
"strconv"
"strings"
typesv1 "github.com/humanlogio/api/go/types/v1"
)
func VisitScalars(v *typesv1.Val, onScalar func(keys []string, scalar *typesv1.Val) error, prefixes ...string) error {
return visitScalars(prefixes, v, onScalar)
}
func visitScalars(keys []string, v *typesv1.Val, onScalar func(keys []string, scalar *typesv1.Val) error) error {
switch val := v.Kind.(type) {
case *typesv1.Val_Str:
return onScalar(keys, v)
case *typesv1.Val_F64:
return onScalar(keys, v)
case *typesv1.Val_I64:
return onScalar(keys, v)
case *typesv1.Val_Bool:
return onScalar(keys, v)
case *typesv1.Val_Ts:
return onScalar(keys, v)
case *typesv1.Val_Dur:
return onScalar(keys, v)
case *typesv1.Val_Arr:
for i, item := range val.Arr.Items {
k := strconv.Itoa(i)
if err := onScalar(append(keys, k), item); err != nil {
return fmt.Errorf("arr[%d] %v", i, err)
}
}
case *typesv1.Val_Obj:
for _, kval := range val.Obj.Kvs {
if err := onScalar(append(keys, kval.Key), kval.Value); err != nil {
return fmt.Errorf("obj[%q] %v", kval.Key, err)
}
}
default:
return fmt.Errorf("unsupported type %v", val)
}
return nil
}
type MakeMap func(prefixes []string, kvs []*typesv1.KV, mkMap MakeMap, mkSlice MakeSlice, setVal func([]string, any) error) error
type MakeSlice func(prefixes []string, items []*typesv1.Val, mkMap MakeMap, mkSlice MakeSlice, setVal func([]string, any) error) error
func ResolveVal(v *typesv1.Val, mkMap MakeMap, mkSlice MakeSlice) (any, error) {
var val any
return val, resolveVal(nil, v, mkMap, mkSlice, func(s []string, a any) error {
val = a
return nil
})
}
var (
MakeFlatGoMap MakeMap = func(prefixes []string, kvs []*typesv1.KV, mkMap MakeMap, mkSlice MakeSlice, setVal func([]string, any) error) error {
if len(prefixes) != 0 {
// dive deeper until we hit literals
for _, kv := range kvs {
keys := append(prefixes, kv.Key)
err := resolveVal(keys, kv.Value, mkMap, mkSlice, setVal)
if err != nil {
return err
}
}
return nil
}
out := make(map[string]any, len(kvs))
for _, kv := range kvs {
keys := []string{kv.Key}
err := resolveVal(keys, kv.Value, mkMap, mkSlice, func(s []string, a any) error {
k := strings.Join(s, ".")
out[k] = a
return nil
})
if err != nil {
return err
}
}
return setVal(nil, out)
}
MakeFlatMapGoSlice MakeSlice = func(prefixes []string, elems []*typesv1.Val, mkMap MakeMap, mkSlice MakeSlice, setVal func([]string, any) error) error {
if len(prefixes) != 0 {
// dive deeper until we hit literals
for i, el := range elems {
keys := append(prefixes, strconv.Itoa(i))
err := resolveVal(keys, el, mkMap, mkSlice, setVal)
if err != nil {
return err
}
}
return nil
}
out := make(map[string]any, len(elems))
for i, el := range elems {
keys := []string{strconv.Itoa(i)}
err := resolveVal(keys, el, mkMap, mkSlice, func(s []string, a any) error {
k := strings.Join(s, ".")
out[k] = a
return nil
})
if err != nil {
return err
}
}
return setVal(nil, out)
}
MakeFlatGoSlice MakeSlice = func(prefixes []string, elems []*typesv1.Val, mkMap MakeMap, mkSlice MakeSlice, setVal func([]string, any) error) error {
if len(prefixes) != 0 {
// dive deeper until we hit literals
for i, el := range elems {
keys := append(prefixes, strconv.Itoa(i))
err := resolveVal(keys, el, mkMap, mkSlice, setVal)
if err != nil {
return err
}
}
return nil
}
out := make([]any, 0, len(elems))
for _, el := range elems {
err := resolveVal(nil, el, mkMap, mkSlice, func(s []string, a any) error {
out = append(out, a)
return nil
})
if err != nil {
return err
}
}
return setVal(nil, out)
}
)
func resolveVal(
prefixes []string,
v *typesv1.Val,
mkMap MakeMap,
mkSlice MakeSlice,
setVal func([]string, any) error,
) error {
switch val := v.Kind.(type) {
case *typesv1.Val_Str:
return setVal(prefixes, val.Str)
case *typesv1.Val_F64:
return setVal(prefixes, val.F64)
case *typesv1.Val_I64:
return setVal(prefixes, val.I64)
case *typesv1.Val_Bool:
return setVal(prefixes, val.Bool)
case *typesv1.Val_Ts:
return setVal(prefixes, val.Ts.AsTime())
case *typesv1.Val_Dur:
return setVal(prefixes, val.Dur.AsDuration())
case *typesv1.Val_Arr:
return mkSlice(prefixes, val.Arr.Items, mkMap, mkSlice, setVal)
case *typesv1.Val_Obj:
return mkMap(prefixes, val.Obj.Kvs, mkMap, mkSlice, setVal)
default:
return fmt.Errorf("unsupported type %v", val)
}
}
|