package repo import ( "encoding" "errors" "github.com/iliadenisov/galaxy/pkg/repo/fs" ) type StorageError error func NewStorageError(err error) error { return StorageError(err) } type StateError error func NewStateError(msg string) error { return StateError(errors.New(msg)) } type Storage interface { Lock() (func() error, error) Exists(string) (bool, error) Write(string, encoding.BinaryMarshaler) error Read(string, encoding.BinaryUnmarshaler) error } type repo struct { s Storage release func() error } func NewRepo(s Storage) (*repo, error) { r := &repo{ s: s, } return r, nil } func NewFileRepo(path string) (*repo, error) { s, err := fs.NewFileStorage(path) if err != nil { return nil, err } return NewRepo(s) } func (r *repo) Lock() (err error) { if r.s == nil { return errors.New("storage is closed") } if r.release != nil { return errors.New("storage already locked") } r.release, err = r.s.Lock() if err != nil { r.close() return } return nil } func (r *repo) Release() (err error) { if r.s == nil { return errors.New("storage is closed") } if r.release == nil { return errors.New("storage was never locked") } err = r.release() if err != nil { return } r.close() return nil } func (r *repo) close() { r.release = nil r.s = nil }