Skip to content

Commit

Permalink
use *os.File instead of file path
Browse files Browse the repository at this point in the history
  • Loading branch information
keks committed Jul 31, 2018
1 parent 2b80fc9 commit 0550843
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 59 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)
}
```
Expand All @@ -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)
}
```
56 changes: 14 additions & 42 deletions persist.go
Original file line number Diff line number Diff line change
@@ -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")
}
21 changes: 7 additions & 14 deletions persist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"time"

"github.com/cheekybits/is"
"github.com/matryer/persist"
"github.com/keks/persist"
)

type obj struct {
Expand All @@ -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{
Expand All @@ -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))
}

0 comments on commit 0550843

Please sign in to comment.