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