From 0550843708b25a82f643090ed369a17d0731b3fd Mon Sep 17 00:00:00 2001 From: keks Date: Tue, 31 Jul 2018 15:06:54 +0000 Subject: [PATCH] use *os.File instead of file path --- README.md | 13 +++++++++--- persist.go | 56 +++++++++++++------------------------------------ persist_test.go | 21 +++++++------------ 3 files changed, 31 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 64d72c0..8fff6f9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# persist [![GoDoc](https://godoc.org/github.com/matryer/persist?status.png)](http://godoc.org/github.com/matryer/persist) +# persist [![GoDoc](https://godoc.org/github.com/keks/persist?status.png)](http://godoc.org/github.com/keks/persist) Persist loads and saves Go objects to files ## Usage @@ -13,7 +13,12 @@ Then save objects like this: ``` var conf Config -if err := persist.Save("./project.conf", &conf); err != nil { +f, err := os.Create("./project.conf", 0x600) +if err != nil { + log.Faralln("failed opening the persistent file:", err) +} + +if err = persist.Save(f, &conf); err != nil { log.Fatalln("failed to save config:", err) } ``` @@ -22,8 +27,10 @@ And load them like this: ``` +// f is still in scope + var conf Config -if err := persist.Load("./project.conf", &conf); err != nil { +if err := persist.Load(f, &conf); err != nil { log.Fatalln("failed to load config:", err) } ``` diff --git a/persist.go b/persist.go index 5e2493d..08c5eb7 100644 --- a/persist.go +++ b/persist.go @@ -1,60 +1,32 @@ package persist import ( - "bytes" "encoding/json" - "io" "os" - "sync" -) - -var lock sync.Mutex - -// Marshal is a function that marshals the object into an -// io.Reader. -// By default, it uses the JSON marshaller. -var Marshal = func(v interface{}) (io.Reader, error) { - b, err := json.MarshalIndent(v, "", "\t") - if err != nil { - return nil, err - } - return bytes.NewReader(b), nil -} -// Unmarshal is a function that unmarshals the data from the -// reader into the specified value. -// By default, it uses the JSON unmarshaller. -var Unmarshal = func(r io.Reader, v interface{}) error { - return json.NewDecoder(r).Decode(v) -} + "github.com/pkg/errors" +) // Save saves a representation of v to the file at path. -func Save(path string, v interface{}) error { - lock.Lock() - defer lock.Unlock() - f, err := os.Create(path) +func Save(f *os.File, v interface{}) error { + data, err := json.MarshalIndent(v, "", "\t") if err != nil { - return err + return errors.Wrapf(err, "error marshaling value of type %T", v) } - defer f.Close() - r, err := Marshal(v) + + _, err = f.Write(data) if err != nil { - return err + return errors.Wrap(err, "error copying data into file") } - _, err = io.Copy(f, r) - return err + + _, err = f.Seek(0, 0) + return errors.Wrap(err, "error seeking to beginning of file") } // Load loads the file at path into v. // Use os.IsNotExist() to see if the returned error is due // to the file being missing. -func Load(path string, v interface{}) error { - lock.Lock() - defer lock.Unlock() - f, err := os.Open(path) - if err != nil { - return err - } - defer f.Close() - return Unmarshal(f, v) +func Load(f *os.File, v interface{}) error { + err := json.NewDecoder(f).Decode(v) + return errors.Wrap(err, "error decoding value") } diff --git a/persist_test.go b/persist_test.go index fce661d..814c3ee 100644 --- a/persist_test.go +++ b/persist_test.go @@ -6,7 +6,7 @@ import ( "time" "github.com/cheekybits/is" - "github.com/matryer/persist" + "github.com/keks/persist" ) type obj struct { @@ -15,17 +15,11 @@ type obj struct { When time.Time } -func TestNoFile(t *testing.T) { - is := is.New(t) - - var v interface{} - err := persist.Load("no-such-file.conf", &v) - is.Equal(true, os.IsNotExist(err)) - -} - func TestPersist(t *testing.T) { is := is.New(t) + + f, err := os.Create("./file.tmp") + is.NoErr(err) defer os.Remove("./file.tmp") o := &obj{ @@ -35,16 +29,15 @@ func TestPersist(t *testing.T) { } // save it - err := persist.Save("./file.tmp", o) + err = persist.Save(f, o) is.NoErr(err) // load it var o2 obj - err = persist.Load("./file.tmp", &o2) + err = persist.Load(f, &o2) is.NoErr(err) is.Equal(o.Name, o2.Name) is.Equal(o.Number, o2.Number) - is.Equal(o.When, o2.When) - + is.True(o.When.Equal(o2.When)) }