github.com/puellanivis/breton@v0.2.16/lib/files/filestore.go (about) 1 package files 2 3 import ( 4 "context" 5 "net/url" 6 "os" 7 "sort" 8 "sync" 9 ) 10 11 // FileStore defines an interface which implements a system of accessing files for reading (Open) writing (Write) and directly listing (List) 12 type FileStore interface { 13 Open(ctx context.Context, uri *url.URL) (Reader, error) 14 Create(ctx context.Context, uri *url.URL) (Writer, error) 15 List(ctx context.Context, uri *url.URL) ([]os.FileInfo, error) 16 } 17 18 var fsMap struct { 19 sync.Mutex 20 21 m map[string]FileStore 22 keys []string 23 sorted bool 24 } 25 26 func getFS(uri *url.URL) (FileStore, bool) { 27 fsMap.Lock() 28 defer fsMap.Unlock() 29 30 if fsMap.m == nil { 31 return nil, false 32 } 33 34 fs, ok := fsMap.m[uri.Scheme] 35 return fs, ok 36 } 37 38 // RegisterScheme takes a FileStore and attaches to it the given schemes so 39 // that files.Open will use that FileStore when a files.Open() is performed 40 // with a URL of any of those schemes. 41 func RegisterScheme(fs FileStore, schemes ...string) { 42 if len(schemes) < 1 { 43 return 44 } 45 46 fsMap.Lock() 47 defer fsMap.Unlock() 48 49 if fsMap.m == nil { 50 fsMap.m = make(map[string]FileStore) 51 } 52 fsMap.sorted = false 53 54 for _, scheme := range schemes { 55 if _, ok := fsMap.m[scheme]; ok { 56 // TODO: report duplicate scheme registration 57 continue 58 } 59 60 fsMap.m[scheme] = fs 61 fsMap.keys = append(fsMap.keys, scheme) 62 } 63 } 64 65 // RegisteredSchemes returns a slice of strings that describe all registered schemes. 66 func RegisteredSchemes() []string { 67 fsMap.Lock() 68 defer fsMap.Unlock() 69 70 if !fsMap.sorted { 71 sort.Strings(fsMap.keys) 72 fsMap.sorted = true 73 } 74 75 return fsMap.keys 76 }