diff --git a/file.go b/file.go index 693baab..6e6a249 100644 --- a/file.go +++ b/file.go @@ -13,13 +13,8 @@ var ( ErrNotSupported = errors.New("operation not supported") ) -// File is an interface that provides functionality for handling -// files/directories as values that can be supplied to commands. For -// directories, child files are accessed serially by calling `NextFile()` -// -// Read/Seek methods are only valid for files -// NextFile method is only valid for directories -type File interface { +// Node is a common interface for files, directories and other special files +type Node interface { io.Closer // Size returns size of this file (if this file is a directory, total size of @@ -28,9 +23,9 @@ type File interface { Size() (int64, error) } -// Regular represents a regular Unix file -type Regular interface { - File +// Node represents a regular Unix file +type File interface { + Node io.Reader io.Seeker @@ -38,18 +33,18 @@ type Regular interface { // DirEntry exposes information about a directory entry type DirEntry interface { - // Name returns the base name of this entry, which is the base name of - // the referenced file + // Name returns base name of this entry, which is the base name of referenced + // file Name() string - // File returns the file referenced by this DirEntry - File() File + // Node returns the file referenced by this DirEntry + Node() Node - // Regular is an alias for ent.File().(Regular). If the file isn't a regular + // File is an alias for ent.Node().(File). If the file isn't a regular // file, nil value will be returned - Regular() Regular + File() File - // Dir is an alias for ent.File().(directory). If the file isn't a directory, + // Dir is an alias for ent.Node().(directory). If the file isn't a directory, // nil value will be returned Dir() Directory } @@ -63,18 +58,18 @@ type DirIterator interface { // to Next() and after Next() returned false may result in undefined behavior DirEntry - // Next advances the iterator to the next file. + // Next advances iterator to the next file. Next() bool - // Err may return an error after the previous call to Next() returned `false`. - // If the previous call to Next() returned `true`, Err() is guaranteed to + // Err may return an error after previous call to Next() returned `false`. + // If previous call to Next() returned `true`, Err() is guaranteed to // return nil Err() error } // Directory is a special file which can link to any number of files. type Directory interface { - File + Node // Entries returns a stateful iterator over directory entries. // @@ -83,7 +78,7 @@ type Directory interface { // it := dir.Entries() // for it.Next() { // name := it.Name() - // file := it.File() + // file := it.Node() // [...] // } // if it.Err() != nil { @@ -105,7 +100,7 @@ type Directory interface { // FileInfo exposes information on files in local filesystem type FileInfo interface { - File + Node // AbsPath returns full real file path. AbsPath() string diff --git a/file_test.go b/file_test.go index cbf227c..8fa2a87 100644 --- a/file_test.go +++ b/file_test.go @@ -25,7 +25,7 @@ func TestSliceFiles(t *testing.T) { if !it.Next() { t.Fatal("Expected a file") } - rf := it.Regular() + rf := it.File() if rf == nil { t.Fatal("Expected a regular file") } @@ -104,7 +104,7 @@ anotherfile if mpf == nil || err != nil { t.Fatal("Expected non-nil MultipartFile, nil error") } - mf, ok := mpf.(Regular) + mf, ok := mpf.(File) if !ok { t.Fatal("Expected file to not be a directory") } @@ -147,7 +147,7 @@ anotherfile if mpf == nil || err != nil { t.Fatal("Expected non-nil MultipartFile, nil error") } - mf, ok = mpf.(Regular) + mf, ok = mpf.(File) if !ok { t.Fatal("Expected file to not be a directory") } diff --git a/is_hidden.go b/is_hidden.go index d5bc886..4ebca60 100644 --- a/is_hidden.go +++ b/is_hidden.go @@ -7,7 +7,7 @@ import ( "strings" ) -func IsHidden(name string, f File) bool { +func IsHidden(name string, f Node) bool { fName := filepath.Base(name) if strings.HasPrefix(fName, ".") && len(fName) > 1 { diff --git a/is_hidden_windows.go b/is_hidden_windows.go index 6f9568a..7419f93 100644 --- a/is_hidden_windows.go +++ b/is_hidden_windows.go @@ -9,7 +9,7 @@ import ( windows "golang.org/x/sys/windows" ) -func IsHidden(name string, f File) bool { +func IsHidden(name string, f Node) bool { fName := filepath.Base(name) diff --git a/linkfile.go b/linkfile.go index df334d5..11f7c92 100644 --- a/linkfile.go +++ b/linkfile.go @@ -13,7 +13,7 @@ type Symlink struct { reader io.Reader } -func NewLinkFile(target string, stat os.FileInfo) Regular { +func NewLinkFile(target string, stat os.FileInfo) File { return &Symlink{ Target: target, stat: stat, @@ -45,4 +45,4 @@ func (lf *Symlink) Size() (int64, error) { return 0, ErrNotSupported } -var _ Regular = &Symlink{} +var _ File = &Symlink{} diff --git a/multifilereader.go b/multifilereader.go index 8817ad8..f5f35b4 100644 --- a/multifilereader.go +++ b/multifilereader.go @@ -11,7 +11,7 @@ import ( "sync" ) -// MultiFileReader reads from a `commands.File` (which can be a directory of files +// MultiFileReader reads from a `commands.Node` (which can be a directory of files // or a regular file) as HTTP multipart encoded data. type MultiFileReader struct { io.Reader @@ -20,7 +20,7 @@ type MultiFileReader struct { files []DirIterator path []string - currentFile File + currentFile Node buf bytes.Buffer mpWriter *multipart.Writer closed bool @@ -86,7 +86,7 @@ func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) { // handle starting a new file part if !mfr.closed { - mfr.currentFile = entry.File() + mfr.currentFile = entry.Node() // write the boundary and headers header := make(textproto.MIMEHeader) @@ -95,7 +95,7 @@ func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) { var contentType string - switch f := entry.File().(type) { + switch f := entry.Node().(type) { case *Symlink: contentType = "application/symlink" case Directory: @@ -107,7 +107,7 @@ func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) { mfr.files = append(mfr.files, newIt) mfr.path = append(mfr.path, entry.Name()) contentType = "application/x-directory" - case Regular: + case File: // otherwise, use the file as a reader to read its contents contentType = "application/octet-stream" default: @@ -115,7 +115,7 @@ func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) { } header.Set("Content-Type", contentType) - if rf, ok := entry.File().(FileInfo); ok { + if rf, ok := entry.Node().(FileInfo); ok { header.Set("abspath", rf.AbsPath()) } @@ -133,7 +133,7 @@ func (mfr *MultiFileReader) Read(buf []byte) (written int, err error) { // otherwise, read from file data switch f := mfr.currentFile.(type) { - case Regular: + case File: written, err = f.Read(buf) if err != io.EOF { return written, err diff --git a/multifilereader_test.go b/multifilereader_test.go index dd7dac9..a3cf1ee 100644 --- a/multifilereader_test.go +++ b/multifilereader_test.go @@ -94,7 +94,7 @@ func TestOutput(t *testing.T) { if mpf == nil || err != nil { t.Fatal("Expected non-nil MultipartFile, nil error") } - mpr, ok := mpf.(Regular) + mpr, ok := mpf.(File) if !ok { t.Fatal("Expected file to be a regular file") } @@ -132,7 +132,7 @@ func TestOutput(t *testing.T) { if child == nil || err != nil { t.Fatal("Expected to be able to read a child file") } - if _, ok := child.(Regular); !ok { + if _, ok := child.(File); !ok { t.Fatal("Expected file to not be a directory") } if cname != "a.txt" { @@ -147,7 +147,7 @@ func TestOutput(t *testing.T) { if child == nil || err != nil { t.Fatal("Expected to be able to read a child file") } - if _, ok := child.(Regular); !ok { + if _, ok := child.(File); !ok { t.Fatal("Expected file to not be a directory") } if cname != "b.txt" { diff --git a/multipartfile.go b/multipartfile.go index be7e221..1552543 100644 --- a/multipartfile.go +++ b/multipartfile.go @@ -22,17 +22,17 @@ const ( var ErrPartOutsideParent = errors.New("file outside parent dir") -// MultipartFile implements File, and is created from a `multipart.Part`. +// MultipartFile implements Node, and is created from a `multipart.Part`. // It can be either a directory or file (checked by calling `IsDirectory()`). type MultipartFile struct { - File + Node Part *multipart.Part Reader PartReader Mediatype string } -func NewFileFromPartReader(reader *multipart.Reader, mediatype string) (File, error) { +func NewFileFromPartReader(reader *multipart.Reader, mediatype string) (Node, error) { if !isDirectory(mediatype) { return nil, ErrNotDirectory } @@ -45,7 +45,7 @@ func NewFileFromPartReader(reader *multipart.Reader, mediatype string) (File, er return f, nil } -func newFileFromPart(parent string, part *multipart.Part, reader PartReader) (string, File, error) { +func newFileFromPart(parent string, part *multipart.Part, reader PartReader) (string, Node, error) { f := &MultipartFile{ Part: part, Reader: reader, @@ -97,7 +97,7 @@ func isDirectory(mediatype string) bool { type multipartIterator struct { f *MultipartFile - curFile File + curFile Node curName string err error } @@ -106,11 +106,11 @@ func (it *multipartIterator) Name() string { return it.curName } -func (it *multipartIterator) File() File { +func (it *multipartIterator) File() Node { return it.curFile } -func (it *multipartIterator) Regular() Regular { +func (it *multipartIterator) Regular() File { return castRegular(it.File()) } diff --git a/readerfile.go b/readerfile.go index 7db7e96..261273c 100644 --- a/readerfile.go +++ b/readerfile.go @@ -14,7 +14,7 @@ type ReaderFile struct { stat os.FileInfo } -func NewReaderFile(reader io.ReadCloser, stat os.FileInfo) Regular { +func NewReaderFile(reader io.ReadCloser, stat os.FileInfo) File { return &ReaderFile{"", reader, stat} } @@ -58,5 +58,5 @@ func (f *ReaderFile) Seek(offset int64, whence int) (int64, error) { return 0, ErrNotSupported } -var _ Regular = &ReaderFile{} +var _ File = &ReaderFile{} var _ FileInfo = &ReaderFile{} diff --git a/serialfile.go b/serialfile.go index 77afafa..cbfecc2 100644 --- a/serialfile.go +++ b/serialfile.go @@ -10,7 +10,7 @@ import ( "strings" ) -// serialFile implements File, and reads from a path on the OS filesystem. +// serialFile implements Node, and reads from a path on the OS filesystem. // No more than one file will be opened at a time (directories will advance // to the next file when NextFile() is called). type serialFile struct { @@ -26,13 +26,13 @@ type serialIterator struct { path string curName string - curFile File + curFile Node err error } // TODO: test/document limitations -func NewSerialFile(path string, hidden bool, stat os.FileInfo) (File, error) { +func NewSerialFile(path string, hidden bool, stat os.FileInfo) (Node, error) { switch mode := stat.Mode(); { case mode.IsRegular(): file, err := os.Open(path) @@ -63,11 +63,11 @@ func (it *serialIterator) Name() string { return it.curName } -func (it *serialIterator) File() File { +func (it *serialIterator) File() Node { return it.curFile } -func (it *serialIterator) Regular() Regular { +func (it *serialIterator) Regular() File { return castRegular(it.File()) } @@ -121,7 +121,7 @@ func (f *serialFile) Entries() (DirIterator, error) { }, nil } -func (f *serialFile) NextFile() (string, File, error) { +func (f *serialFile) NextFile() (string, Node, error) { // if there aren't any files left in the root directory, we're done if len(f.files) == 0 { return "", nil, io.EOF @@ -182,12 +182,12 @@ func (f *serialFile) Size() (int64, error) { return du, err } -func castRegular(f File) Regular { - r, _ := f.(Regular) +func castRegular(f Node) File { + r, _ := f.(File) return r } -func castDir(f File) Directory { +func castDir(f Node) Directory { d, _ := f.(Directory) return d } diff --git a/slicefile.go b/slicefile.go index 62c299f..ddc2632 100644 --- a/slicefile.go +++ b/slicefile.go @@ -2,18 +2,18 @@ package files type fileEntry struct { name string - file File + file Node } func (e fileEntry) Name() string { return e.name } -func (e fileEntry) File() File { +func (e fileEntry) File() Node { return e.file } -func (e fileEntry) Regular() Regular { +func (e fileEntry) Regular() File { return castRegular(e.file) } @@ -21,7 +21,7 @@ func (e fileEntry) Dir() Directory { return castDir(e.file) } -func FileEntry(name string, file File) DirEntry { +func FileEntry(name string, file Node) DirEntry { return fileEntry{ name: name, file: file, @@ -37,12 +37,12 @@ func (it *sliceIterator) Name() string { return it.files[it.n].Name() } -func (it *sliceIterator) File() File { - return it.files[it.n].File() +func (it *sliceIterator) File() Node { + return it.files[it.n].Node() } -func (it *sliceIterator) Regular() Regular { - return it.files[it.n].Regular() +func (it *sliceIterator) Regular() File { + return it.files[it.n].File() } func (it *sliceIterator) Dir() Directory { @@ -58,8 +58,8 @@ func (it *sliceIterator) Err() error { return nil } -// SliceFile implements File, and provides simple directory handling. -// It contains children files, and is created from a `[]File`. +// SliceFile implements Node, and provides simple directory handling. +// It contains children files, and is created from a `[]Node`. // SliceFiles are always directories, and can't be read from or closed. type SliceFile struct { files []DirEntry @@ -85,7 +85,7 @@ func (f *SliceFile) Size() (int64, error) { var size int64 for _, file := range f.files { - s, err := file.File().Size() + s, err := file.Node().Size() if err != nil { return 0, err } diff --git a/webfile.go b/webfile.go index c8e930a..6c1cc3f 100644 --- a/webfile.go +++ b/webfile.go @@ -61,4 +61,4 @@ func (wf *WebFile) Size() (int64, error) { return wf.contentLength, nil } -var _ Regular = &WebFile{} +var _ File = &WebFile{}