package db import ( "bytes" "errors" "fmt" "io/ioutil" "os" "path/filepath" "github.com/xlgmokha/x/pkg/env" "github.com/xlgmokha/x/pkg/serde" "github.com/xlgmokha/x/pkg/x" ) type Entity interface { Identifier() string } type Storage[T Entity] struct { dir string } func New[T Entity](dir string) *Storage[T] { fullPath := x.Must(filepath.Abs(dir)) x.Check(os.MkdirAll(fullPath, 0700)) return &Storage[T]{ dir: fullPath, } } func (db *Storage[T]) Save(item T) error { if db.fileExistsFor(item) { return nil } w := new(bytes.Buffer) x.Check(serde.To(w, item, serde.YAML)) if env.Fetch("DUMP", "") != "" { fmt.Println(w.String()) } return ioutil.WriteFile(db.filePathFor(item), w.Bytes(), 0700) } func (db *Storage[T]) filePathFor(item T) string { return fmt.Sprintf("%v/%v.yaml", db.dir, item.Identifier()) } func (db *Storage[T]) fileExistsFor(item T) bool { _, err := os.Stat(db.filePathFor(item)) if err != nil && errors.Is(err, os.ErrNotExist) { return false } return true }