/
mockfs.go
131 lines (113 loc) · 3.23 KB
/
mockfs.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
package mockfs
import (
"context"
"errors"
"fmt"
"io"
"path"
"time"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/hash"
)
// Fs is a minimal mock Fs
type Fs struct {
name string // the name of the remote
root string // The root directory (OS path)
features *fs.Features // optional features
rootDir fs.DirEntries // directory listing of root
}
// ErrNotImplemented is returned by unimplemented methods
var ErrNotImplemented = errors.New("not implemented")
// NewFs returns a new mock Fs
func NewFs(name, root string) *Fs {
f := &Fs{
name: name,
root: root,
}
f.features = (&fs.Features{}).Fill(f)
return f
}
// AddObject adds an Object for List to return
// Only works for the root for the moment
func (f *Fs) AddObject(o fs.Object) {
f.rootDir = append(f.rootDir, o)
// Make this object part of mockfs if possible
do, ok := o.(interface{ SetFs(f fs.Fs) })
if ok {
do.SetFs(f)
}
}
// Name of the remote (as passed into NewFs)
func (f *Fs) Name() string {
return f.name
}
// Root of the remote (as passed into NewFs)
func (f *Fs) Root() string {
return f.root
}
// String returns a description of the FS
func (f *Fs) String() string {
return fmt.Sprintf("Mock file system at %s", f.root)
}
// Precision of the ModTimes in this Fs
func (f *Fs) Precision() time.Duration {
return time.Second
}
// Hashes returns the supported hash types of the filesystem
func (f *Fs) Hashes() hash.Set {
return hash.NewHashSet()
}
// Features returns the optional features of this Fs
func (f *Fs) Features() *fs.Features {
return f.features
}
// List the objects and directories in dir into entries. The
// entries can be returned in any order but should be for a
// complete directory.
//
// dir should be "" to list the root, and should not have
// trailing slashes.
//
// This should return ErrDirNotFound if the directory isn't
// found.
func (f *Fs) List(ctx context.Context, dir string) (entries fs.DirEntries, err error) {
if dir == "" {
return f.rootDir, nil
}
return entries, fs.ErrorDirNotFound
}
// NewObject finds the Object at remote. If it can't be found
// it returns the error ErrorObjectNotFound.
func (f *Fs) NewObject(ctx context.Context, remote string) (fs.Object, error) {
dirPath := path.Dir(remote)
if dirPath == "" || dirPath == "." {
for _, entry := range f.rootDir {
if entry.Remote() == remote {
return entry.(fs.Object), nil
}
}
}
return nil, fs.ErrorObjectNotFound
}
// Put in to the remote path with the modTime given of the given size
//
// May create the object even if it returns an error - if so
// will return the object and the error, otherwise will return
// nil and the error
func (f *Fs) Put(ctx context.Context, in io.Reader, src fs.ObjectInfo, options ...fs.OpenOption) (fs.Object, error) {
return nil, ErrNotImplemented
}
// Mkdir makes the directory (container, bucket)
//
// Shouldn't return an error if it already exists
func (f *Fs) Mkdir(ctx context.Context, dir string) error {
return ErrNotImplemented
}
// Rmdir removes the directory (container, bucket) if empty
//
// Return an error if it doesn't exist or isn't empty
func (f *Fs) Rmdir(ctx context.Context, dir string) error {
return ErrNotImplemented
}
// Assert it is the correct type
var _ fs.Fs = (*Fs)(nil)