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 }