feat: add BVK exchange library

This commit is contained in:
Георгий
2026-07-12 20:44:44 +03:00
parent 3a1c524eb2
commit 0ff0905a9c
15 changed files with 627 additions and 0 deletions

84
store_file.go Normal file
View File

@@ -0,0 +1,84 @@
package mila
import (
"context"
"encoding/json"
"errors"
"os"
"path/filepath"
"sync"
)
type FileStore struct {
path string
mu sync.Mutex
mem *MemoryStore
}
func NewFileStore(path string) *FileStore {
return &FileStore{
path: path,
mem: NewMemoryStore(),
}
}
func (s *FileStore) Get(ctx context.Context) (ContentState, error) {
if state, err := s.mem.Get(ctx); err == nil {
return state, nil
}
s.mu.Lock()
defer s.mu.Unlock()
data, err := os.ReadFile(s.path)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return ContentState{}, ErrNotReady
}
return ContentState{}, err
}
var state ContentState
if err := json.Unmarshal(data, &state); err != nil {
return ContentState{}, err
}
if state.IsZero() {
return ContentState{}, ErrNotReady
}
if err := s.mem.Set(ctx, state); err != nil {
return ContentState{}, err
}
return state, nil
}
func (s *FileStore) Set(ctx context.Context, state ContentState) error {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
s.mu.Lock()
defer s.mu.Unlock()
if err := os.MkdirAll(filepath.Dir(s.path), 0o755); err != nil {
return err
}
data, err := json.MarshalIndent(state, "", " ")
if err != nil {
return err
}
tmp := s.path + ".tmp"
if err := os.WriteFile(tmp, data, 0o644); err != nil {
return err
}
if err := os.Rename(tmp, s.path); err != nil {
_ = os.Remove(tmp)
return err
}
return s.mem.Set(ctx, state)
}