aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Majewsky <majewsky@gmx.net>2018-02-07 19:58:03 +0100
committerStefan Majewsky <majewsky@gmx.net>2018-02-07 19:58:03 +0100
commit99ef0307e75fecc469f63a82bb72d1b697e14fff (patch)
tree7114579ba523dc54b92b9bbea9d12dced4c02bcf
parent801b5207dcbf3438e7612e1f7edc9de32ce0780c (diff)
downloadgo-schwift-99ef0307e75fecc469f63a82bb72d1b697e14fff.tar.gz
finish moving towards new auto-generated Headers implementation
Everything in one package once more. The bigger API in *this* package is worth it when we don't have to expose guts to cross package boundaries.
-rw-r--r--errors.go12
-rw-r--r--field_metadata.go (renamed from headers/metadata.go)40
-rw-r--r--field_string.go (renamed from headers/string.go)44
-rw-r--r--field_time.go (renamed from headers/time.go)47
-rw-r--r--field_uint64.go (renamed from headers/uint64.go)71
-rw-r--r--generated.go298
-rw-r--r--generated.go.in80
-rw-r--r--headers.go7
-rw-r--r--headers/base.go33
-rw-r--r--headers/errors.go31
-rw-r--r--headers/headers.go91
-rw-r--r--headers/headers_test.go97
12 files changed, 273 insertions, 578 deletions
diff --git a/errors.go b/errors.go
index df6b706..7a7d40d 100644
--- a/errors.go
+++ b/errors.go
@@ -76,3 +76,15 @@ func Is(err error, code int) bool {
}
return false
}
+
+//MalformedHeaderError is generated when a response from Swift contains a
+//malformed header.
+type MalformedHeaderError struct {
+ Key string
+ ParseError error
+}
+
+//Error implements the builtin/error interface.
+func (e MalformedHeaderError) Error() string {
+ return "Bad header " + e.Key + ": " + e.ParseError.Error()
+}
diff --git a/headers/metadata.go b/field_metadata.go
index 8f07e89..cebd2af 100644
--- a/headers/metadata.go
+++ b/field_metadata.go
@@ -16,37 +16,41 @@
*
******************************************************************************/
-package headers
+package schwift
-//Metadata is a helper type that provides safe access to the metadata headers
-//in a schwift.Headers instance. It cannot be directly constructed, but each
-//subtype of schwift.Headers has a field "Metadata" of this type. For example:
+//FieldMetadata is a helper type that provides safe access to the metadata headers
+//in a SomethingHeaders instance. It cannot be directly constructed, but each
+//SomethingHeaders type has a method "Metadata" returning this type. For example:
//
-// var hdr ObjectHeaders
+// hdr := make(ObjectHeaders)
// //the following two statements are equivalent
-// hdr.Set("X-Object-Meta-Access", "strictly confidential")
-// hdr.Metadata.Set("Access", "strictly confidential")
-// //because hdr.Metadata is a headers.Metadata instance
-type Metadata struct {
- Base
+// hdr["X-Object-Meta-Access"] = "strictly confidential"
+// hdr.Metadata().Set("Access", "strictly confidential")
+type FieldMetadata struct {
+ h headerInterface
+ k string
}
//Clear works like Headers.Clear(), but prepends the metadata prefix to the key.
-func (m Metadata) Clear(key string) {
- m.H.Clear(m.K + key)
+func (m FieldMetadata) Clear(key string) {
+ m.h.Clear(m.k + key)
}
//Del works like Headers.Del(), but prepends the metadata prefix to the key.
-func (m Metadata) Del(key string) {
- m.H.Del(m.K + key)
+func (m FieldMetadata) Del(key string) {
+ m.h.Del(m.k + key)
}
//Get works like Headers.Get(), but prepends the metadata prefix to the key.
-func (m Metadata) Get(key string) string {
- return m.H.Get(m.K + key)
+func (m FieldMetadata) Get(key string) string {
+ return m.h.Get(m.k + key)
}
//Set works like Headers.Set(), but prepends the metadata prefix to the key.
-func (m Metadata) Set(key, value string) {
- m.H.Set(m.K+key, value)
+func (m FieldMetadata) Set(key, value string) {
+ m.h.Set(m.k+key, value)
+}
+
+func (m FieldMetadata) validate() error {
+ return nil
}
diff --git a/headers/string.go b/field_string.go
index 9979aef..d44d517 100644
--- a/headers/string.go
+++ b/field_string.go
@@ -16,45 +16,49 @@
*
******************************************************************************/
-package headers
+package schwift
-//String is a helper type that provides type-safe access to a Swift header key
-//whose value is a string. It cannot be directly constructed, but some subtypes
-//of schwift.Headers have fields of this type. For example:
+//FieldString is a helper type that provides type-safe access to a Swift header key
+//whose value is a string. It cannot be directly constructed, but methods on
+//the Headers types return this type. For example:
//
-// var hdr AccountHeaders
+// hdr := make(AccountHeaders)
// //the following two statements are equivalent:
-// hdr.Set("X-Container-Read", ".r:*,.rlistings")
-// hdr.ReadACL.Set(".r:*,.rlistings")
-// //because hdr.ReadACL is a headers.String instance
-type String struct {
- Base
+// hdr["X-Container-Read"] = ".r:*,.rlistings"
+// hdr.ReadACL().Set(".r:*,.rlistings")
+type FieldString struct {
+ h headerInterface
+ k string
}
//Exists checks whether there is a value for this header.
-func (f String) Exists() bool {
- return f.H.Get(f.K) != ""
+func (f FieldString) Exists() bool {
+ return f.h.Get(f.k) != ""
}
//Get returns the value for this header, or the empty string if there is no value.
-func (f String) Get() string {
- return f.H.Get(f.K)
+func (f FieldString) Get() string {
+ return f.h.Get(f.k)
}
//Set writes a new value for this header into the corresponding schwift.Headers
//instance.
-func (f String) Set(value string) {
- f.H.Set(f.K, value)
+func (f FieldString) Set(value string) {
+ f.h.Set(f.k, value)
}
//Del removes this key from the original schwift.Headers instance, so that the
//key will remain unchanged on the server during Update().
-func (f String) Del() {
- f.H.Del(f.K)
+func (f FieldString) Del() {
+ f.h.Del(f.k)
}
//Clear sets this key to an empty string in the original schwift.Headers
//instance, so that the key will be removed on the server during Update().
-func (f String) Clear() {
- f.H.Clear(f.K)
+func (f FieldString) Clear() {
+ f.h.Clear(f.k)
+}
+
+func (f FieldString) validate() error {
+ return nil
}
diff --git a/headers/time.go b/field_time.go
index 5f9209f..d8a1776 100644
--- a/headers/time.go
+++ b/field_time.go
@@ -16,7 +16,7 @@
*
******************************************************************************/
-package headers
+package schwift
import (
"math"
@@ -24,28 +24,37 @@ import (
"time"
)
-//UnixTimeReadonly is a helper type that provides type-safe access to a Swift
-//header whose value is a UNIX timestamp. It cannot be directly constructed,
-//but some subtypes of schwift.Headers have fields of this type. For example:
+//FieldUnixTimeReadonly is a helper type that provides type-safe access to a
+//Swift header whose value is a UNIX timestamp. It cannot be directly
+//constructed, but methods on the Headers types return this type. For example:
//
-// var hdr AccountHeaders
-// //hdr.Timestamp is a headers.UnixTimeReadonly instance
-// hdr.Timestamp.Get() //returns a time.Time
-// hdr.Get("X-Timestamp") //returns a string containing a UNIX timestamp
-// //refering to the same point in time
-type UnixTimeReadonly struct {
- Base
+// //suppose you have:
+// hdr, err := obj.Headers()
+//
+// //you could do all this:
+// sec, err := strconv.ParseFloat(hdr.Get("X-Timestamp"), 64)
+// time := time.Unix(int64(sec), int64(1e9 * (sec - math.Floor(sec))))
+//
+// //or you can just:
+// time := hdr.Timestamp().Get()
+//
+//Don't worry about the missing `err` in the last line. When the X-Timestamp
+//header fails to parse, Object.Headers() already returns the corresponding
+//MalformedHeaderError.
+type FieldUnixTimeReadonly struct {
+ h headerInterface
+ k string
}
//Exists checks whether there is a value for this header.
-func (f UnixTimeReadonly) Exists() bool {
- return f.H.Get(f.K) != ""
+func (f FieldUnixTimeReadonly) Exists() bool {
+ return f.h.Get(f.k) != ""
}
//Get returns the value for this header, or the zero value if there is no value
//(or if it is not a valid timestamp).
-func (f UnixTimeReadonly) Get() time.Time {
- v, err := strconv.ParseFloat(f.H.Get(f.K), 64)
+func (f FieldUnixTimeReadonly) Get() time.Time {
+ v, err := strconv.ParseFloat(f.h.Get(f.k), 64)
if err != nil {
return time.Time{}
}
@@ -56,10 +65,8 @@ func (f UnixTimeReadonly) Get() time.Time {
)
}
-//Validate is only used internally, but needs to be exported to cross package
-//boundaries.
-func (f UnixTimeReadonly) Validate() error {
- val := f.H.Get(f.K)
+func (f FieldUnixTimeReadonly) validate() error {
+ val := f.h.Get(f.k)
if val == "" {
return nil
}
@@ -67,5 +74,5 @@ func (f UnixTimeReadonly) Validate() error {
if err == nil {
return nil
}
- return MalformedHeaderError{f.K, err}
+ return MalformedHeaderError{f.k, err}
}
diff --git a/headers/uint64.go b/field_uint64.go
index 6e8668b..4655478 100644
--- a/headers/uint64.go
+++ b/field_uint64.go
@@ -16,34 +16,34 @@
*
******************************************************************************/
-package headers
+package schwift
import (
"strconv"
)
-//Uint64 is a helper type that provides type-safe access to a Swift header
+//FieldUint64 is a helper type that provides type-safe access to a Swift header
//whose value is an unsigned integer. It cannot be directly constructed, but
-//some subtypes of schwift.Headers have fields of this type. For example:
+//methods on the Headers types return this type. For example:
//
-// var hdr AccountHeaders
+// hdr := make(AccountHeaders)
// //the following two statements are equivalent:
-// hdr.Set("X-Account-Meta-Quota-Bytes", "1048576")
-// hdr.QuotaBytes.Set(1 << 20)
-// //because hdr.QuotaBytes is a headers.Uint64 instance
-type Uint64 struct {
- Base
+// hdr["X-Account-Meta-Quota-Bytes"] = "1048576"
+// hdr.QuotaBytes().Set(1 << 20)
+type FieldUint64 struct {
+ h headerInterface
+ k string
}
//Exists checks whether there is a value for this header.
-func (f Uint64) Exists() bool {
- return f.H.Get(f.K) != ""
+func (f FieldUint64) Exists() bool {
+ return f.h.Get(f.k) != ""
}
//Get returns the value for this header, or 0 if there is no value (or if it is
//not a valid uint64).
-func (f Uint64) Get() uint64 {
- v, err := strconv.ParseUint(f.H.Get(f.K), 10, 64)
+func (f FieldUint64) Get() uint64 {
+ v, err := strconv.ParseUint(f.h.Get(f.k), 10, 64)
if err != nil {
return 0
}
@@ -52,26 +52,26 @@ func (f Uint64) Get() uint64 {
//Set writes a new value for this header into the corresponding schwift.Headers
//instance.
-func (f Uint64) Set(value uint64) {
- f.H.Set(f.K, strconv.FormatUint(value, 10))
+func (f FieldUint64) Set(value uint64) {
+ f.h.Set(f.k, strconv.FormatUint(value, 10))
}
//Del removes this key from the original schwift.Headers instance, so that the
//key will remain unchanged on the server during Update().
-func (f Uint64) Del() {
- f.H.Del(f.K)
+func (f FieldUint64) Del() {
+ f.h.Del(f.k)
}
//Clear sets this key to an empty string in the original schwift.Headers
//instance, so that the key will be removed on the server during Update().
-func (f Uint64) Clear() {
- f.H.Clear(f.K)
+func (f FieldUint64) Clear() {
+ f.h.Clear(f.k)
}
-//Validate is only used internally, but needs to be exported to cross package
+//validate is only used internally, but needs to be exported to cross package
//boundaries.
-func (f Uint64) Validate() error {
- val := f.H.Get(f.K)
+func (f FieldUint64) validate() error {
+ val := f.h.Get(f.k)
if val == "" {
return nil
}
@@ -79,36 +79,35 @@ func (f Uint64) Validate() error {
if err == nil {
return nil
}
- return MalformedHeaderError{f.K, err}
+ return MalformedHeaderError{f.k, err}
}
////////////////////////////////////////////////////////////////////////////////
-//Uint64Readonly is a readonly variant of Uint64. It is used for fields that
-//cannot be set by the client.
-type Uint64Readonly struct {
- Base
+//FieldUint64Readonly is a readonly variant of FieldUint64. It is used for
+//fields that cannot be set by the client.
+type FieldUint64Readonly struct {
+ h headerInterface
+ k string
}
//Exists checks whether there is a value for this header.
-func (f Uint64Readonly) Exists() bool {
- return f.H.Get(f.K) != ""
+func (f FieldUint64Readonly) Exists() bool {
+ return f.h.Get(f.k) != ""
}
//Get returns the value for this header, or 0 if there is no value (or if it is
//not a valid uint64).
-func (f Uint64Readonly) Get() uint64 {
- v, err := strconv.ParseUint(f.H.Get(f.K), 10, 64)
+func (f FieldUint64Readonly) Get() uint64 {
+ v, err := strconv.ParseUint(f.h.Get(f.k), 10, 64)
if err != nil {
return 0
}
return v
}
-//Validate is only used internally, but needs to be exported to cross package
-//boundaries.
-func (f Uint64Readonly) Validate() error {
- val := f.H.Get(f.K)
+func (f FieldUint64Readonly) validate() error {
+ val := f.h.Get(f.k)
if val == "" {
return nil
}
@@ -116,5 +115,5 @@ func (f Uint64Readonly) Validate() error {
if err == nil {
return nil
}
- return MalformedHeaderError{f.K, err}
+ return MalformedHeaderError{f.k, err}
}
diff --git a/generated.go b/generated.go
index a3dca80..60b5a46 100644
--- a/generated.go
+++ b/generated.go
@@ -8,16 +8,13 @@
package schwift
-import (
- "net/textproto"
-
- "github.com/majewsky/schwift/headers"
-)
+import "net/textproto"
//AccountHeaders contains the headers for a schwift.Account instance.
//
//To read and write well-known headers, use the methods on this type.
-//To read and write arbitary headers, use the methods on type Headers.
+//To read and write arbitary headers, use the http.Header-like methods Get(),
+//Set(), Clear(), Del().
type AccountHeaders map[string]string
//Clear sets the value for the specified header to the empty string. When the
@@ -49,114 +46,84 @@ func (h AccountHeaders) Set(key, value string) {
h[textproto.CanonicalMIMEHeaderKey(key)] = value
}
-//Validate returns headers.MalformedHeaderError if the value of any well-known
-//header does not conform to its data type. This is called automatically by
-//Schwift when preparing an AccountHeaders instance from a GET/HEAD response,
-//so you usually do not need to do it yourself. You will get the validation error
-//from the Account method doing the request, e.g. Headers().
+//Validate returns MalformedHeaderError if the value of any well-known header
+//does not conform to its data type. This is called automatically by Schwift
+//when preparing an AccountHeaders instance from a GET/HEAD response, so you
+//usually do not need to do it yourself. You will get the validation error from
+//the Account method doing the request, e.g. Headers().
func (h AccountHeaders) Validate() error {
- if err := h.BytesUsed().Validate(); err != nil {
+ if err := h.BytesUsed().validate(); err != nil {
+ return err
+ }
+ if err := h.ContainerCount().validate(); err != nil {
+ return err
+ }
+ if err := h.Metadata().validate(); err != nil {
+ return err
+ }
+ if err := h.QuotaBytes().validate(); err != nil {
return err
}
- if err := h.ContainerCount().Validate(); err != nil {
+ if err := h.TempURLKey2().validate(); err != nil {
return err
}
- if err := h.QuotaBytes().Validate(); err != nil {
+ if err := h.TempURLKey().validate(); err != nil {
return err
}
- if err := h.ObjectCount().Validate(); err != nil {
+ if err := h.ObjectCount().validate(); err != nil {
return err
}
- if err := h.Timestamp().Validate(); err != nil {
+ if err := h.Timestamp().validate(); err != nil {
return err
}
return evadeGolintComplaint1()
}
//BytesUsed provides type-safe access to X-Account-Bytes-Used headers.
-func (h AccountHeaders) BytesUsed() headers.Uint64Readonly {
- return headers.Uint64Readonly{
- Base: headers.Base{
- H: h,
- K: "X-Account-Bytes-Used",
- },
- }
+func (h AccountHeaders) BytesUsed() FieldUint64Readonly {
+ return FieldUint64Readonly{h, "X-Account-Bytes-Used"}
}
//ContainerCount provides type-safe access to X-Account-Container-Count headers.
-func (h AccountHeaders) ContainerCount() headers.Uint64Readonly {
- return headers.Uint64Readonly{
- Base: headers.Base{
- H: h,
- K: "X-Account-Container-Count",
- },
- }
+func (h AccountHeaders) ContainerCount() FieldUint64Readonly {
+ return FieldUint64Readonly{h, "X-Account-Container-Count"}
}
//Metadata provides type-safe access to X-Account-Meta- headers.
-func (h AccountHeaders) Metadata() headers.Metadata {
- return headers.Metadata{
- Base: headers.Base{
- H: h,
- K: "X-Account-Meta-",
- },
- }
+func (h AccountHeaders) Metadata() FieldMetadata {
+ return FieldMetadata{h, "X-Account-Meta-"}
}
//QuotaBytes provides type-safe access to X-Account-Meta-Quota-Bytes headers.
-func (h AccountHeaders) QuotaBytes() headers.Uint64 {
- return headers.Uint64{
- Base: headers.Base{
- H: h,
- K: "X-Account-Meta-Quota-Bytes",
- },
- }
+func (h AccountHeaders) QuotaBytes() FieldUint64 {
+ return FieldUint64{h, "X-Account-Meta-Quota-Bytes"}
}
//TempURLKey2 provides type-safe access to X-Account-Meta-Temp-URL-Key-2 headers.
-func (h AccountHeaders) TempURLKey2() headers.String {
- return headers.String{
- Base: headers.Base{
- H: h,
- K: "X-Account-Meta-Temp-URL-Key-2",
- },
- }
+func (h AccountHeaders) TempURLKey2() FieldString {
+ return FieldString{h, "X-Account-Meta-Temp-URL-Key-2"}
}
//TempURLKey provides type-safe access to X-Account-Meta-Temp-URL-Key headers.
-func (h AccountHeaders) TempURLKey() headers.String {
- return headers.String{
- Base: headers.Base{
- H: h,
- K: "X-Account-Meta-Temp-URL-Key",
- },
- }
+func (h AccountHeaders) TempURLKey() FieldString {
+ return FieldString{h, "X-Account-Meta-Temp-URL-Key"}
}
//ObjectCount provides type-safe access to X-Account-Object-Count headers.
-func (h AccountHeaders) ObjectCount() headers.Uint64Readonly {
- return headers.Uint64Readonly{
- Base: headers.Base{
- H: h,
- K: "X-Account-Object-Count",
- },
- }
+func (h AccountHeaders) ObjectCount() FieldUint64Readonly {
+ return FieldUint64Readonly{h, "X-Account-Object-Count"}
}
//Timestamp provides type-safe access to X-Timestamp headers.
-func (h AccountHeaders) Timestamp() headers.UnixTimeReadonly {
- return headers.UnixTimeReadonly{
- Base: headers.Base{
- H: h,
- K: "X-Timestamp",
- },
- }
+func (h AccountHeaders) Timestamp() FieldUnixTimeReadonly {
+ return FieldUnixTimeReadonly{h, "X-Timestamp"}
}
//ContainerHeaders contains the headers for a schwift.Container instance.
//
//To read and write well-known headers, use the methods on this type.
-//To read and write arbitary headers, use the methods on type Headers.
+//To read and write arbitary headers, use the http.Header-like methods Get(),
+//Set(), Clear(), Del().
type ContainerHeaders map[string]string
//Clear sets the value for the specified header to the empty string. When the
@@ -188,178 +155,133 @@ func (h ContainerHeaders) Set(key, value string) {
h[textproto.CanonicalMIMEHeaderKey(key)] = value
}
-//Validate returns headers.MalformedHeaderError if the value of any well-known
-//header does not conform to its data type. This is called automatically by
-//Schwift when preparing an ContainerHeaders instance from a GET/HEAD response,
-//so you usually do not need to do it yourself. You will get the validation error
-//from the Container method doing the request, e.g. Headers().
+//Validate returns MalformedHeaderError if the value of any well-known header
+//does not conform to its data type. This is called automatically by Schwift
+//when preparing an ContainerHeaders instance from a GET/HEAD response, so you
+//usually do not need to do it yourself. You will get the validation error from
+//the Container method doing the request, e.g. Headers().
func (h ContainerHeaders) Validate() error {
- if err := h.BytesUsed().Validate(); err != nil {
+ if err := h.BytesUsed().validate(); err != nil {
+ return err
+ }
+ if err := h.Metadata().validate(); err != nil {
+ return err
+ }
+ if err := h.BytesUsedQuota().validate(); err != nil {
+ return err
+ }
+ if err := h.ObjectCountQuota().validate(); err != nil {
+ return err
+ }
+ if err := h.TempURLKey2().validate(); err != nil {
+ return err
+ }
+ if err := h.TempURLKey().validate(); err != nil {
return err
}
- if err := h.BytesUsedQuota().Validate(); err != nil {
+ if err := h.ObjectCount().validate(); err != nil {
return err
}
- if err := h.ObjectCountQuota().Validate(); err != nil {
+ if err := h.ReadACL().validate(); err != nil {
return err
}
- if err := h.ObjectCount().Validate(); err != nil {
+ if err := h.SyncKey().validate(); err != nil {
return err
}
- if err := h.Timestamp().Validate(); err != nil {
+ if err := h.SyncTo().validate(); err != nil {
+ return err
+ }
+ if err := h.WriteACL().validate(); err != nil {
+ return err
+ }
+ if err := h.HistoryLocation().validate(); err != nil {
+ return err
+ }
+ if err := h.StoragePolicy().validate(); err != nil {
+ return err
+ }
+ if err := h.Timestamp().validate(); err != nil {
+ return err
+ }
+ if err := h.VersionsLocation().validate(); err != nil {
return err
}
return evadeGolintComplaint1()
}
//BytesUsed provides type-safe access to X-Container-Bytes-Used headers.
-func (h ContainerHeaders) BytesUsed() headers.Uint64Readonly {
- return headers.Uint64Readonly{
- Base: headers.Base{
- H: h,
- K: "X-Container-Bytes-Used",
- },
- }
+func (h ContainerHeaders) BytesUsed() FieldUint64Readonly {
+ return FieldUint64Readonly{h, "X-Container-Bytes-Used"}
}
//Metadata provides type-safe access to X-Container-Meta- headers.
-func (h ContainerHeaders) Metadata() headers.Metadata {
- return headers.Metadata{
- Base: headers.Base{
- H: h,
- K: "X-Container-Meta-",
- },
- }
+func (h ContainerHeaders) Metadata() FieldMetadata {
+ return FieldMetadata{h, "X-Container-Meta-"}
}
//BytesUsedQuota provides type-safe access to X-Container-Meta-Quota-Bytes headers.
-func (h ContainerHeaders) BytesUsedQuota() headers.Uint64 {
- return headers.Uint64{
- Base: headers.Base{
- H: h,
- K: "X-Container-Meta-Quota-Bytes",
- },
- }
+func (h ContainerHeaders) BytesUsedQuota() FieldUint64 {
+ return FieldUint64{h, "X-Container-Meta-Quota-Bytes"}
}
//ObjectCountQuota provides type-safe access to X-Container-Meta-Quota-Count headers.
-func (h ContainerHeaders) ObjectCountQuota() headers.Uint64 {
- return headers.Uint64{
- Base: headers.Base{
- H: h,
- K: "X-Container-Meta-Quota-Count",
- },
- }
+func (h ContainerHeaders) ObjectCountQuota() FieldUint64 {
+ return FieldUint64{h, "X-Container-Meta-Quota-Count"}
}
//TempURLKey2 provides type-safe access to X-Container-Meta-Temp-URL-Key-2 headers.
-func (h ContainerHeaders) TempURLKey2() headers.String {
- return headers.String{
- Base: headers.Base{
- H: h,
- K: "X-Container-Meta-Temp-URL-Key-2",
- },
- }
+func (h ContainerHeaders) TempURLKey2() FieldString {
+ return FieldString{h, "X-Container-Meta-Temp-URL-Key-2"}
}
//TempURLKey provides type-safe access to X-Container-Meta-Temp-URL-Key headers.
-func (h ContainerHeaders) TempURLKey() headers.String {
- return headers.String{
- Base: headers.Base{
- H: h,
- K: "X-Container-Meta-Temp-URL-Key",
- },
- }
+func (h ContainerHeaders) TempURLKey() FieldString {
+ return FieldString{h, "X-Container-Meta-Temp-URL-Key"}
}
//ObjectCount provides type-safe access to X-Container-Object-Count headers.
-func (h ContainerHeaders) ObjectCount() headers.Uint64Readonly {
- return headers.Uint64Readonly{
- Base: headers.Base{
- H: h,
- K: "X-Container-Object-Count",
- },
- }
+func (h ContainerHeaders) ObjectCount() FieldUint64Readonly {
+ return FieldUint64Readonly{h, "X-Container-Object-Count"}
}
//ReadACL provides type-safe access to X-Container-Read headers.
-func (h ContainerHeaders) ReadACL() headers.String {
- return headers.String{
- Base: headers.Base{
- H: h,
- K: "X-Container-Read",
- },
- }
+func (h ContainerHeaders) ReadACL() FieldString {
+ return FieldString{h, "X-Container-Read"}
}
//SyncKey provides type-safe access to X-Container-Sync-Key headers.
-func (h ContainerHeaders) SyncKey() headers.String {
- return headers.String{
- Base: headers.Base{
- H: h,
- K: "X-Container-Sync-Key",
- },
- }
+func (h ContainerHeaders) SyncKey() FieldString {
+ return FieldString{h, "X-Container-Sync-Key"}
}
//SyncTo provides type-safe access to X-Container-Sync-To headers.
-func (h ContainerHeaders) SyncTo() headers.String {
- return headers.String{
- Base: headers.Base{
- H: h,
- K: "X-Container-Sync-To",
- },
- }
+func (h ContainerHeaders) SyncTo() FieldString {
+ return FieldString{h, "X-Container-Sync-To"}
}
//WriteACL provides type-safe access to X-Container-Write headers.
-func (h ContainerHeaders) WriteACL() headers.String {
- return headers.String{
- Base: headers.Base{
- H: h,
- K: "X-Container-Write",
- },
- }
+func (h ContainerHeaders) WriteACL() FieldString {
+ return FieldString{h, "X-Container-Write"}
}
//HistoryLocation provides type-safe access to X-History-Location headers.
-func (h ContainerHeaders) HistoryLocation() headers.String {
- return headers.String{
- Base: headers.Base{
- H: h,
- K: "X-History-Location",
- },
- }
+func (h ContainerHeaders) HistoryLocation() FieldString {
+ return FieldString{h, "X-History-Location"}
}
//StoragePolicy provides type-safe access to X-Storage-Policy headers.
-func (h ContainerHeaders) StoragePolicy() headers.String {
- return headers.String{
- Base: headers.Base{
- H: h,
- K: "X-Storage-Policy",
- },
- }
+func (h ContainerHeaders) StoragePolicy() FieldString {
+ return FieldString{h, "X-Storage-Policy"}
}
//Timestamp provides type-safe access to X-Timestamp headers.
-func (h ContainerHeaders) Timestamp() headers.UnixTimeReadonly {
- return headers.UnixTimeReadonly{
- Base: headers.Base{
- H: h,
- K: "X-Timestamp",
- },
- }
+func (h ContainerHeaders) Timestamp() FieldUnixTimeReadonly {
+ return FieldUnixTimeReadonly{h, "X-Timestamp"}
}
//VersionsLocation provides type-safe access to X-Versions-Location headers.
-func (h ContainerHeaders) VersionsLocation() headers.String {
- return headers.String{
- Base: headers.Base{
- H: h,
- K: "X-Versions-Location",
- },
- }
+func (h ContainerHeaders) VersionsLocation() FieldString {
+ return FieldString{h, "X-Versions-Location"}
}
func evadeGolintComplaint1() error {
diff --git a/generated.go.in b/generated.go.in
index 034a8e4..808c950 100644
--- a/generated.go.in
+++ b/generated.go.in
@@ -1,33 +1,33 @@
{
"Account": {
"Fields": [
- { "Header": "X-Account-Bytes-Used", "Attribute": "BytesUsed", "Type": "headers.Uint64Readonly" },
- { "Header": "X-Account-Container-Count", "Attribute": "ContainerCount", "Type": "headers.Uint64Readonly" },
- { "Header": "X-Account-Meta-", "Attribute": "Metadata", "Type": "headers.Metadata" },
- { "Header": "X-Account-Meta-Quota-Bytes", "Attribute": "QuotaBytes", "Type": "headers.Uint64" },
- { "Header": "X-Account-Meta-Temp-URL-Key-2", "Attribute": "TempURLKey2", "Type": "headers.String" },
- { "Header": "X-Account-Meta-Temp-URL-Key", "Attribute": "TempURLKey", "Type": "headers.String" },
- { "Header": "X-Account-Object-Count", "Attribute": "ObjectCount", "Type": "headers.Uint64Readonly" },
- { "Header": "X-Timestamp", "Attribute": "Timestamp", "Type": "headers.UnixTimeReadonly" }
+ { "Header": "X-Account-Bytes-Used", "Attribute": "BytesUsed", "Type": "Uint64Readonly" },
+ { "Header": "X-Account-Container-Count", "Attribute": "ContainerCount", "Type": "Uint64Readonly" },
+ { "Header": "X-Account-Meta-", "Attribute": "Metadata", "Type": "Metadata" },
+ { "Header": "X-Account-Meta-Quota-Bytes", "Attribute": "QuotaBytes", "Type": "Uint64" },
+ { "Header": "X-Account-Meta-Temp-URL-Key-2", "Attribute": "TempURLKey2", "Type": "String" },
+ { "Header": "X-Account-Meta-Temp-URL-Key", "Attribute": "TempURLKey", "Type": "String" },
+ { "Header": "X-Account-Object-Count", "Attribute": "ObjectCount", "Type": "Uint64Readonly" },
+ { "Header": "X-Timestamp", "Attribute": "Timestamp", "Type": "UnixTimeReadonly" }
]
},
"Container": {
"Fields": [
- { "Header": "X-Container-Bytes-Used", "Attribute": "BytesUsed", "Type": "headers.Uint64Readonly" },
- { "Header": "X-Container-Meta-", "Attribute": "Metadata", "Type": "headers.Metadata" },
- { "Header": "X-Container-Meta-Quota-Bytes", "Attribute": "BytesUsedQuota", "Type": "headers.Uint64" },
- { "Header": "X-Container-Meta-Quota-Count", "Attribute": "ObjectCountQuota", "Type": "headers.Uint64" },
- { "Header": "X-Container-Meta-Temp-URL-Key-2", "Attribute": "TempURLKey2", "Type": "headers.String" },
- { "Header": "X-Container-Meta-Temp-URL-Key", "Attribute": "TempURLKey", "Type": "headers.String" },
- { "Header": "X-Container-Object-Count", "Attribute": "ObjectCount", "Type": "headers.Uint64Readonly" },
- { "Header": "X-Container-Read", "Attribute": "ReadACL", "Type": "headers.String" },
- { "Header": "X-Container-Sync-Key", "Attribute": "SyncKey", "Type": "headers.String" },
- { "Header": "X-Container-Sync-To", "Attribute": "SyncTo", "Type": "headers.String" },
- { "Header": "X-Container-Write", "Attribute": "WriteACL", "Type": "headers.String" },
- { "Header": "X-History-Location", "Attribute": "HistoryLocation", "Type": "headers.String" },
- { "Header": "X-Storage-Policy", "Attribute": "StoragePolicy", "Type": "headers.String" },
- { "Header": "X-Timestamp", "Attribute": "Timestamp", "Type": "headers.UnixTimeReadonly" },
- { "Header": "X-Versions-Location", "Attribute": "VersionsLocation", "Type": "headers.String" }
+ { "Header": "X-Container-Bytes-Used", "Attribute": "BytesUsed", "Type": "Uint64Readonly" },
+ { "Header": "X-Container-Meta-", "Attribute": "Metadata", "Type": "Metadata" },
+ { "Header": "X-Container-Meta-Quota-Bytes", "Attribute": "BytesUsedQuota", "Type": "Uint64" },
+ { "Header": "X-Container-Meta-Quota-Count", "Attribute": "ObjectCountQuota", "Type": "Uint64" },
+ { "Header": "X-Container-Meta-Temp-URL-Key-2", "Attribute": "TempURLKey2", "Type": "String" },
+ { "Header": "X-Container-Meta-Temp-URL-Key", "Attribute": "TempURLKey", "Type": "String" },
+ { "Header": "X-Container-Object-Count", "Attribute": "ObjectCount", "Type": "Uint64Readonly" },
+ { "Header": "X-Container-Read", "Attribute": "ReadACL", "Type": "String" },
+ { "Header": "X-Container-Sync-Key", "Attribute": "SyncKey", "Type": "String" },
+ { "Header": "X-Container-Sync-To", "Attribute": "SyncTo", "Type": "String" },
+ { "Header": "X-Container-Write", "Attribute": "WriteACL", "Type": "String" },
+ { "Header": "X-History-Location", "Attribute": "HistoryLocation", "Type": "String" },
+ { "Header": "X-Storage-Policy", "Attribute": "StoragePolicy", "Type": "String" },
+ { "Header": "X-Timestamp", "Attribute": "Timestamp", "Type": "UnixTimeReadonly" },
+ { "Header": "X-Versions-Location", "Attribute": "VersionsLocation", "Type": "String" }
]
}
}
@@ -42,18 +42,15 @@
package schwift
-import (
- "net/textproto"
-
- "github.com/majewsky/schwift/headers"
-)
+import "net/textproto"
{{- range $htype, $hmeta := . }}
//{{$htype}}Headers contains the headers for a schwift.{{$htype}} instance.
//
//To read and write well-known headers, use the methods on this type.
-//To read and write arbitary headers, use the methods on type Headers.
+//To read and write arbitary headers, use the http.Header-like methods Get(),
+//Set(), Clear(), Del().
type {{$htype}}Headers map[string]string
//Clear sets the value for the specified header to the empty string. When the
@@ -91,30 +88,25 @@ func (h {{$htype}}Headers) Set(key, value string) {
h[textproto.CanonicalMIMEHeaderKey(key)] = value
}
-//Validate returns headers.MalformedHeaderError if the value of any well-known
-//header does not conform to its data type. This is called automatically by
-//Schwift when preparing an {{$htype}}Headers instance from a GET/HEAD response,
-//so you usually do not need to do it yourself. You will get the validation error
-//from the {{$htype}} method doing the request, e.g. Headers().
+//Validate returns MalformedHeaderError if the value of any well-known header
+//does not conform to its data type. This is called automatically by Schwift
+//when preparing an {{$htype}}Headers instance from a GET/HEAD response, so you
+//usually do not need to do it yourself. You will get the validation error from
+//the {{$htype}} method doing the request, e.g. Headers().
func (h {{$htype}}Headers) Validate() error {
-{{- range $field := $hmeta.Fields }}{{if not (eq $field.Type "headers.String" "headers.Metadata")}}
- if err := h.{{$field.Attribute}}().Validate(); err != nil {
+{{- range $field := $hmeta.Fields }}
+ if err := h.{{$field.Attribute}}().validate(); err != nil {
return err
}
-{{- end }}{{ end }}
+{{- end }}
return evadeGolintComplaint1()
}
{{- range $field := $hmeta.Fields }}
//{{$field.Attribute}} provides type-safe access to {{$field.Header}} headers.
-func (h {{$htype}}Headers) {{$field.Attribute}}() {{$field.Type}} {
- return {{$field.Type}}{
- Base: headers.Base{
- H: h,
- K: "{{$field.Header}}",
- },
- }
+func (h {{$htype}}Headers) {{$field.Attribute}}() Field{{$field.Type}} {
+ return Field{{$field.Type}}{h, "{{$field.Header}}"}
}
{{- end }}
{{- end }}
diff --git a/headers.go b/headers.go
index 9661ec0..1bc206f 100644
--- a/headers.go
+++ b/headers.go
@@ -46,3 +46,10 @@ func headersFromHTTP(src http.Header) map[string]string {
}
return h
}
+
+type headerInterface interface {
+ Clear(string)
+ Del(string)
+ Get(string) string
+ Set(string, string)
+}
diff --git a/headers/base.go b/headers/base.go
deleted file mode 100644
index 3b5b3ec..0000000
--- a/headers/base.go
+++ /dev/null
@@ -1,33 +0,0 @@
-/******************************************************************************
-*
-* Copyright 2018 Stefan Majewsky <majewsky@gmx.net>
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************************/
-
-package headers
-
-//Base is an implementation detail.
-type Base struct {
- H Interface
- K string
-}
-
-//Interface is an implementation detail.
-type Interface interface {
- Clear(string)
- Del(string)
- Get(string) string
- Set(string, string)
-}
diff --git a/headers/errors.go b/headers/errors.go
deleted file mode 100644
index 6c1f5ab..0000000
--- a/headers/errors.go
+++ /dev/null
@@ -1,31 +0,0 @@
-/******************************************************************************
-*
-* Copyright 2018 Stefan Majewsky <majewsky@gmx.net>
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************************/
-
-package headers
-
-//MalformedHeaderError is generated when a response from Swift contains a
-//malformed header.
-type MalformedHeaderError struct {
- Key string
- ParseError error
-}
-
-//Error implements the builtin/error interface.
-func (e MalformedHeaderError) Error() string {
- return "Bad header " + e.Key + ": " + e.ParseError.Error()
-}
diff --git a/headers/headers.go b/headers/headers.go
deleted file mode 100644
index 33127a8..0000000
--- a/headers/headers.go
+++ /dev/null
@@ -1,91 +0,0 @@
-/******************************************************************************
-*
-* Copyright 2018 Stefan Majewsky <majewsky@gmx.net>
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************************/
-
-//Package headers contains helper types for the type-safe representation of
-//headers on Swift accounts/containers/objects.
-package headers
-
-import (
- "net/http"
- "net/textproto"
-)
-
-//Headers works like http.Header, but does not allow multiple values per key.
-//
-//If you write the map directly, without using the provided methods, you must
-//normalize all keys with textproto.CanonicalMIMEHeaderKey(). Otherwise, the
-//results are undefined.
-type Headers map[string]string
-
-//Clear sets the value for the specified header to the empty string. When the
-//Headers instance is then sent to the server with Update(), the server will
-//delete the value for that header; cf. Del().
-func (h Headers) Clear(key string) {
- h.Set(key, "")
-}
-
-//Del deletes a key from the Headers instance. When the Headers instance
-//is then sent to the server with Update(), Del() has different effects
-//depending on context because of Swift's inconsistent API:
-//
-//For most writable attributes, a key which has been deleted with Del() will
-//remain unchanged on the server. To remove the key on the server, use Clear()
-//instead.
-//
-//For object metadata (but not other object attributes), deleting a key will
-//cause that key to be deleted on the server. Del() is identical to Clear() in
-//this case.
-func (h Headers) Del(key string) {
- k := textproto.CanonicalMIMEHeaderKey(key)
- delete(h, k)
-}
-
-//Get returns the value for the specified header.
-func (h Headers) Get(key string) string {
- if h == nil {
- return ""
- }
- k := textproto.CanonicalMIMEHeaderKey(key)
- return h[k]
-}
-
-//Set sets a new value for the specified header, possibly overwriting a
-//previous value.
-func (h Headers) Set(key, value string) {
- k := textproto.CanonicalMIMEHeaderKey(key)
- h[k] = value
-}
-
-//ToHTTP converts this map into a http.Header.
-func (h Headers) ToHTTP() http.Header {
- dest := make(http.Header, len(h))
- for k, v := range h {
- dest.Set(k, v)
- }
- return dest
-}
-
-//FromHTTP populates this map with the headers in the given http.Header. When a
-//header has multiple values, every value but the first one will be discarded.
-func (h Headers) FromHTTP(src http.Header) {
- for k, v := range src {
- if len(v) > 0 {
- h.Set(k, v[0])
- }
- }
-}
diff --git a/headers/headers_test.go b/headers/headers_test.go
deleted file mode 100644
index 9724435..0000000
--- a/headers/headers_test.go
+++ /dev/null
@@ -1,97 +0,0 @@
-/******************************************************************************
-*
-* Copyright 2018 Stefan Majewsky <majewsky@gmx.net>
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************************/
-
-package headers
-
-import "testing"
-
-func TestHeaders(t *testing.T) {
- h := make(Headers)
- h.Set("first", "value1")
- h.Set("second-thing", "value2")
-
- expectHeaders(t, h, map[string]string{
- "First": "value1",
- "Second-Thing": "value2",
- })
-
- expectString(t, h.Get("first"), "value1")
- expectString(t, h.Get("First"), "value1")
- expectString(t, h.Get("FIRST"), "value1")
-
- h.Set("first", "changed")
- h.Set("third", "")
-
- expectHeaders(t, h, map[string]string{
- "First": "changed",
- "Second-Thing": "value2",
- "Third": "",
- })
-
- h.Clear("second-thing")
- h.Clear("fourth-thing")
-
- expectHeaders(t, h, map[string]string{
- "First": "changed",
- "Second-Thing": "",
- "Third": "",
- "Fourth-Thing": "",
- })
-
- h.Del("FIRST")
- h.Del("second-Thing")
-
- expectHeaders(t, h, map[string]string{
- "Third": "",
- "Fourth-Thing": "",
- })
-
-}
-
-func expectString(t *testing.T, actual string, expected string) {
- t.Helper()
- if actual != expected {
- t.Errorf("expected value %q, got %q instead\n", expected, actual)
- }
-}
-
-func expectHeaders(t *testing.T, actual Headers, expected map[string]string) {
- t.Helper()
- reported := make(map[string]bool)
-
- for k, av := range actual {
- ev, exists := expected[k]
- if !exists {
- ev = "<not set>"
- }
- if av != ev {
- t.Errorf(`expected "%s: %s", got "%s: %s" instead`, k, ev, k, av)
- reported[k] = true
- }
- }
-
- for k, ev := range expected {
- av, exists := actual[k]
- if !exists {
- av = "<not set>"
- }
- if av != ev && !reported[k] {
- t.Errorf(`expected "%s: %s", got "%s: %s" instead`, k, ev, k, av)
- }
- }
-}