github.com/mutagen-io/mutagen@v0.18.0-rc1/pkg/encoding/common.go (about)

     1  package encoding
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"github.com/mutagen-io/mutagen/pkg/filesystem"
     8  )
     9  
    10  // LoadAndUnmarshal provides the underlying loading and unmarshaling
    11  // functionality for the encoding package. It reads the data at the specified
    12  // path and then invokes the specified unmarshaling callback (usually a closure)
    13  // to decode the data.
    14  func LoadAndUnmarshal(path string, unmarshal func([]byte) error) error {
    15  	// Grab the file contents.
    16  	data, err := os.ReadFile(path)
    17  	if err != nil {
    18  		if os.IsNotExist(err) {
    19  			return err
    20  		}
    21  		return fmt.Errorf("unable to load file: %w", err)
    22  	}
    23  
    24  	// Perform the unmarshaling.
    25  	if err := unmarshal(data); err != nil {
    26  		return fmt.Errorf("unable to unmarshal data: %w", err)
    27  	}
    28  
    29  	// Success.
    30  	return nil
    31  }
    32  
    33  // MarshalAndSave provide the underlying marshaling and saving functionality for
    34  // the encoding package. It invokes the specified marshaling callback (usually a
    35  // closure) and writes the result atomically to the specified path. The data is
    36  // saved with read/write permissions for the user only.
    37  func MarshalAndSave(path string, marshal func() ([]byte, error)) error {
    38  	// Marshal the message.
    39  	data, err := marshal()
    40  	if err != nil {
    41  		return fmt.Errorf("unable to marshal message: %w", err)
    42  	}
    43  
    44  	// Write the file atomically with secure file permissions.
    45  	if err := filesystem.WriteFileAtomic(path, data, 0600); err != nil {
    46  		return fmt.Errorf("unable to write message data: %w", err)
    47  	}
    48  
    49  	// Success.
    50  	return nil
    51  }