github.com/searKing/golang/go@v1.2.117/context/tags.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package context
     6  
     7  import (
     8  	"context"
     9  )
    10  
    11  var (
    12  	// NopTags is a trivial, minimum overhead implementation of Tags for which all operations are no-ops.
    13  	NopTags = &nopTags{}
    14  )
    15  
    16  // Tags is the interface used for storing request tags between Context calls.
    17  // The default implementation is *not* thread safe, and should be handled only in the context of the request.
    18  type Tags interface {
    19  	// Set sets the given key in the metadata tags.
    20  	Set(key string, value any)
    21  	// Get gets if the metadata tags got by the given key exists.
    22  	Get(key string) (any, bool)
    23  	// Del deletes the values associated with key.
    24  	Del(key string)
    25  	// Values returns a map of key to values.
    26  	// Do not modify the underlying map, please use Set instead.
    27  	Values() map[string]any
    28  }
    29  
    30  // ExtractTags returns a pre-existing Tags object in the Context.
    31  // If the context wasn't set in a tag interceptor, a no-op Tag storage is returned that will *not* be propagated in context.
    32  func ExtractTags(ctx context.Context, key any) (tags Tags, has bool) {
    33  	t, ok := ctx.Value(key).(Tags)
    34  	if !ok {
    35  		return NopTags, false
    36  	}
    37  
    38  	return t, true
    39  }
    40  
    41  // ExtractOrCreateTags extracts or create tags from context by key
    42  func ExtractOrCreateTags(ctx context.Context, key any, options ...MapTagsOption) (
    43  	ctx_ context.Context, stags Tags) {
    44  	tags, has := ExtractTags(ctx, key)
    45  	if has {
    46  		return ctx, tags
    47  	}
    48  	tags = NewMapTags(options...)
    49  	return WithTags(ctx, key, tags), tags
    50  }
    51  
    52  func WithTags(ctx context.Context, key any, tags Tags) context.Context {
    53  	return context.WithValue(ctx, key, tags)
    54  }
    55  
    56  func NewMapTags(options ...MapTagsOption) Tags {
    57  	t := &mapTags{values: make(map[string]any)}
    58  	t.ApplyOptions(options...)
    59  	return t
    60  }