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  }