github.com/fluhus/gostuff@v0.4.1-0.20240331134726-be71864f2b5d/jio/jio.go (about)

     1  // Package jio provides convenience functions for saving and loading
     2  // JSON-encoded values.
     3  //
     4  // Uses the [aio] package for I/O.
     5  package jio
     6  
     7  import (
     8  	"encoding/json"
     9  	"io"
    10  
    11  	"github.com/fluhus/gostuff/aio"
    12  )
    13  
    14  // Save saves v to the given file, encoded as JSON.
    15  func Save(file string, v interface{}) error {
    16  	f, err := aio.Create(file)
    17  	if err != nil {
    18  		return err
    19  	}
    20  	e := json.NewEncoder(f)
    21  	e.SetIndent("", "  ")
    22  	if err := e.Encode(v); err != nil {
    23  		f.Close()
    24  		return err
    25  	}
    26  	return f.Close()
    27  }
    28  
    29  // Load loads a JSON encoded value from the given file and populates v with it.
    30  func Load(file string, v interface{}) error {
    31  	f, err := aio.Open(file)
    32  	if err != nil {
    33  		return err
    34  	}
    35  	defer f.Close()
    36  	return json.NewDecoder(f).Decode(v)
    37  }
    38  
    39  // Iter returns an iterator over sequential JSON values in a file.
    40  //
    41  // Note: a file with several independent JSON values is not a valid JSON file.
    42  func Iter[T any](file string) func(yield func(T, error) bool) {
    43  	return func(yield func(T, error) bool) {
    44  		f, err := aio.Open(file)
    45  		if err != nil {
    46  			var t T
    47  			yield(t, err)
    48  			return
    49  		}
    50  		defer f.Close()
    51  		j := json.NewDecoder(f)
    52  		for {
    53  			var t T
    54  			err := j.Decode(&t)
    55  			if err == io.EOF {
    56  				return
    57  			}
    58  			if err != nil {
    59  				yield(t, err)
    60  				return
    61  			}
    62  			if !yield(t, nil) {
    63  				return
    64  			}
    65  		}
    66  	}
    67  }