1package policy 2 3import ( 4 "context" 5 "math/rand" 6 7 "github.com/rclone/rclone/backend/union/upstream" 8 "github.com/rclone/rclone/fs" 9) 10 11func init() { 12 registerPolicy("rand", &Rand{}) 13} 14 15// Rand stands for random 16// Calls all and then randomizes. Returns one candidate. 17type Rand struct { 18 All 19} 20 21func (p *Rand) rand(upstreams []*upstream.Fs) *upstream.Fs { 22 return upstreams[rand.Intn(len(upstreams))] 23} 24 25func (p *Rand) randEntries(entries []upstream.Entry) upstream.Entry { 26 return entries[rand.Intn(len(entries))] 27} 28 29// Action category policy, governing the modification of files and directories 30func (p *Rand) Action(ctx context.Context, upstreams []*upstream.Fs, path string) ([]*upstream.Fs, error) { 31 upstreams, err := p.All.Action(ctx, upstreams, path) 32 if err != nil { 33 return nil, err 34 } 35 return []*upstream.Fs{p.rand(upstreams)}, nil 36} 37 38// ActionEntries is ACTION category policy but receiving a set of candidate entries 39func (p *Rand) ActionEntries(entries ...upstream.Entry) ([]upstream.Entry, error) { 40 entries, err := p.All.ActionEntries(entries...) 41 if err != nil { 42 return nil, err 43 } 44 return []upstream.Entry{p.randEntries(entries)}, nil 45} 46 47// Create category policy, governing the creation of files and directories 48func (p *Rand) Create(ctx context.Context, upstreams []*upstream.Fs, path string) ([]*upstream.Fs, error) { 49 upstreams, err := p.All.Create(ctx, upstreams, path) 50 if err != nil { 51 return nil, err 52 } 53 return []*upstream.Fs{p.rand(upstreams)}, nil 54} 55 56// CreateEntries is CREATE category policy but receiving a set of candidate entries 57func (p *Rand) CreateEntries(entries ...upstream.Entry) ([]upstream.Entry, error) { 58 entries, err := p.All.CreateEntries(entries...) 59 if err != nil { 60 return nil, err 61 } 62 return []upstream.Entry{p.randEntries(entries)}, nil 63} 64 65// Search category policy, governing the access to files and directories 66func (p *Rand) Search(ctx context.Context, upstreams []*upstream.Fs, path string) (*upstream.Fs, error) { 67 if len(upstreams) == 0 { 68 return nil, fs.ErrorObjectNotFound 69 } 70 upstreams, err := p.epall(ctx, upstreams, path) 71 if err != nil { 72 return nil, err 73 } 74 return p.rand(upstreams), nil 75} 76 77// SearchEntries is SEARCH category policy but receiving a set of candidate entries 78func (p *Rand) SearchEntries(entries ...upstream.Entry) (upstream.Entry, error) { 79 if len(entries) == 0 { 80 return nil, fs.ErrorObjectNotFound 81 } 82 return p.randEntries(entries), nil 83} 84