From ef7ac088c09be1ea2dce24e4a1908ec94151184a Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Thu, 4 Jul 2019 12:24:58 +0100 Subject: [PATCH] operations: make NewOverrideObjectInfo public and factor uses --- backend/googlephotos/googlephotos_test.go | 16 ++----- fs/fs.go | 23 ++++++++++ fs/operations/operations.go | 53 +++++++++++++++++++---- 3 files changed, 70 insertions(+), 22 deletions(-) diff --git a/backend/googlephotos/googlephotos_test.go b/backend/googlephotos/googlephotos_test.go index 7fe46781f..3b2b6f2e5 100644 --- a/backend/googlephotos/googlephotos_test.go +++ b/backend/googlephotos/googlephotos_test.go @@ -12,6 +12,7 @@ import ( _ "github.com/rclone/rclone/backend/local" "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/hash" + "github.com/rclone/rclone/fs/operations" "github.com/rclone/rclone/fstest" "github.com/rclone/rclone/lib/random" "github.com/stretchr/testify/assert" @@ -26,17 +27,6 @@ const ( fileNameUpload = "rclone-test-image2.jpg" ) -// Wrapper to override the remote for an object -type overrideRemoteObject struct { - fs.Object - remote string -} - -// Remote returns the overridden remote name -func (o *overrideRemoteObject) Remote() string { - return o.remote -} - func TestIntegration(t *testing.T) { ctx := context.Background() fstest.Initialise() @@ -66,7 +56,7 @@ func TestIntegration(t *testing.T) { require.NoError(t, err) in, err := srcObj.Open(ctx) require.NoError(t, err) - dstObj, err := f.Put(ctx, in, &overrideRemoteObject{srcObj, remote}) + dstObj, err := f.Put(ctx, in, operations.NewOverrideRemote(srcObj, remote)) require.NoError(t, err) assert.Equal(t, remote, dstObj.Remote()) _ = in.Close() @@ -231,7 +221,7 @@ func TestIntegration(t *testing.T) { require.NoError(t, err) in, err := srcObj.Open(ctx) require.NoError(t, err) - dstObj, err := f.Put(ctx, in, &overrideRemoteObject{srcObj, remote}) + dstObj, err := f.Put(ctx, in, operations.NewOverrideRemote(srcObj, remote)) require.NoError(t, err) assert.Equal(t, remote, dstObj.Remote()) _ = in.Close() diff --git a/fs/fs.go b/fs/fs.go index e0bc9252a..6f35b52e8 100644 --- a/fs/fs.go +++ b/fs/fs.go @@ -412,6 +412,29 @@ type GetTierer interface { GetTier() string } +// FullObjectInfo contains all the read-only optional interfaces +// +// Use for checking making wrapping ObjectInfos implement everything +type FullObjectInfo interface { + ObjectInfo + MimeTyper + IDer + ObjectUnWrapper + GetTierer +} + +// FullObject contains all the optional interfaces for Object +// +// Use for checking making wrapping Objects implement everything +type FullObject interface { + Object + MimeTyper + IDer + ObjectUnWrapper + GetTierer + SetTierer +} + // ObjectOptionalInterfaces returns the names of supported and // unsupported optional interfaces for an Object func ObjectOptionalInterfaces(o Object) (supported, unsupported []string) { diff --git a/fs/operations/operations.go b/fs/operations/operations.go index ff4d970a1..40f837932 100644 --- a/fs/operations/operations.go +++ b/fs/operations/operations.go @@ -261,28 +261,63 @@ func removeFailedCopy(ctx context.Context, dst fs.Object) bool { return true } -// Wrapper to override the remote for an object -type overrideRemoteObject struct { - fs.Object +// OverrideRemote is a wrapper to override the Remote for an +// ObjectInfo +type OverrideRemote struct { + fs.ObjectInfo remote string } +// NewOverrideRemote returns an OverrideRemoteObject which will +// return the remote specified +func NewOverrideRemote(oi fs.ObjectInfo, remote string) *OverrideRemote { + return &OverrideRemote{ + ObjectInfo: oi, + remote: remote, + } +} + // Remote returns the overridden remote name -func (o *overrideRemoteObject) Remote() string { +func (o *OverrideRemote) Remote() string { return o.remote } // MimeType returns the mime type of the underlying object or "" if it // can't be worked out -func (o *overrideRemoteObject) MimeType(ctx context.Context) string { - if do, ok := o.Object.(fs.MimeTyper); ok { +func (o *OverrideRemote) MimeType(ctx context.Context) string { + if do, ok := o.ObjectInfo.(fs.MimeTyper); ok { return do.MimeType(ctx) } return "" } -// Check interface is satisfied -var _ fs.MimeTyper = (*overrideRemoteObject)(nil) +// ID returns the ID of the Object if known, or "" if not +func (o *OverrideRemote) ID() string { + if do, ok := o.ObjectInfo.(fs.IDer); ok { + return do.ID() + } + return "" +} + +// UnWrap returns the Object that this Object is wrapping or nil if it +// isn't wrapping anything +func (o *OverrideRemote) UnWrap() fs.Object { + if o, ok := o.ObjectInfo.(fs.Object); ok { + return o + } + return nil +} + +// GetTier returns storage tier or class of the Object +func (o *OverrideRemote) GetTier() string { + if do, ok := o.ObjectInfo.(fs.GetTierer); ok { + return do.GetTier() + } + return "" +} + +// Check all optional interfaces satisfied +var _ fs.FullObjectInfo = (*OverrideRemote)(nil) // Copy src object to dst or f if nil. If dst is nil then it uses // remote as the name of the new object. @@ -378,7 +413,7 @@ func Copy(ctx context.Context, f fs.Fs, dst fs.Object, remote string, src fs.Obj var wrappedSrc fs.ObjectInfo = src // We try to pass the original object if possible if src.Remote() != remote { - wrappedSrc = &overrideRemoteObject{Object: src, remote: remote} + wrappedSrc = NewOverrideRemote(src, remote) } if doUpdate { actionTaken = "Copied (replaced existing)"