github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/store/json.go (about)

     1  package store
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"unsafe"
     7  
     8  	json "github.com/json-iterator/go"
     9  	"github.com/json-iterator/go/extra"
    10  	"github.com/modern-go/reflect2"
    11  
    12  	"github.com/tilt-dev/tilt/pkg/model"
    13  )
    14  
    15  var defaultJSONIterator = json.Config{}.Froze()
    16  
    17  func CreateEngineStateEncoder(w io.Writer) *json.Encoder {
    18  	config := json.Config{SortMapKeys: true}.Froze()
    19  	config.RegisterExtension(&extra.BinaryAsStringExtension{})
    20  	config.RegisterExtension(newEngineStateExtension())
    21  	config.RegisterExtension(&privateFieldsExtension{})
    22  	return config.NewEncoder(w)
    23  }
    24  
    25  type targetIDEncoder struct {
    26  	delegate json.ValEncoder
    27  }
    28  
    29  func (targetIDEncoder) IsEmpty(ptr unsafe.Pointer) bool {
    30  	tID := (*model.TargetID)(ptr)
    31  	return tID.Empty()
    32  }
    33  
    34  func (e targetIDEncoder) Encode(ptr unsafe.Pointer, stream *json.Stream) {
    35  	tID := (*model.TargetID)(ptr)
    36  	s := tID.String()
    37  	stream.WriteString(fmt.Sprintf("%q", s))
    38  }
    39  
    40  type engineStateExtension struct {
    41  	*json.DummyExtension
    42  	targetIDType reflect2.Type
    43  }
    44  
    45  func newEngineStateExtension() engineStateExtension {
    46  	return engineStateExtension{
    47  		// memoize the type lookup
    48  		targetIDType: reflect2.TypeOf(model.TargetID{}),
    49  	}
    50  }
    51  
    52  func (e engineStateExtension) CreateMapKeyEncoder(typ reflect2.Type) json.ValEncoder {
    53  	if e.targetIDType == typ {
    54  		return targetIDEncoder{delegate: defaultJSONIterator.EncoderOf(typ)}
    55  	}
    56  	return nil
    57  }
    58  
    59  func (e engineStateExtension) CreateEncoder(typ reflect2.Type) json.ValEncoder {
    60  	if e.targetIDType == typ {
    61  		return targetIDEncoder{delegate: defaultJSONIterator.EncoderOf(typ)}
    62  	}
    63  	return nil
    64  }