diff --git a/CHANGELOG.md b/CHANGELOG.md index 56509d3..5b5e5a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +## [0.20.0] - 2023-04-12 + +### Added + +- Adds response headers to Api Error class + +### Changed + ## [0.19.1] - 2023-04-12 ### Added diff --git a/api_error.go b/api_error.go index d8aaa0e..7205840 100644 --- a/api_error.go +++ b/api_error.go @@ -6,6 +6,7 @@ import "fmt" type ApiError struct { Message string ResponseStatusCode int + ResponseHeaders *ResponseHeaders } func (e *ApiError) Error() string { @@ -18,5 +19,5 @@ func (e *ApiError) Error() string { // NewApiError creates a new ApiError instance func NewApiError() *ApiError { - return &ApiError{} + return &ApiError{ResponseHeaders: NewResponseHeaders()} } diff --git a/headers.go b/headers.go new file mode 100644 index 0000000..23c94bd --- /dev/null +++ b/headers.go @@ -0,0 +1,111 @@ +package abstractions + +import "strings" + +type header struct { + headers map[string]map[string]struct{} +} + +type void struct{} + +var voidInstance void + +func normalizeHeaderKey(key string) string { + return strings.ToLower(strings.Trim(key, " ")) +} + +//Add adds a new header or append a new value to an existing header +func (r *header) Add(key string, value string, additionalValues ...string) { + normalizedKey := normalizeHeaderKey(key) + if normalizedKey == "" || value == "" { + return + } + if r.headers == nil { + r.headers = make(map[string]map[string]struct{}) + } + if r.headers[normalizedKey] == nil { + r.headers[normalizedKey] = make(map[string]struct{}) + } + r.headers[normalizedKey][value] = voidInstance + for _, v := range additionalValues { + r.headers[normalizedKey][v] = voidInstance + } +} + +//Get returns the values for the specific header +func (r *header) Get(key string) []string { + if r.headers == nil { + return nil + } + normalizedKey := normalizeHeaderKey(key) + if r.headers[normalizedKey] == nil { + return make([]string, 0) + } + values := make([]string, 0, len(r.headers[normalizedKey])) + for k := range r.headers[normalizedKey] { + values = append(values, k) + } + return values +} + +//Remove removes the specific header and all its values +func (r *header) Remove(key string) { + if r.headers == nil { + return + } + normalizedKey := normalizeHeaderKey(key) + delete(r.headers, normalizedKey) +} + +//RemoveValue remove the value for the specific header +func (r *header) RemoveValue(key string, value string) { + if r.headers == nil { + return + } + normalizedKey := normalizeHeaderKey(key) + if r.headers[normalizedKey] == nil { + return + } + delete(r.headers[normalizedKey], value) + if len(r.headers[normalizedKey]) == 0 { + delete(r.headers, normalizedKey) + } +} + +//ContainsKey check if the key exists in the headers +func (r *header) ContainsKey(key string) bool { + if r.headers == nil { + return false + } + normalizedKey := normalizeHeaderKey(key) + return r.headers[normalizedKey] != nil +} + +//Clear clear all headers +func (r *header) Clear() { + r.headers = nil +} + +//AddAll adds all headers from the other headers +func (r *header) AddAll(other *header) { + if other == nil || other.headers == nil { + return + } + for k, v := range other.headers { + for k2 := range v { + r.Add(k, k2) + } + } +} + +//ListKeys returns all the keys in the headers +func (r *header) ListKeys() []string { + if r.headers == nil { + return make([]string, 0) + } + keys := make([]string, 0, len(r.headers)) + for k := range r.headers { + keys = append(keys, k) + } + return keys +} diff --git a/request_headers.go b/request_headers.go index a167e4f..99eb096 100644 --- a/request_headers.go +++ b/request_headers.go @@ -1,100 +1,18 @@ package abstractions -import "strings" - //RequestHeaders represents a collection of request headers type RequestHeaders struct { - headers map[string]map[string]struct{} + header } //NewRequestHeaders creates a new RequestHeaders func NewRequestHeaders() *RequestHeaders { return &RequestHeaders{ - headers: make(map[string]map[string]struct{}), + header{make(map[string]map[string]struct{})}, } } -func (r *RequestHeaders) normalizeHeaderKey(key string) string { - return strings.ToLower(strings.Trim(key, " ")) -} - -type void struct{} - -var voidInstance void - -//Add adds a new header or append a new value to an existing header -func (r *RequestHeaders) Add(key string, value string, additionalValues ...string) { - normalizedKey := r.normalizeHeaderKey(key) - if normalizedKey == "" || value == "" { - return - } - if r.headers == nil { - r.headers = make(map[string]map[string]struct{}) - } - if r.headers[normalizedKey] == nil { - r.headers[normalizedKey] = make(map[string]struct{}) - } - r.headers[normalizedKey][value] = voidInstance - for _, v := range additionalValues { - r.headers[normalizedKey][v] = voidInstance - } -} - -//Get returns the values for the specific header -func (r *RequestHeaders) Get(key string) []string { - if r.headers == nil { - return nil - } - normalizedKey := r.normalizeHeaderKey(key) - if r.headers[normalizedKey] == nil { - return make([]string, 0) - } - values := make([]string, 0, len(r.headers[normalizedKey])) - for k := range r.headers[normalizedKey] { - values = append(values, k) - } - return values -} - -//Remove removes the specific header and all its values -func (r *RequestHeaders) Remove(key string) { - if r.headers == nil { - return - } - normalizedKey := r.normalizeHeaderKey(key) - delete(r.headers, normalizedKey) -} - -//RemoveValue remove the value for the specific header -func (r *RequestHeaders) RemoveValue(key string, value string) { - if r.headers == nil { - return - } - normalizedKey := r.normalizeHeaderKey(key) - if r.headers[normalizedKey] == nil { - return - } - delete(r.headers[normalizedKey], value) - if len(r.headers[normalizedKey]) == 0 { - delete(r.headers, normalizedKey) - } -} - -//ContainsKey check if the key exists in the headers -func (r *RequestHeaders) ContainsKey(key string) bool { - if r.headers == nil { - return false - } - normalizedKey := r.normalizeHeaderKey(key) - return r.headers[normalizedKey] != nil -} - -//Clear clear all headers -func (r *RequestHeaders) Clear() { - r.headers = nil -} - -//AddAll adds all headers from the other RequestHeaders +//AddAll adds all headers from the other headers func (r *RequestHeaders) AddAll(other *RequestHeaders) { if other == nil || other.headers == nil { return @@ -105,15 +23,3 @@ func (r *RequestHeaders) AddAll(other *RequestHeaders) { } } } - -//ListKeys returns all the keys in the headers -func (r *RequestHeaders) ListKeys() []string { - if r.headers == nil { - return make([]string, 0) - } - keys := make([]string, 0, len(r.headers)) - for k := range r.headers { - keys = append(keys, k) - } - return keys -} diff --git a/response_headers.go b/response_headers.go new file mode 100644 index 0000000..9aaad74 --- /dev/null +++ b/response_headers.go @@ -0,0 +1,25 @@ +package abstractions + +//ResponseHeaders represents a collection of response headers +type ResponseHeaders struct { + header +} + +//NewResponseHeaders creates a new ResponseHeaders +func NewResponseHeaders() *ResponseHeaders { + return &ResponseHeaders{ + header{make(map[string]map[string]struct{})}, + } +} + +//AddAll adds all headers from the other headers +func (r *ResponseHeaders) AddAll(other *ResponseHeaders) { + if other == nil || other.headers == nil { + return + } + for k, v := range other.headers { + for k2 := range v { + r.Add(k, k2) + } + } +}