github.com/puellanivis/breton@v0.2.16/lib/files/json/json.go (about)

     1  // Package json is intended to replace uses of encoding/json while integrating with the files package.
     2  package json
     3  
     4  import (
     5  	"bytes"
     6  	"context"
     7  	"encoding/json"
     8  	"io"
     9  
    10  	"github.com/puellanivis/breton/lib/files"
    11  )
    12  
    13  // Unmarshal is encoding/json.Unmarshal
    14  func Unmarshal(data []byte, v interface{}) error {
    15  	return json.Unmarshal(data, v)
    16  }
    17  
    18  // ReadFrom will ReadAndClose the given io.ReadCloser and unmarshal that data into v as per json.Unmarshal.
    19  func ReadFrom(r io.ReadCloser, v interface{}) error {
    20  	data, err := files.ReadFrom(r)
    21  	if err != nil {
    22  		return err
    23  	}
    24  
    25  	if len(data) < 1 {
    26  		v = nil
    27  		return nil
    28  	}
    29  
    30  	return json.Unmarshal(data, v)
    31  }
    32  
    33  // Read will open a filename with the given context, and Unmarshal that data into v as per json.Unmarshal.
    34  func Read(ctx context.Context, filename string, v interface{}) error {
    35  	f, err := files.Open(ctx, filename)
    36  	if err != nil {
    37  		return err
    38  	}
    39  
    40  	return ReadFrom(f, v)
    41  }
    42  
    43  // Marshal is a wrapper around encoding/json.Marshal that will optionally apply
    44  // Indent or Compact options.
    45  func Marshal(v interface{}, opts ...Option) ([]byte, error) {
    46  	c := &config{
    47  		escapeHTML: true,
    48  	}
    49  
    50  	for _, opt := range opts {
    51  		_ = opt(c)
    52  	}
    53  
    54  	b := new(bytes.Buffer)
    55  	enc := json.NewEncoder(b)
    56  
    57  	if c.prefix != "" || c.indent != "" {
    58  		enc.SetIndent(c.prefix, c.indent)
    59  	}
    60  
    61  	if !c.escapeHTML {
    62  		enc.SetEscapeHTML(c.escapeHTML)
    63  	}
    64  
    65  	if err := enc.Encode(v); err != nil {
    66  		return nil, err
    67  	}
    68  
    69  	if c.compact {
    70  		buf := new(bytes.Buffer)
    71  		if err := json.Compact(buf, b.Bytes()); err != nil {
    72  			return nil, err
    73  		}
    74  		b = buf
    75  	}
    76  
    77  	return b.Bytes(), nil
    78  }
    79  
    80  // WriteTo writes a value marshalled as JSON to the the given io.WriteCloser.
    81  func WriteTo(w io.WriteCloser, v interface{}, opts ...Option) error {
    82  	b, err := Marshal(v, opts...)
    83  	if err != nil {
    84  		return err
    85  	}
    86  
    87  	return files.WriteTo(w, b)
    88  }
    89  
    90  // Write writes a marshaled JSON to a filename with the given Context.
    91  func Write(ctx context.Context, filename string, v interface{}, opts ...Option) error {
    92  	f, err := files.Create(ctx, filename)
    93  	if err != nil {
    94  		return err
    95  	}
    96  
    97  	return WriteTo(f, v, opts...)
    98  }