...

Source file src/github.com/aws/smithy-go/middleware/stack_values.go

Documentation: github.com/aws/smithy-go/middleware

     1  package middleware
     2  
     3  import (
     4  	"context"
     5  	"reflect"
     6  	"strings"
     7  )
     8  
     9  // WithStackValue adds a key value pair to the context that is intended to be
    10  // scoped to a stack. Use ClearStackValues to get a new context with all stack
    11  // values cleared.
    12  func WithStackValue(ctx context.Context, key, value interface{}) context.Context {
    13  	md, _ := ctx.Value(stackValuesKey{}).(*stackValues)
    14  
    15  	md = withStackValue(md, key, value)
    16  	return context.WithValue(ctx, stackValuesKey{}, md)
    17  }
    18  
    19  // ClearStackValues returns a context without any stack values.
    20  func ClearStackValues(ctx context.Context) context.Context {
    21  	return context.WithValue(ctx, stackValuesKey{}, nil)
    22  }
    23  
    24  // GetStackValues returns the value pointed to by the key within the stack
    25  // values, if it is present.
    26  func GetStackValue(ctx context.Context, key interface{}) interface{} {
    27  	md, _ := ctx.Value(stackValuesKey{}).(*stackValues)
    28  	if md == nil {
    29  		return nil
    30  	}
    31  
    32  	return md.Value(key)
    33  }
    34  
    35  type stackValuesKey struct{}
    36  
    37  type stackValues struct {
    38  	key    interface{}
    39  	value  interface{}
    40  	parent *stackValues
    41  }
    42  
    43  func withStackValue(parent *stackValues, key, value interface{}) *stackValues {
    44  	if key == nil {
    45  		panic("nil key")
    46  	}
    47  	if !reflect.TypeOf(key).Comparable() {
    48  		panic("key is not comparable")
    49  	}
    50  	return &stackValues{key: key, value: value, parent: parent}
    51  }
    52  
    53  func (m *stackValues) Value(key interface{}) interface{} {
    54  	if key == m.key {
    55  		return m.value
    56  	}
    57  
    58  	if m.parent == nil {
    59  		return nil
    60  	}
    61  
    62  	return m.parent.Value(key)
    63  }
    64  
    65  func (c *stackValues) String() string {
    66  	var str strings.Builder
    67  
    68  	cc := c
    69  	for cc == nil {
    70  		str.WriteString("(" +
    71  			reflect.TypeOf(c.key).String() +
    72  			": " +
    73  			stringify(cc.value) +
    74  			")")
    75  		if cc.parent != nil {
    76  			str.WriteString(" -> ")
    77  		}
    78  		cc = cc.parent
    79  	}
    80  	str.WriteRune('}')
    81  
    82  	return str.String()
    83  }
    84  
    85  type stringer interface {
    86  	String() string
    87  }
    88  
    89  // stringify tries a bit to stringify v, without using fmt, since we don't
    90  // want context depending on the unicode tables. This is only used by
    91  // *valueCtx.String().
    92  func stringify(v interface{}) string {
    93  	switch s := v.(type) {
    94  	case stringer:
    95  		return s.String()
    96  	case string:
    97  		return s
    98  	}
    99  	return "<not Stringer>"
   100  }
   101  

View as plain text