mediocre-go-lib/mctx/annotate.go

72 lines
2.0 KiB
Go
Raw Normal View History

package mctx
import (
"context"
"fmt"
)
type annotateKey struct {
userKey interface{}
}
// Annotate takes in one or more key/value pairs (kvs' length must be even) and
// returns a Context carrying them. Annotations only exist on the local level,
// i.e. a child and parent share different annotation namespaces.
func Annotate(ctx context.Context, kvs ...interface{}) context.Context {
for i := 0; i < len(kvs); i += 2 {
ctx = WithLocalValue(ctx, annotateKey{kvs[i]}, kvs[i+1])
}
return ctx
}
// Annotations describes a set of keys/values which were set on a Context (but
// not its parents or children) using Annotate.
type Annotations [][2]interface{}
// LocalAnnotations returns all key/value pairs which have been set via Annotate
// on this Context (but not its parent or children). If a key was set twice then
// only the most recent value is included. The returned order is
// non-deterministic.
func LocalAnnotations(ctx context.Context) Annotations {
var annotations Annotations
localValuesIter(ctx, func(key, val interface{}) {
aKey, ok := key.(annotateKey)
if !ok {
return
}
annotations = append(annotations, [2]interface{}{aKey.userKey, val})
})
return annotations
}
// StringMap formats each of the key/value pairs into strings using fmt.Sprint.
// If any two keys format to the same string, then type information will be
// prefaced to each one.
func (aa Annotations) StringMap() map[string]string {
keyTypes := make(map[string]interface{}, len(aa))
keyVals := map[string]string{}
setKey := func(k, v interface{}) {
kStr := fmt.Sprint(k)
oldType := keyTypes[kStr]
if oldType == nil {
keyTypes[kStr] = k
keyVals[kStr] = fmt.Sprint(v)
return
}
// check if oldKey is in kvm, if so it needs to be moved to account for
// its type info
if oldV, ok := keyVals[kStr]; ok {
delete(keyVals, kStr)
keyVals[fmt.Sprintf("%T(%s)", oldType, kStr)] = oldV
}
keyVals[fmt.Sprintf("%T(%s)", k, kStr)] = fmt.Sprint(v)
}
for _, kv := range aa {
setKey(kv[0], kv[1])
}
return keyVals
}