codec.go raw

   1  package dotenv
   2  
   3  import (
   4  	"bytes"
   5  	"fmt"
   6  	"sort"
   7  	"strings"
   8  
   9  	"github.com/subosito/gotenv"
  10  )
  11  
  12  const keyDelimiter = "_"
  13  
  14  // Codec implements the encoding.Encoder and encoding.Decoder interfaces for encoding data containing environment variables
  15  // (commonly called as dotenv format).
  16  type Codec struct{}
  17  
  18  func (Codec) Encode(v map[string]any) ([]byte, error) {
  19  	flattened := map[string]any{}
  20  
  21  	flattened = flattenAndMergeMap(flattened, v, "", keyDelimiter)
  22  
  23  	keys := make([]string, 0, len(flattened))
  24  
  25  	for key := range flattened {
  26  		keys = append(keys, key)
  27  	}
  28  
  29  	sort.Strings(keys)
  30  
  31  	var buf bytes.Buffer
  32  
  33  	for _, key := range keys {
  34  		_, err := buf.WriteString(fmt.Sprintf("%v=%v\n", strings.ToUpper(key), flattened[key]))
  35  		if err != nil {
  36  			return nil, err
  37  		}
  38  	}
  39  
  40  	return buf.Bytes(), nil
  41  }
  42  
  43  func (Codec) Decode(b []byte, v map[string]any) error {
  44  	var buf bytes.Buffer
  45  
  46  	_, err := buf.Write(b)
  47  	if err != nil {
  48  		return err
  49  	}
  50  
  51  	env, err := gotenv.StrictParse(&buf)
  52  	if err != nil {
  53  		return err
  54  	}
  55  
  56  	for key, value := range env {
  57  		v[key] = value
  58  	}
  59  
  60  	return nil
  61  }
  62