1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
package objectapi
import (
"context"
"errors"
"time"
)
// Object is meant to be a domain object for a theoretical object store.
type Object struct {
Key string
Value string
Access time.Time
}
// Client is meant to model an SDK client for a theoretical object store API.
// Because we're only using it for demo purposes, it embeds a mock server with
// fixed data.
type Client struct {
token string
server *mockServer
}
// NewClient is meant to model a constructor for the SDK client.
func NewClient(token string) (*Client, error) {
return &Client{
token: token,
server: newMockServer(),
}, nil
}
// Create is some bit of functionality.
func (c *Client) Create(ctx context.Context, key, value string, overwrite bool) error {
return c.server.create(c.token, key, value, overwrite)
}
// Delete is some bit of functionality.
func (c *Client) Delete(ctx context.Context, key string, force bool) (existed bool, err error) {
return c.server.delete(c.token, key, force)
}
// List is some bit of functionality.
func (c *Client) List(ctx context.Context) ([]Object, error) {
return c.server.list(c.token)
}
//
//
//
type mockServer struct {
token string
objects map[string]Object
}
func newMockServer() *mockServer {
return &mockServer{
token: "SECRET",
objects: defaultObjects,
}
}
func (s *mockServer) create(token, key, value string, overwrite bool) error {
if token != s.token {
return errors.New("not authorized")
}
if _, ok := s.objects[key]; ok && !overwrite {
return errors.New("object already exists")
}
s.objects[key] = Object{
Key: key,
Value: value,
Access: time.Now(),
}
return nil
}
func (s *mockServer) delete(token, key string, force bool) (existed bool, err error) {
if token != s.token {
return false, errors.New("not authorized")
}
_, ok := s.objects[key]
delete(s.objects, key)
return ok, nil
}
func (s *mockServer) list(token string) ([]Object, error) {
if token != s.token {
return nil, errors.New("not authorized")
}
result := make([]Object, 0, len(s.objects))
for _, obj := range s.objects {
result = append(result, obj)
}
return result, nil
}
var defaultObjects = map[string]Object{
"apple": {
Key: "apple",
Value: "The fruit of any of certain other species of tree of the same genus.",
Access: mustParseTime(time.RFC3339, "2019-03-15T15:01:00Z"),
},
"beach": {
Key: "beach",
Value: "The shore of a body of water, especially when sandy or pebbly.",
Access: mustParseTime(time.RFC3339, "2019-04-20T12:21:30Z"),
},
"carillon": {
Key: "carillon",
Value: "A stationary set of chromatically tuned bells in a tower.",
Access: mustParseTime(time.RFC3339, "2019-07-04T23:59:59Z"),
},
}
func mustParseTime(layout string, value string) time.Time {
t, err := time.Parse(layout, value)
if err != nil {
panic(err)
}
return t
}
|