package magic import ( "encoding/json" "io" "net/http" ) type JsonDecodeError struct { inner error } func (err JsonDecodeError) Error() string { return "failed to decode json: " + err.inner.Error() } func (err JsonDecodeError) WriteResponse(rw http.ResponseWriter) { rw.WriteHeader(http.StatusBadRequest) } type Json[T any] struct { Data T } func NewJson[T any](data T) Json[T] { return Json[T]{ Data: data, } } func (data *Json[T]) FromRequest(request *http.Request) error { bodyReader := request.Body defer bodyReader.Close() request.Body = http.NoBody if err := json.NewDecoder(bodyReader).Decode(&data.Data); err != nil { return JsonDecodeError{inner: err} } return nil } type counter struct { counter int64 } func (c *counter) Write(b []byte) (int, error) { n := len(b) c.counter += int64(n) return n, nil } func (container Json[T]) Write(w io.Writer) (int64, error) { counter := &counter{} err := json.NewEncoder(io.MultiWriter(counter, w)).Encode(container.Data) return counter.counter, err } func (json Json[T]) WriteResponse(w http.ResponseWriter) { json.Write(w) }