package vfs import ( "bytes" "context" "io/fs" "path" "time" ) type MemoryFs struct { name string files map[string]*MemoryFile } var _ Filesystem = (*MemoryFs)(nil) // ModTime implements Filesystem. func (mfs *MemoryFs) ModTime() time.Time { return time.Time{} } // Mode implements Filesystem. func (mfs *MemoryFs) Mode() fs.FileMode { return fs.ModeDir } // Size implements Filesystem. func (fs *MemoryFs) Size() int64 { return 0 } // Sys implements Filesystem. func (fs *MemoryFs) Sys() any { return nil } // FsKind implements Filesystem. func (fs *MemoryFs) FsName() string { return "memoryfs" } // Info implements Filesystem. func (fs *MemoryFs) Info() (fs.FileInfo, error) { return NewDirInfo(fs.name), nil } // IsDir implements Filesystem. func (fs *MemoryFs) IsDir() bool { return true } // Name implements Filesystem. func (fs *MemoryFs) Name() string { return fs.name } // Type implements Filesystem. func (mfs *MemoryFs) Type() fs.FileMode { return fs.ModeDir } func NewMemoryFS(name string, files map[string]*MemoryFile) *MemoryFs { return &MemoryFs{ name: name, files: files, } } func (m *MemoryFs) Open(ctx context.Context, filename string) (File, error) { return GetFile(m.files, filename) } func (fs *MemoryFs) ReadDir(ctx context.Context, path string) ([]fs.DirEntry, error) { return ListDirFromFiles(fs.files, path) } // Stat implements Filesystem. func (mfs *MemoryFs) Stat(ctx context.Context, filename string) (fs.FileInfo, error) { file, ok := mfs.files[filename] if !ok { return nil, ErrNotExist } return NewFileInfo(path.Base(filename), file.Size()), nil } // Unlink implements Filesystem. func (fs *MemoryFs) Unlink(ctx context.Context, filename string) error { return ErrNotImplemented } var _ File = (*MemoryFile)(nil) type MemoryFile struct { name string data *bytes.Reader } func NewMemoryFile(name string, data []byte) *MemoryFile { return &MemoryFile{ name: name, data: bytes.NewReader(data), } } // Name implements File. func (d *MemoryFile) Name() string { return d.name } // Seek implements File. func (d *MemoryFile) Seek(offset int64, whence int) (int64, error) { return d.data.Seek(offset, whence) } // Type implements File. func (d *MemoryFile) Type() fs.FileMode { return ROMode } func (d *MemoryFile) Info() (fs.FileInfo, error) { return NewFileInfo(d.name, int64(d.data.Len())), nil } func (d *MemoryFile) Size() int64 { return int64(d.data.Len()) } func (d *MemoryFile) IsDir() bool { return false } func (d *MemoryFile) Close(ctx context.Context) (err error) { return } // Read implements File. func (d *MemoryFile) Read(ctx context.Context, p []byte) (n int, err error) { return d.data.Read(p) } // ReadAt implements File. func (d *MemoryFile) ReadAt(ctx context.Context, p []byte, off int64) (n int, err error) { return d.data.ReadAt(p, off) }