67 lines
1.1 KiB
Go
67 lines
1.1 KiB
Go
package storage
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// Encode serializes a value into JSON.
|
|
func Encode(value any) ([]byte, error) {
|
|
return json.MarshalIndent(value, "", " ")
|
|
}
|
|
|
|
// Decode deserializes JSON into the supplied value.
|
|
func Decode(data []byte, target any) error {
|
|
return json.Unmarshal(data, target)
|
|
}
|
|
|
|
// Save writes a value to a JSON file.
|
|
func Save(path string, value any) error {
|
|
data, err := Encode(value)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
dir := filepath.Dir(path)
|
|
|
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
|
return err
|
|
}
|
|
|
|
file, err := os.CreateTemp(dir, ".settings-*.tmp")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tempPath := file.Name()
|
|
|
|
defer os.Remove(tempPath)
|
|
|
|
if _, err := file.Write(data); err != nil {
|
|
file.Close()
|
|
return err
|
|
}
|
|
|
|
if err := file.Sync(); err != nil {
|
|
file.Close()
|
|
return err
|
|
}
|
|
|
|
if err := file.Close(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return os.Rename(tempPath, path)
|
|
}
|
|
|
|
// Load reads a JSON file into the supplied target.
|
|
func Load(path string, target any) error {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return Decode(data, target)
|
|
}
|