From 182fce9914c7d907d92ad23afa4c9dfd360d851f Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 22 Nov 2024 17:55:15 +0000 Subject: [PATCH] fs: define ListP interface for paged listing #4788 --- fs/features.go | 39 +++++++++++++++++++++++++++++++++++++++ fs/types.go | 1 + 2 files changed, 40 insertions(+) diff --git a/fs/features.go b/fs/features.go index 828f3b94b..c830ec637 100644 --- a/fs/features.go +++ b/fs/features.go @@ -158,6 +158,21 @@ type Features struct { // of listing recursively that doing a directory traversal. ListR ListRFn + // ListP lists the objects and directories of the Fs starting + // from dir non recursively to out. + // + // dir should be "" to start from the root, and should not + // have trailing slashes. + // + // This should return ErrDirNotFound if the directory isn't + // found. + // + // It should call callback for each tranche of entries read. + // These need not be returned in any particular order. If + // callback returns an error then the listing will stop + // immediately. + ListP func(ctx context.Context, dir string, callback ListRCallback) error + // About gets quota information from the Fs About func(ctx context.Context) (*Usage, error) @@ -326,6 +341,9 @@ func (ft *Features) Fill(ctx context.Context, f Fs) *Features { if do, ok := f.(ListRer); ok { ft.ListR = do.ListR } + if do, ok := f.(ListPer); ok { + ft.ListP = do.ListP + } if do, ok := f.(Abouter); ok { ft.About = do.About } @@ -432,6 +450,9 @@ func (ft *Features) Mask(ctx context.Context, f Fs) *Features { if mask.ListR == nil { ft.ListR = nil } + if mask.ListP == nil { + ft.ListP = nil + } if mask.About == nil { ft.About = nil } @@ -660,6 +681,24 @@ type ListRer interface { ListR(ctx context.Context, dir string, callback ListRCallback) error } +// ListPer is an optional interfaces for Fs +type ListPer interface { + // ListP lists the objects and directories of the Fs starting + // from dir non recursively into out. + // + // dir should be "" to start from the root, and should not + // have trailing slashes. + // + // This should return ErrDirNotFound if the directory isn't + // found. + // + // It should call callback for each tranche of entries read. + // These need not be returned in any particular order. If + // callback returns an error then the listing will stop + // immediately. + ListP(ctx context.Context, dir string, callback ListRCallback) error +} + // RangeSeeker is the interface that wraps the RangeSeek method. // // Some of the returns from Object.Open() may optionally implement diff --git a/fs/types.go b/fs/types.go index 2ed4e588b..c664ce162 100644 --- a/fs/types.go +++ b/fs/types.go @@ -311,6 +311,7 @@ func DirectoryOptionalInterfaces(d Directory) (supported, unsupported []string) type ListRCallback func(entries DirEntries) error // ListRFn is defines the call used to recursively list a directory +// with ListR or page through a directory with ListP type ListRFn func(ctx context.Context, dir string, callback ListRCallback) error // Flagger describes the interface rclone config types flags must satisfy