diff --git a/fs/dir.go b/fs/dir.go index c55bcea23..5830c6f38 100644 --- a/fs/dir.go +++ b/fs/dir.go @@ -7,6 +7,7 @@ import ( // Dir describes an unspecialized directory for directory/container/bucket lists type Dir struct { + f Info // Fs this directory is part of remote string // name of the directory modTime time.Time // modification or creation time - IsZero for unknown size int64 // size of directory and contents or -1 if unknown @@ -20,6 +21,7 @@ type Dir struct { // If the modTime is unknown pass in time.Time{} func NewDir(remote string, modTime time.Time) *Dir { return &Dir{ + f: Unknown, remote: remote, modTime: modTime, size: -1, @@ -30,6 +32,7 @@ func NewDir(remote string, modTime time.Time) *Dir { // NewDirCopy creates an unspecialized copy of the Directory object passed in func NewDirCopy(ctx context.Context, d Directory) *Dir { return &Dir{ + f: d.Fs(), remote: d.Remote(), modTime: d.ModTime(ctx), size: d.Size(), @@ -38,6 +41,11 @@ func NewDirCopy(ctx context.Context, d Directory) *Dir { } } +// Fs returns the Fs that this directory is part of +func (d *Dir) Fs() Info { + return d.f +} + // String returns the name func (d *Dir) String() string { return d.remote diff --git a/fs/list/list_test.go b/fs/list/list_test.go index 59312d898..616271746 100644 --- a/fs/list/list_test.go +++ b/fs/list/list_test.go @@ -87,6 +87,7 @@ func TestFilterAndSortCheckDirRoot(t *testing.T) { type unknownDirEntry string +func (o unknownDirEntry) Fs() fs.Info { return fs.Unknown } func (o unknownDirEntry) String() string { return string(o) } func (o unknownDirEntry) Remote() string { return string(o) } func (o unknownDirEntry) ModTime(ctx context.Context) (t time.Time) { return t } diff --git a/fs/metadata.go b/fs/metadata.go index 19b07cb63..919e7862a 100644 --- a/fs/metadata.go +++ b/fs/metadata.go @@ -63,10 +63,10 @@ func (m *Metadata) MergeOptions(options []OpenOption) { } } -// GetMetadata from an ObjectInfo +// GetMetadata from an DirEntry // // If the object has no metadata then metadata will be nil -func GetMetadata(ctx context.Context, o ObjectInfo) (metadata Metadata, err error) { +func GetMetadata(ctx context.Context, o DirEntry) (metadata Metadata, err error) { do, ok := o.(Metadataer) if !ok { return nil, nil @@ -91,7 +91,7 @@ type mapItem struct { // This runs an external program on the metadata which can be used to // map it from one form to another. -func metadataMapper(ctx context.Context, cmdLine SpaceSepList, dstFs Fs, o ObjectInfo, metadata Metadata) (newMetadata Metadata, err error) { +func metadataMapper(ctx context.Context, cmdLine SpaceSepList, dstFs Fs, o DirEntry, metadata Metadata) (newMetadata Metadata, err error) { ci := GetConfig(ctx) cmd := exec.Command(cmdLine[0], cmdLine[1:]...) in := mapItem{ @@ -145,14 +145,14 @@ func metadataMapper(ctx context.Context, cmdLine SpaceSepList, dstFs Fs, o Objec return out.Metadata, nil } -// GetMetadataOptions from an ObjectInfo and merge it with any in options +// GetMetadataOptions from an DirEntry and merge it with any in options // // If --metadata isn't in use it will return nil. // // If the object has no metadata then metadata will be nil. // // This should be passed the destination Fs for the metadata mapper -func GetMetadataOptions(ctx context.Context, dstFs Fs, o ObjectInfo, options []OpenOption) (metadata Metadata, err error) { +func GetMetadataOptions(ctx context.Context, dstFs Fs, o DirEntry, options []OpenOption) (metadata Metadata, err error) { ci := GetConfig(ctx) if !ci.Metadata { return nil, nil diff --git a/fs/mimetype.go b/fs/mimetype.go index 4ea9aab2a..a0bfcd9fe 100644 --- a/fs/mimetype.go +++ b/fs/mimetype.go @@ -54,7 +54,7 @@ func MimeTypeFromName(remote string) (mimeType string) { // MimeType returns the MimeType from the object, either by calling // the MimeTyper interface or using MimeTypeFromName -func MimeType(ctx context.Context, o ObjectInfo) (mimeType string) { +func MimeType(ctx context.Context, o DirEntry) (mimeType string) { // Read the MimeType from the optional interface if available if do, ok := o.(MimeTyper); ok { mimeType = do.MimeType(ctx) diff --git a/fs/types.go b/fs/types.go index 16afe79d8..a709f628b 100644 --- a/fs/types.go +++ b/fs/types.go @@ -102,9 +102,6 @@ type Object interface { type ObjectInfo interface { DirEntry - // Fs returns read only access to the Fs that this object is part of - Fs() Info - // Hash returns the selected checksum of the file // If no checksum is available it returns "" Hash(ctx context.Context, ty hash.Type) (string, error) @@ -117,6 +114,9 @@ type ObjectInfo interface { // a Dir or Object. These are returned from directory listings - type // assert them into the correct type. type DirEntry interface { + // Fs returns read only access to the Fs that this object is part of + Fs() Info + // String returns a description of the Object String() string @@ -332,3 +332,28 @@ type WriterAtCloser interface { io.WriterAt io.Closer } + +type unknownFs struct{} + +// Name of the remote (as passed into NewFs) +func (unknownFs) Name() string { return "unknown" } + +// Root of the remote (as passed into NewFs) +func (unknownFs) Root() string { return "" } + +// String returns a description of the FS +func (unknownFs) String() string { return "unknown" } + +// Precision of the ModTimes in this Fs +func (unknownFs) Precision() time.Duration { return ModTimeNotSupported } + +// Returns the supported hash types of the filesystem +func (unknownFs) Hashes() hash.Set { return hash.Set(hash.None) } + +// Features returns the optional features of this Fs +func (unknownFs) Features() *Features { return &Features{} } + +// Unknown holds an Info for an unknown Fs +// +// This is used when we need an Fs but don't have one. +var Unknown Info = unknownFs{}