micro/metadata/metadata.go
Vasiliy Tolstov 2f8c0d9f9d
All checks were successful
pr / test (pull_request) Successful in 2m10s
lint / lint (pull_request) Successful in 10m35s
rework metadata
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
2024-03-09 17:21:20 +03:00

118 lines
2.6 KiB
Go

// Package metadata is a way of defining message headers
package metadata
import (
"net/textproto"
"strings"
)
var (
// HeaderTopic is the header name that contains topic name
HeaderTopic = "Micro-Topic"
// HeaderContentType specifies content type of message
HeaderContentType = "Content-Type"
// HeaderEndpoint specifies endpoint in service
HeaderEndpoint = "Micro-Endpoint"
// HeaderService specifies service
HeaderService = "Micro-Service"
// HeaderTimeout specifies timeout of operation
HeaderTimeout = "Micro-Timeout"
// HeaderAuthorization specifies Authorization header
HeaderAuthorization = "Authorization"
// HeaderXRequestID specifies request id
HeaderXRequestID = "X-Request-Id"
)
// Metadata is our way of representing request headers internally.
type Metadata map[string][]string
// Get returns value from metadata by key
func (md Metadata) Get(key string) (string, bool) {
// fast path
val, ok := md[key]
if !ok {
// slow path
val, ok = md[textproto.CanonicalMIMEHeaderKey(key)]
}
return strings.Join(val, ","), ok
}
// Set is used to store value in metadata
func (md Metadata) Set(kv ...string) {
if len(kv)%2 == 1 {
kv = kv[:len(kv)-1]
}
for idx := 0; idx < len(kv); idx += 2 {
md[textproto.CanonicalMIMEHeaderKey(kv[idx])] = []string{kv[idx+1]}
}
}
// Append is used to append value in metadata
func (md Metadata) Append(k string, v ...string) {
if len(v) == 0 {
return
}
k = textproto.CanonicalMIMEHeaderKey(k)
md[k] = append(md[k], v...)
}
// Del is used to remove value from metadata
func (md Metadata) Del(keys ...string) {
for _, key := range keys {
// fast path
delete(md, key)
// slow path
delete(md, textproto.CanonicalMIMEHeaderKey(key))
}
}
// Copy makes a copy of the metadata
func Copy(md Metadata) Metadata {
nmd := make(Metadata, len(md))
for k, v := range md {
nmd[k] = v
}
return nmd
}
// New return new sized metadata
func New(size int) Metadata {
if size == 0 {
size = 2
}
return make(Metadata, size)
}
// Merge merges metadata to existing metadata, overwriting if specified
func Merge(omd Metadata, mmd Metadata, overwrite bool) Metadata {
nmd := Copy(omd)
for key, val := range mmd {
nval, ok := nmd[key]
switch {
case ok && overwrite:
nmd[key] = nval
continue
case ok && !overwrite:
continue
case !ok:
for _, v := range val {
if v != "" {
nval = append(nval, v)
}
}
nmd[key] = nval
}
}
return nmd
}
// Pairs from which metadata created
func Pairs(kv ...string) Metadata {
if len(kv)%2 == 1 {
kv = kv[:len(kv)-1]
}
md := make(Metadata, len(kv)/2)
md.Set(kv...)
return md
}