package fs import ( "fmt" "io" "time" ) // Limited defines a Fs which can only return the Objects passed in // from the Fs passed in type Limited struct { objects []Object fs Fs } // NewLimited maks a limited Fs limited to the objects passed in func NewLimited(fs Fs, objects ...Object) Fs { f := &Limited{ objects: objects, fs: fs, } return f } // Name is name of the remote (as passed into NewFs) func (f *Limited) Name() string { return f.fs.Name() // return name of underlying remote } // Root is the root of the remote (as passed into NewFs) func (f *Limited) Root() string { return f.fs.Root() // return root of underlying remote } // String returns a description of the FS func (f *Limited) String() string { return fmt.Sprintf("%s limited to %d objects", f.fs.String(), len(f.objects)) } // List the Fs into a channel func (f *Limited) List() ObjectsChan { out := make(ObjectsChan, Config.Checkers) go func() { for _, obj := range f.objects { out <- obj } close(out) }() return out } // ListDir lists the Fs directories/buckets/containers into a channel func (f *Limited) ListDir() DirChan { out := make(DirChan, Config.Checkers) close(out) return out } // NewFsObject finds the Object at remote. Returns nil if can't be found func (f *Limited) NewFsObject(remote string) Object { for _, obj := range f.objects { if obj.Remote() == remote { return obj } } return nil } // Put in to the remote path with the modTime given of the given size // // May create the object even if it returns an error - if so // will return the object and the error, otherwise will return // nil and the error func (f *Limited) Put(in io.Reader, src ObjectInfo) (Object, error) { remote := src.Remote() obj := f.NewFsObject(remote) if obj == nil { return nil, fmt.Errorf("Can't create %q in limited fs", remote) } return obj, obj.Update(in, src) } // Mkdir make the directory (container, bucket) func (f *Limited) Mkdir() error { // All directories are already made - just ignore return nil } // Rmdir removes the directory (container, bucket) if empty func (f *Limited) Rmdir() error { // Ignore this in a limited fs return nil } // Precision of the ModTimes in this Fs func (f *Limited) Precision() time.Duration { return f.fs.Precision() } // Hashes returns the supported hash sets. func (f *Limited) Hashes() HashSet { return f.fs.Hashes() } // Copy src to this remote using server side copy operations. // // This is stored with the remote path given // // It returns the destination Object and a possible error // // Will only be called if src.Fs().Name() == f.Name() // // If it isn't possible then return fs.ErrorCantCopy func (f *Limited) Copy(src Object, remote string) (Object, error) { fCopy, ok := f.fs.(Copier) if !ok { return nil, ErrorCantCopy } return fCopy.Copy(src, remote) } // Move src to this remote using server side move operations. // // This is stored with the remote path given // // It returns the destination Object and a possible error // // Will only be called if src.Fs().Name() == f.Name() // // If it isn't possible then return fs.ErrorCantMove func (f *Limited) Move(src Object, remote string) (Object, error) { fMove, ok := f.fs.(Mover) if !ok { return nil, ErrorCantMove } return fMove.Move(src, remote) } // UnWrap returns the Fs that this Fs is wrapping func (f *Limited) UnWrap() Fs { return f.fs } // Check the interfaces are satisfied var ( _ Fs = (*Limited)(nil) _ Copier = (*Limited)(nil) _ Mover = (*Limited)(nil) _ UnWrapper = (*Limited)(nil) )