Files
cgofuse/fs/fs.go
Matheus Sampaio Queiroga 9a774478a2
All checks were successful
Fuse test / go-test (push) Successful in 32s
Merge winfsp to fuse and update fs
Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
2025-08-18 19:07:05 -03:00

169 lines
5.9 KiB
Go

// Package fs provides generic interfaces and types for file and filesystem operations,
// abstracting over different file implementations and enabling flexible filesystem backends.
//
// The File interface defines a set of methods for file operations, including reading, writing,
// seeking, directory reading, file statistics, synchronization, and truncation.
//
// The FileSystem interface is a generic interface for filesystem operations, parameterized by a File type.
// It includes methods for opening files, creating directories, retrieving file statistics, renaming,
// removing files, and reading directory entries.
//
// Additional interfaces are provided for extended filesystem operations, such as unlinking, removing directories,
// creating links and symlinks, reading symlinks, changing permissions and ownership, and checking access permissions.
//
// The FileSystemMount interface abstracts mounting and unmounting of filesystems, providing access to the underlying FileSystem.
package fs
import (
"context"
"io"
"io/fs"
"iter"
"os"
"sync"
"time"
)
type File interface {
io.ReadWriteCloser
io.ReaderAt
io.WriterAt
io.Seeker
ReadDir(count int) ([]fs.DirEntry, error)
Stat() (fs.FileInfo, error)
Sync() error
Truncate(size int64) error
}
type FileSystem[F File] interface {
OpenFile(name string, flag int, perm fs.FileMode) (F, error)
Mkdir(name string, perm fs.FileMode) error
Stat(name string) (fs.FileInfo, error)
Rename(source, target string) error
Remove(name string) error
ReadDir(name string) ([]fs.DirEntry, error)
}
type FileSystemMount[T File, F FileSystem[T]] interface {
Mount(context.Context) error // Mount filesystem
Done() // Wait unmount
SetOption(...any) // Set option to fuse or winfsp
}
type FileSystemInitDestroy interface {
Init()
Destroy()
}
type FileSystemUnlink interface {
Unlink(name string) error
}
type FileSystemRmdir interface {
Rmdir(name string) error
}
type FileSystemLink interface {
Link(oldpath string, newpath string) error
}
type FileSystemSymlink interface {
Symlink(target string, newpath string) error
}
type FileSystemReadlink interface {
Readlink(string) (string, error)
}
type FileSystemChmod interface {
Chmod(name string, perm fs.FileMode) error
}
type FileSystemChown interface {
Chown(name string, uid, gid int) error
}
type FileSystemAccess interface {
Access(path string, mode uint32) error
}
type FileSystemStatFS interface {
Statfs(path string) (total, free uint64, err error)
}
type FileSystemUtimens interface {
Utimens(path string, access, modification time.Time) error
}
var (
_ FileSystem[*os.File] = (*fileAssert)(nil)
_ FileSystemLink = (*fileAssert)(nil)
_ FileSystemSymlink = (*fileAssert)(nil)
_ FileSystemReadlink = (*fileAssert)(nil)
_ FileSystemChmod = (*fileAssert)(nil)
_ FileSystemChown = (*fileAssert)(nil)
_ FileSystemUnlink = (*fileAssert)(nil)
_ FileSystemRmdir = (*fileAssert)(nil)
_ FileSystemAccess = (*fileAssert)(nil)
_ = New("", (*fileAssert)(nil))
)
type fileAssert struct{}
func (*fileAssert) Unlink(name string) error { return nil }
func (*fileAssert) Rmdir(name string) error { return nil }
func (*fileAssert) Access(path string, mode uint32) error { return nil }
func (*fileAssert) Chmod(name string, perm fs.FileMode) error { return nil }
func (*fileAssert) Chown(name string, uid, gid int) error { return nil }
func (*fileAssert) Link(oldname string, newname string) error { return nil }
func (*fileAssert) Mkdir(name string, perm fs.FileMode) error { return nil }
func (*fileAssert) MkdirAll(name string, perm fs.FileMode) error { return nil }
func (*fileAssert) Remove(name string) error { return nil }
func (*fileAssert) RemoveAll(name string) error { return nil }
func (*fileAssert) Rename(oldpath, newpath string) error { return nil }
func (*fileAssert) Symlink(oldname string, newname string) error { return nil }
func (*fileAssert) Truncate(name string, size int64) error { return nil }
func (*fileAssert) WriteFile(name string, data []byte, perm fs.FileMode) error { return nil }
func (*fileAssert) Create(name string) (*os.File, error) { return nil, nil }
func (*fileAssert) Lstat(name string) (stat fs.FileInfo, err error) { return nil, nil }
func (*fileAssert) Open(name string) (file *os.File, err error) { return nil, nil }
func (*fileAssert) ReadDir(name string) ([]fs.DirEntry, error) { return nil, nil }
func (*fileAssert) ReadFile(name string) ([]byte, error) { return nil, nil }
func (*fileAssert) Stat(name string) (stat fs.FileInfo, err error) { return nil, nil }
func (*fileAssert) Readlink(name string) (string, error) { return "", nil }
func (*fileAssert) OpenFile(name string, flags int, perm fs.FileMode) (*os.File, error) {
return nil, nil
}
type mapSync[K, V any] sync.Map
func (m *mapSync[K, V]) Store(key K, value V) { (*sync.Map)(m).Store(key, value) }
func (m *mapSync[K, V]) Delete(key K) { (*sync.Map)(m).Delete(key) }
func (m *mapSync[K, V]) LoadAndDelete(key K) (value V, loaded bool) {
v, l := (*sync.Map)(m).LoadAndDelete(key)
if v == nil {
return *new(V), l
}
return v.(V), l
}
func (m *mapSync[K, V]) Load(key K) (V, bool) {
v, k := (*sync.Map)(m).Load(key)
if v == nil {
return *new(V), k
}
return v.(V), k
}
func (m *mapSync[K, V]) Range(f func(key K, value V) bool) {
(*sync.Map)(m).Range(func(key, value any) bool {
if k, ok := key.(K); ok {
if v, ok := value.(V); ok {
return f(k, v)
}
}
return true
})
}
func (m *mapSync[K, V]) Seq() iter.Seq2[K, V] {
if m != nil {
return func(yield func(K, V) bool) {
m.Range(yield)
}
}
return nil
}