github.com/artpar/rclone@v1.67.3/fs/dir_wrapper.go (about)

     1  package fs
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  )
     7  
     8  // DirWrapper wraps a Directory object so the Remote can be overridden
     9  type DirWrapper struct {
    10  	Directory           // Directory we are wrapping
    11  	remote       string // name of the directory
    12  	failSilently bool   // if set, ErrorNotImplemented should not be considered an error for this directory
    13  }
    14  
    15  // NewDirWrapper creates a wrapper for a directory object
    16  //
    17  // This passes through optional methods and should be used for
    18  // wrapping backends to wrap native directories.
    19  func NewDirWrapper(remote string, d Directory) *DirWrapper {
    20  	return &DirWrapper{
    21  		Directory: d,
    22  		remote:    remote,
    23  	}
    24  }
    25  
    26  // NewLimitedDirWrapper creates a DirWrapper that should fail silently instead of erroring for ErrorNotImplemented.
    27  //
    28  // Intended for exceptional dirs lacking abilities that the Fs otherwise usually supports
    29  // (ex. a Combine root which can't set metadata/modtime, regardless of support by wrapped backend)
    30  func NewLimitedDirWrapper(remote string, d Directory) *DirWrapper {
    31  	dw := NewDirWrapper(remote, d)
    32  	dw.failSilently = true
    33  	return dw
    34  }
    35  
    36  // String returns the name
    37  func (d *DirWrapper) String() string {
    38  	return d.remote
    39  }
    40  
    41  // Remote returns the remote path
    42  func (d *DirWrapper) Remote() string {
    43  	return d.remote
    44  }
    45  
    46  // SetRemote sets the remote
    47  func (d *DirWrapper) SetRemote(remote string) *DirWrapper {
    48  	d.remote = remote
    49  	return d
    50  }
    51  
    52  // Metadata returns metadata for an DirEntry
    53  //
    54  // It should return nil if there is no Metadata
    55  func (d *DirWrapper) Metadata(ctx context.Context) (Metadata, error) {
    56  	do, ok := d.Directory.(Metadataer)
    57  	if !ok {
    58  		return nil, nil
    59  	}
    60  	return do.Metadata(ctx)
    61  }
    62  
    63  // SetMetadata sets metadata for an DirEntry
    64  //
    65  // It should return fs.ErrorNotImplemented if it can't set metadata
    66  func (d *DirWrapper) SetMetadata(ctx context.Context, metadata Metadata) error {
    67  	do, ok := d.Directory.(SetMetadataer)
    68  	if !ok {
    69  		if d.failSilently {
    70  			Debugf(d, "Can't SetMetadata for this directory (%T from %v) -- skipping", d.Directory, d.Fs())
    71  			return nil
    72  		}
    73  		return ErrorNotImplemented
    74  	}
    75  	return do.SetMetadata(ctx, metadata)
    76  }
    77  
    78  // SetModTime sets the metadata on the DirEntry to set the modification date
    79  //
    80  // If there is any other metadata it does not overwrite it.
    81  func (d *DirWrapper) SetModTime(ctx context.Context, t time.Time) error {
    82  	do, ok := d.Directory.(SetModTimer)
    83  	if !ok {
    84  		if d.failSilently {
    85  			Debugf(d, "Can't SetModTime for this directory (%T from %v) -- skipping", d.Directory, d.Fs())
    86  			return nil
    87  		}
    88  		return ErrorNotImplemented
    89  	}
    90  	return do.SetModTime(ctx, t)
    91  }
    92  
    93  // Check interfaces
    94  var (
    95  	_ DirEntry      = (*DirWrapper)(nil)
    96  	_ Directory     = (*DirWrapper)(nil)
    97  	_ FullDirectory = (*DirWrapper)(nil)
    98  )