jsonfile/jsonfile.go

71 lines
1.7 KiB
Go

package jsonfile
import (
"encoding/json"
"errors"
"os"
"path/filepath"
"git.tordarus.net/Tordarus/adverr"
)
var (
ErrDirectoryCreation = adverr.NewErrTmpl("ErrDirectoryCreation", "Could not create directory at %s")
ErrFileCreation = adverr.NewErrTmpl("ErrFileCreationFailed", "Could not create file at %s")
ErrFileOpen = adverr.NewErrTmpl("ErrFileOpen", "Could not open file at %s")
ErrJsonEncoding = adverr.NewErrTmpl("ErrJsonEncoding", "Could not encode JSON of %#v")
ErrJsonDecoding = adverr.NewErrTmpl("ErrJsonDecoding", "Could not decode JSON")
)
// Save encodes value writes its JSON into the file
func Save(path string, value interface{}) error {
dir := filepath.Dir(path)
err := os.MkdirAll(dir, os.ModePerm)
if err != nil {
return ErrDirectoryCreation.Wrap(err, dir)
}
file, err := os.Create(path)
if err != nil {
return ErrFileCreation.Wrap(err, path)
}
defer file.Close()
enc := json.NewEncoder(file)
enc.SetIndent("", "\t")
err = enc.Encode(value)
if err != nil {
return ErrJsonEncoding.Wrap(err, value)
}
return nil
}
// Load reads the file contents and decodes them as JSON into value
func Load(path string, value interface{}) error {
file, err := os.Open(path)
if err != nil {
return ErrFileOpen.Wrap(err, path)
}
defer file.Close()
dec := json.NewDecoder(file)
err = dec.Decode(value)
if err != nil {
return ErrJsonDecoding.Wrap(err)
}
return nil
}
// File uses Load() to load data from the file into value.
// If it fails, Save() will be executed instead
// storing the current value into the file
func File(path string, value interface{}) error {
err := Load(path, value)
if errors.Is(err, ErrFileOpen) {
return Save(path, value)
}
return err
}