Created
August 3, 2024 12:29
-
-
Save abdivasiyev/0d62959cda7ee082c9826dfb8318dcc3 to your computer and use it in GitHub Desktop.
Decode everything using only one package
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package decoder | |
import ( | |
"encoding/json" | |
"io" | |
"net/http" | |
"github.com/gorilla/schema" | |
) | |
const ( | |
JSON = "json" | |
QueryParam = "queryParam" | |
Header = "header" | |
) | |
type ( | |
Decoder interface { | |
Data(d []byte) Decoder | |
Req(r *http.Request) Decoder | |
Reader(r io.Reader) Decoder | |
Decode(dest any) error | |
} | |
baseDecoder struct { | |
req *http.Request | |
r io.Reader | |
d []byte | |
} | |
jsonDecoder struct { | |
baseDecoder | |
} | |
queryDecoder struct { | |
decoder *schema.Decoder | |
baseDecoder | |
} | |
headerDecoder struct { | |
decoder *schema.Decoder | |
baseDecoder | |
} | |
) | |
func (bd *baseDecoder) Data(d []byte) Decoder { | |
bd.d = d | |
return bd | |
} | |
func (bd *baseDecoder) Reader(r io.Reader) Decoder { | |
bd.r = r | |
return bd | |
} | |
func (bd *baseDecoder) Req(r *http.Request) Decoder { | |
bd.req = r | |
return bd | |
} | |
func (bd *baseDecoder) Decode(dest any) error { | |
return nil | |
} | |
func (j *jsonDecoder) Decode(dest any) error { | |
if j.req != nil { | |
return json.NewDecoder(j.req.Body).Decode(dest) | |
} | |
if j.r != nil { | |
return json.NewDecoder(j.r).Decode(dest) | |
} | |
return json.Unmarshal(j.d, dest) | |
} | |
func (q *queryDecoder) Decode(dest any) error { | |
if q.decoder != nil { | |
q.decoder = schema.NewDecoder() | |
q.decoder.SetAliasTag("query") | |
} | |
if q.req == nil { | |
return nil | |
} | |
return q.decoder.Decode(dest, q.req.URL.Query()) | |
} | |
func (q *headerDecoder) Decode(dest any) error { | |
if q.decoder != nil { | |
q.decoder = schema.NewDecoder() | |
q.decoder.SetAliasTag("header") | |
} | |
if q.req == nil { | |
return nil | |
} | |
return q.decoder.Decode(dest, q.req.Header) | |
} | |
func New(contentType string) Decoder { | |
switch contentType { | |
case QueryParam: | |
return &queryDecoder{} | |
case Header: | |
return &headerDecoder{} | |
default: | |
return &jsonDecoder{} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment