gitee.com/liuxuezhan/go-micro-v1.18.0@v1.0.0/metadata/metadata.go (about)

     1  // Package metadata is a way of defining message headers
     2  package metadata
     3  
     4  import (
     5  	"context"
     6  )
     7  
     8  type metaKey struct{}
     9  
    10  // Metadata is our way of representing request headers internally.
    11  // They're used at the RPC level and translate back and forth
    12  // from Transport headers.
    13  type Metadata map[string]string
    14  
    15  // Copy makes a copy of the metadata
    16  func Copy(md Metadata) Metadata {
    17  	cmd := make(Metadata)
    18  	for k, v := range md {
    19  		cmd[k] = v
    20  	}
    21  	return cmd
    22  }
    23  
    24  // Get returns a single value from metadata in the context
    25  func Get(ctx context.Context, key string) (string, bool) {
    26  	md, ok := FromContext(ctx)
    27  	if !ok {
    28  		return "", ok
    29  	}
    30  	val, ok := md[key]
    31  	return val, ok
    32  }
    33  
    34  // FromContext returns metadata from the given context
    35  func FromContext(ctx context.Context) (Metadata, bool) {
    36  	md, ok := ctx.Value(metaKey{}).(Metadata)
    37  	return md, ok
    38  }
    39  
    40  // NewContext creates a new context with the given metadata
    41  func NewContext(ctx context.Context, md Metadata) context.Context {
    42  	return context.WithValue(ctx, metaKey{}, md)
    43  }
    44  
    45  // MergeContext merges metadata to existing metadata, overwriting if specified
    46  func MergeContext(ctx context.Context, patchMd Metadata, overwrite bool) context.Context {
    47  	md, _ := ctx.Value(metaKey{}).(Metadata)
    48  	cmd := make(Metadata)
    49  	for k, v := range md {
    50  		cmd[k] = v
    51  	}
    52  	for k, v := range patchMd {
    53  		if _, ok := cmd[k]; ok && !overwrite {
    54  			// skip
    55  		} else {
    56  			cmd[k] = v
    57  		}
    58  	}
    59  	return context.WithValue(ctx, metaKey{}, cmd)
    60  
    61  }