package vfs import ( "context" "errors" "io/fs" "path" "time" "github.com/royalcat/ctxio" ) type File interface { IsDir() bool Size() int64 fs.DirEntry ctxio.Reader ctxio.ReaderAt ctxio.Closer ctxio.Seeker } var ErrNotImplemented = errors.New("not implemented") type Filesystem interface { // Open opens the named file for reading. If successful, methods on the // returned file can be used for reading; the associated file descriptor has // mode O_RDONLY. Open(ctx context.Context, filename string) (File, error) // ReadDir reads the directory named by dirname and returns a list of // directory entries. ReadDir(ctx context.Context, path string) ([]fs.DirEntry, error) Stat(ctx context.Context, filename string) (fs.FileInfo, error) Unlink(ctx context.Context, filename string) error Rename(ctx context.Context, oldpath, newpath string) error // As filesystem mounted to some path, make sense to have the filesystem implement DirEntry fs.DirEntry } // readonly const ROMode = fs.FileMode(0555) type fileInfo struct { name string size int64 isDir bool } var _ fs.FileInfo = &fileInfo{} var _ fs.DirEntry = &fileInfo{} func NewDirInfo(name string) *fileInfo { return &fileInfo{ name: path.Base(name), size: 0, isDir: true, } } func NewFileInfo(name string, size int64) *fileInfo { return &fileInfo{ name: path.Base(name), size: size, isDir: false, } } func (fi *fileInfo) Info() (fs.FileInfo, error) { return fi, nil } func (fi *fileInfo) Type() fs.FileMode { if fi.isDir { return fs.ModeDir } return 0 } func (fi *fileInfo) Name() string { return fi.name } func (fi *fileInfo) Size() int64 { return fi.size } func (fi *fileInfo) Mode() fs.FileMode { if fi.isDir { return ROMode | fs.ModeDir } return ROMode } func (fi *fileInfo) ModTime() time.Time { // TODO fix it return time.Time{} } func (fi *fileInfo) IsDir() bool { return fi.isDir } func (fi *fileInfo) Sys() interface{} { return nil } type FilesystemPrototype string // Info implements Filesystem. func (p FilesystemPrototype) Info() (fs.FileInfo, error) { return NewDirInfo(string(p)), nil } // IsDir implements Filesystem. func (p FilesystemPrototype) IsDir() bool { return true } // Name implements Filesystem. func (p FilesystemPrototype) Name() string { return string(p) } // Type implements Filesystem. func (p FilesystemPrototype) Type() fs.FileMode { return fs.ModeDir }