package middleware
import (
)
func ( context.Context, , interface{}) context.Context {
, := .Value(stackValuesKey{}).(*stackValues)
= withStackValue(, , )
return context.WithValue(, stackValuesKey{}, )
}
func ( context.Context) context.Context {
return context.WithValue(, stackValuesKey{}, nil)
}
func ( context.Context, interface{}) interface{} {
, := .Value(stackValuesKey{}).(*stackValues)
if == nil {
return nil
}
return .Value()
}
type stackValuesKey struct{}
type stackValues struct {
key interface{}
value interface{}
parent *stackValues
}
func ( *stackValues, , interface{}) *stackValues {
if == nil {
panic("nil key")
}
if !reflect.TypeOf().Comparable() {
panic("key is not comparable")
}
return &stackValues{key: , value: , parent: }
}
func ( *stackValues) ( interface{}) interface{} {
if == .key {
return .value
}
if .parent == nil {
return nil
}
return .parent.()
}
func ( *stackValues) () string {
var strings.Builder
:=
for == nil {
.WriteString("(" +
reflect.TypeOf(.key).String() +
": " +
stringify(.value) +
")")
if .parent != nil {
.WriteString(" -> ")
}
= .parent
}
.WriteRune('}')
return .String()
}
type stringer interface {
String() string
}
func ( interface{}) string {
switch s := .(type) {
case stringer:
return .String()
case string:
return
}
return "<not Stringer>"
}