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 }