diff --git a/src/internal/operations/restore.go b/src/internal/operations/restore.go index dfb07b396..74f1e3c44 100644 --- a/src/internal/operations/restore.go +++ b/src/internal/operations/restore.go @@ -256,35 +256,9 @@ func formatDetailsForRestoration( sel selectors.Selector, deets *details.Details, ) ([]path.Path, error) { - var fds *details.Details - - switch sel.Service { - case selectors.ServiceExchange: - er, err := sel.ToExchangeRestore() - if err != nil { - return nil, err - } - - // format the details and retrieve the items from kopia - fds = er.Reduce(ctx, deets) - if len(fds.Entries) == 0 { - return nil, selectors.ErrorNoMatchingItems - } - - case selectors.ServiceOneDrive: - odr, err := sel.ToOneDriveRestore() - if err != nil { - return nil, err - } - - // format the details and retrieve the items from kopia - fds = odr.Reduce(ctx, deets) - if len(fds.Entries) == 0 { - return nil, selectors.ErrorNoMatchingItems - } - - default: - return nil, errors.Errorf("Service %s not supported", sel.Service) + fds, err := sel.Reduce(ctx, deets) + if err != nil { + return nil, err } var ( diff --git a/src/pkg/selectors/onedrive.go b/src/pkg/selectors/onedrive.go index 72865baec..b75b551e0 100644 --- a/src/pkg/selectors/onedrive.go +++ b/src/pkg/selectors/onedrive.go @@ -35,6 +35,8 @@ type ( } ) +var _ Reducer = &OneDriveRestore{} + // NewOneDriveBackup produces a new Selector with the service set to ServiceOneDrive. func NewOneDriveBackup() *OneDriveBackup { src := OneDriveBackup{ diff --git a/src/pkg/selectors/scopes.go b/src/pkg/selectors/scopes.go index 794f28b70..2c0931219 100644 --- a/src/pkg/selectors/scopes.go +++ b/src/pkg/selectors/scopes.go @@ -10,6 +10,19 @@ import ( "github.com/alcionai/corso/src/pkg/path" ) +// Any returns the set matching any value. +func Any() []string { + return []string{AnyTgt} +} + +// None returns the set matching None of the values. +// This is primarily a fallback for empty values. Adding None() +// to any selector will force all matches() checks on that selector +// to fail. +func None() []string { + return []string{NoneTgt} +} + // --------------------------------------------------------------------------- // types & interfaces // --------------------------------------------------------------------------- diff --git a/src/pkg/selectors/selectors.go b/src/pkg/selectors/selectors.go index 755421dd5..50d81241d 100644 --- a/src/pkg/selectors/selectors.go +++ b/src/pkg/selectors/selectors.go @@ -97,19 +97,6 @@ func newSelector(s service) Selector { } } -// Any returns the set matching any value. -func Any() []string { - return []string{AnyTgt} -} - -// None returns the set matching None of the values. -// This is primarily a fallback for empty values. Adding None() -// to any selector will force all matches() checks on that selector -// to fail. -func None() []string { - return []string{NoneTgt} -} - func (s Selector) String() string { bs, err := json.Marshal(s) if err != nil { @@ -190,6 +177,32 @@ func (s Selector) PathService() path.ServiceType { return serviceToPathType[s.Service] } +// Reduce is a quality-of-life interpreter that allows Reduce to be called +// from the generic selector by interpreting the selector service type rather +// than have the caller make that interpretation. Returns an error if the +// service is unsupported. +func (s Selector) Reduce(ctx context.Context, deets *details.Details) (*details.Details, error) { + var ( + r Reducer + err error + ) + + switch s.Service { + case ServiceExchange: + r, err = s.ToExchangeRestore() + case ServiceOneDrive: + r, err = s.ToOneDriveRestore() + default: + return nil, errors.New("service not supported: " + s.Service.String()) + } + + if err != nil { + return nil, err + } + + return r.Reduce(ctx, deets), nil +} + // --------------------------------------------------------------------------- // Printing Selectors for Human Reading // ---------------------------------------------------------------------------