-
Notifications
You must be signed in to change notification settings - Fork 67
/
router.go
140 lines (122 loc) · 2.74 KB
/
router.go
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
129
130
131
132
133
134
135
136
137
138
139
140
package storage
import (
"context"
"fmt"
"io"
)
type Scheme string
const (
FileScheme Scheme = "file"
StdioScheme Scheme = "stdio"
HTTPScheme Scheme = "http"
HTTPSScheme Scheme = "https"
S3Scheme Scheme = "s3"
)
// Router is an Engine that routes each function call to the correct sub-Engine
// based off the provided URI's scheme and its enablement.
type Router struct {
engines map[Scheme]Engine
}
var _ Engine = (*Router)(nil)
func NewRouter() *Router {
return &Router{
engines: make(map[Scheme]Engine),
}
}
func (r *Router) Enable(scheme Scheme) {
var engine Engine
switch scheme {
case FileScheme:
engine = NewFileSystem()
case StdioScheme:
engine = NewStdioEngine()
case HTTPScheme, HTTPSScheme:
engine = NewHTTP()
case S3Scheme:
engine = NewS3()
default:
panic(fmt.Sprintf("storage.Router.Enable(): unknown scheme: %q", scheme))
}
r.engines[scheme] = engine
}
func (r *Router) lookup(u *URI) (Engine, error) {
scheme := getScheme(u)
engine, ok := r.engines[scheme]
if !ok {
if !knownScheme(scheme) {
return nil, fmt.Errorf("unknown scheme %q", scheme)
}
return nil, fmt.Errorf("scheme %q not allowed", scheme)
}
return engine, nil
}
func (r *Router) Get(ctx context.Context, u *URI) (Reader, error) {
engine, err := r.lookup(u)
if err != nil {
return nil, err
}
return engine.Get(ctx, u)
}
func (r *Router) Put(ctx context.Context, u *URI) (io.WriteCloser, error) {
engine, err := r.lookup(u)
if err != nil {
return nil, err
}
return engine.Put(ctx, u)
}
func (r *Router) PutIfNotExists(ctx context.Context, u *URI, b []byte) error {
engine, err := r.lookup(u)
if err != nil {
return err
}
return engine.PutIfNotExists(ctx, u, b)
}
func (r *Router) Delete(ctx context.Context, u *URI) error {
engine, err := r.lookup(u)
if err != nil {
return err
}
return engine.Delete(ctx, u)
}
func (r *Router) DeleteByPrefix(ctx context.Context, u *URI) error {
engine, err := r.lookup(u)
if err != nil {
return err
}
return engine.DeleteByPrefix(ctx, u)
}
func (r *Router) Size(ctx context.Context, u *URI) (int64, error) {
engine, err := r.lookup(u)
if err != nil {
return 0, err
}
return engine.Size(ctx, u)
}
func (r *Router) Exists(ctx context.Context, u *URI) (bool, error) {
engine, err := r.lookup(u)
if err != nil {
return false, err
}
return engine.Exists(ctx, u)
}
func (r *Router) List(ctx context.Context, u *URI) ([]Info, error) {
engine, err := r.lookup(u)
if err != nil {
return nil, err
}
return engine.List(ctx, u)
}
func getScheme(u *URI) Scheme {
if u.Scheme == "" {
return FileScheme
}
return Scheme(u.Scheme)
}
func knownScheme(s Scheme) bool {
switch s {
case FileScheme, StdioScheme, HTTPScheme, HTTPSScheme, S3Scheme:
return true
default:
return false
}
}