gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

binding.go (3934B)


      1 // Copyright 2014 Manu Martinez-Almeida. All rights reserved.
      2 // Use of this source code is governed by a MIT style
      3 // license that can be found in the LICENSE file.
      4 
      5 //go:build !nomsgpack
      6 
      7 package binding
      8 
      9 import "net/http"
     10 
     11 // Content-Type MIME of the most common data formats.
     12 const (
     13 	MIMEJSON              = "application/json"
     14 	MIMEHTML              = "text/html"
     15 	MIMEXML               = "application/xml"
     16 	MIMEXML2              = "text/xml"
     17 	MIMEPlain             = "text/plain"
     18 	MIMEPOSTForm          = "application/x-www-form-urlencoded"
     19 	MIMEMultipartPOSTForm = "multipart/form-data"
     20 	MIMEPROTOBUF          = "application/x-protobuf"
     21 	MIMEMSGPACK           = "application/x-msgpack"
     22 	MIMEMSGPACK2          = "application/msgpack"
     23 	MIMEYAML              = "application/x-yaml"
     24 	MIMETOML              = "application/toml"
     25 )
     26 
     27 // Binding describes the interface which needs to be implemented for binding the
     28 // data present in the request such as JSON request body, query parameters or
     29 // the form POST.
     30 type Binding interface {
     31 	Name() string
     32 	Bind(*http.Request, any) error
     33 }
     34 
     35 // BindingBody adds BindBody method to Binding. BindBody is similar with Bind,
     36 // but it reads the body from supplied bytes instead of req.Body.
     37 type BindingBody interface {
     38 	Binding
     39 	BindBody([]byte, any) error
     40 }
     41 
     42 // BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
     43 // but it reads the Params.
     44 type BindingUri interface {
     45 	Name() string
     46 	BindUri(map[string][]string, any) error
     47 }
     48 
     49 // StructValidator is the minimal interface which needs to be implemented in
     50 // order for it to be used as the validator engine for ensuring the correctness
     51 // of the request. Gin provides a default implementation for this using
     52 // https://github.com/go-playground/validator/tree/v10.6.1.
     53 type StructValidator interface {
     54 	// ValidateStruct can receive any kind of type and it should never panic, even if the configuration is not right.
     55 	// If the received type is a slice|array, the validation should be performed travel on every element.
     56 	// If the received type is not a struct or slice|array, any validation should be skipped and nil must be returned.
     57 	// If the received type is a struct or pointer to a struct, the validation should be performed.
     58 	// If the struct is not valid or the validation itself fails, a descriptive error should be returned.
     59 	// Otherwise nil must be returned.
     60 	ValidateStruct(any) error
     61 
     62 	// Engine returns the underlying validator engine which powers the
     63 	// StructValidator implementation.
     64 	Engine() any
     65 }
     66 
     67 // Validator is the default validator which implements the StructValidator
     68 // interface. It uses https://github.com/go-playground/validator/tree/v10.6.1
     69 // under the hood.
     70 var Validator StructValidator = &defaultValidator{}
     71 
     72 // These implement the Binding interface and can be used to bind the data
     73 // present in the request to struct instances.
     74 var (
     75 	JSON          = jsonBinding{}
     76 	XML           = xmlBinding{}
     77 	Form          = formBinding{}
     78 	Query         = queryBinding{}
     79 	FormPost      = formPostBinding{}
     80 	FormMultipart = formMultipartBinding{}
     81 	ProtoBuf      = protobufBinding{}
     82 	MsgPack       = msgpackBinding{}
     83 	YAML          = yamlBinding{}
     84 	Uri           = uriBinding{}
     85 	Header        = headerBinding{}
     86 	TOML          = tomlBinding{}
     87 )
     88 
     89 // Default returns the appropriate Binding instance based on the HTTP method
     90 // and the content type.
     91 func Default(method, contentType string) Binding {
     92 	if method == http.MethodGet {
     93 		return Form
     94 	}
     95 
     96 	switch contentType {
     97 	case MIMEJSON:
     98 		return JSON
     99 	case MIMEXML, MIMEXML2:
    100 		return XML
    101 	case MIMEPROTOBUF:
    102 		return ProtoBuf
    103 	case MIMEMSGPACK, MIMEMSGPACK2:
    104 		return MsgPack
    105 	case MIMEYAML:
    106 		return YAML
    107 	case MIMETOML:
    108 		return TOML
    109 	case MIMEMultipartPOSTForm:
    110 		return FormMultipart
    111 	default: // case MIMEPOSTForm:
    112 		return Form
    113 	}
    114 }
    115 
    116 func validate(obj any) error {
    117 	if Validator == nil {
    118 		return nil
    119 	}
    120 	return Validator.ValidateStruct(obj)
    121 }