package disk import ( "io" "io/fs" "time" ) // File interface extends the fs.File interface to include io.Writer. // This is because the standard fs package is modeled after a read-only File // System, but we need to write to files as well. The standard os.File type will // satisfy this interface, as it implements both fs.File and io.Writer. type File interface { fs.File io.Writer } // Disk interface defines the methods for a disk abstraction layer. This allows // us to easily create mock disks for testing purposes, or to simulate different // levels of failure and latency in a simuated environment. type Disk interface { // Mkdir creates a directory with the specified name and permissions. Mkdir(name string, perm fs.FileMode) error // Create creates a new file with the specified name and returns a File interface. Create(name string) (File, error) // Stat retrieves the file information for the specified name, returning // fs.FileInfo and an error if any. Stat(name string) (fs.FileInfo, error) // Open opens an existing file with the specified name and returns a File interface. Open(name string) (File, error) // Remove deletes the file or directory with the specified name. Remove(name string) error } type MockDisk struct { MkdirFunc func(name string, perm fs.FileMode) error CreateFunc func(name string) (File, error) StatFunc func(name string) (fs.FileInfo, error) OpenFunc func(name string) (File, error) RemoveFunc func(name string) error } var _ Disk = &MockDisk{} func (t *MockDisk) Mkdir(name string, perm fs.FileMode) error { if t.MkdirFunc != nil { return t.MkdirFunc(name, perm) } return nil } func (t *MockDisk) Create(name string) (File, error) { if t.CreateFunc != nil { return t.CreateFunc(name) } return nil, nil } func (t *MockDisk) Stat(name string) (fs.FileInfo, error) { if t.StatFunc != nil { return t.StatFunc(name) } return nil, nil } func (t *MockDisk) Open(name string) (File, error) { if t.OpenFunc != nil { return t.OpenFunc(name) } return nil, nil } func (t *MockDisk) Remove(name string) error { if t.RemoveFunc != nil { return t.RemoveFunc(name) } return nil } type MockFileInfo struct { NameFunc func() string SizeFunc func() int64 IsDirFunc func() bool ModeFunc func() fs.FileMode ModTimeFunc func() fs.FileInfo SysFunc func() any } var _ fs.FileInfo = &MockFileInfo{} // IsDir implements fs.FileInfo. func (t *MockFileInfo) IsDir() bool { if t.IsDirFunc != nil { return t.IsDirFunc() } return false } // ModTime implements fs.FileInfo. func (t *MockFileInfo) ModTime() time.Time { if t.ModTimeFunc != nil { return t.ModTimeFunc().ModTime() } return time.Time{} } // Mode implements fs.FileInfo. func (t *MockFileInfo) Mode() fs.FileMode { if t.ModeFunc != nil { return t.ModeFunc() } return 0 } // Name implements fs.FileInfo. func (t *MockFileInfo) Name() string { if t.NameFunc != nil { return t.NameFunc() } return "" } // Size implements fs.FileInfo. func (t *MockFileInfo) Size() int64 { if t.SizeFunc != nil { return t.SizeFunc() } return 0 } // Sys implements fs.FileInfo. func (t *MockFileInfo) Sys() any { if t.SysFunc != nil { return t.SysFunc() } return nil }