diff --git a/fs-absolute.go b/fs-absolute.go index 5d6a825..7782031 100644 --- a/fs-absolute.go +++ b/fs-absolute.go @@ -171,7 +171,7 @@ func (f *absoluteFS) Rename(from, to string) error { // (before umask). If successful, methods on the returned File can // be used for I/O; the associated file descriptor has mode O_RDWR. // If there is an error, it will be of type *PathError. -func (f *absoluteFS) Create(name string) (*os.File, error) { +func (f *absoluteFS) Create(name string) (fs.File, error) { return os.Create(name) } diff --git a/fs-relative.go b/fs-relative.go index c2b59b1..5b59a95 100644 --- a/fs-relative.go +++ b/fs-relative.go @@ -359,7 +359,7 @@ func NewWriteFileFS(rel Rel) WriteFileFS { // the fly wether a call to Create is on a override basis or not. This decision // has to be made at the point of creating the file system. This is less // flexible and just results in friction, but this is out of our power. -func (f *writeFileFS) Create(name string) (*os.File, error) { +func (f *writeFileFS) Create(name string) (fs.File, error) { if !fs.ValidPath(name) { return nil, NewInvalidPathError("Create", name) } diff --git a/luna/mem-fs.go b/luna/mem-fs.go index f659704..8c4cc6b 100644 --- a/luna/mem-fs.go +++ b/luna/mem-fs.go @@ -1,10 +1,12 @@ package luna import ( + "io" "io/fs" "os" "strings" "testing/fstest" + "time" nef "github.com/snivilised/nefilim" lab "github.com/snivilised/nefilim/internal/laboratory" @@ -44,22 +46,15 @@ func (f *MemFS) DirectoryExists(name string) bool { return false } -func (f *MemFS) Create(name string) (*os.File, error) { +func (f *MemFS) Create(name string) (fs.File, error) { if _, err := f.Stat(name); err == nil { return nil, fs.ErrExist } - file := &fstest.MapFile{ - Mode: lab.Perms.File, - } - - f.MapFS[name] = file - // TODO: this needs a resolution using a file interface - // rather than using os.File which is a struct not an - // interface - dummy := &os.File{} + adapter := &FileAdapter{name: name} + f.MapFS[name] = &fstest.MapFile{Data: adapter.data} - return dummy, nil + return adapter, nil } func (f *MemFS) MakeDir(name string, perm os.FileMode) error { @@ -176,3 +171,72 @@ func (f *MemFS) WriteFile(name string, data []byte, perm os.FileMode) error { return nil } + +// File + +type FileInfoAdapter struct { + name string + size int64 + dir bool +} + +func (fi *FileInfoAdapter) Name() string { + return fi.name +} + +func (fi *FileInfoAdapter) Size() int64 { + return fi.size +} + +func (fi *FileInfoAdapter) Mode() os.FileMode { + return lab.Perms.File +} + +func (fi *FileInfoAdapter) ModTime() time.Time { + var t time.Time + return t +} + +func (fi *FileInfoAdapter) IsDir() bool { + return fi.dir +} + +func (fi *FileInfoAdapter) Sys() interface{} { + return nil +} + +type FileAdapter struct { + name string + data []byte + pos int64 +} + +func (f *FileAdapter) Read(p []byte) (n int, err error) { + if f.pos >= int64(len(f.data)) { + return 0, io.EOF + } + + n = copy(p, f.data[f.pos:]) + f.pos += int64(n) + + return n, nil +} + +func (f *FileAdapter) Write(p []byte) (n int, err error) { + f.data = append(f.data[:f.pos], p...) + n = len(p) + f.pos += int64(n) + + return n, nil +} + +func (f *FileAdapter) Close() error { + return nil +} + +func (f *FileAdapter) Stat() (os.FileInfo, error) { + return &FileInfoAdapter{ + name: f.name, + size: int64(len(f.data)), + }, nil +} diff --git a/nefilim-defs.go b/nefilim-defs.go index 72c35f7..123550b 100644 --- a/nefilim-defs.go +++ b/nefilim-defs.go @@ -123,7 +123,7 @@ type ( // WriteFileFS file system non streaming writer WriteFileFS interface { // Create creates or truncates the named file. - Create(name string) (*os.File, error) + Create(name string) (fs.File, error) // Write writes file at path, to file system specified WriteFile(name string, data []byte, perm os.FileMode) error }