new configuration format (more explicit + cleaner)
This commit is contained in:
parent
aef8d74bb9
commit
43779b8644
|
@ -42,9 +42,6 @@ func Load(path string) (*Controller, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (5) Set default optional fields */
|
|
||||||
receiver.setDefaults()
|
|
||||||
|
|
||||||
return receiver, nil
|
return receiver, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -148,9 +145,8 @@ func (c *Controller) format(controllerName string) error {
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
for pName, pData := range method.Ptr.Parameters {
|
for pName, pData := range method.Ptr.Parameters {
|
||||||
|
|
||||||
/* (4) Fail on invalid rename (set but empty) */
|
if len(pData.Rename) < 1 {
|
||||||
if pData.Rename != nil && len(*pData.Rename) < 1 {
|
pData.Rename = pName
|
||||||
return fmt.Errorf("Empty rename for %s.%s parameter '%s'", controllerName, method.Name, pName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (5) Check for name/rename conflict */
|
/* (5) Check for name/rename conflict */
|
||||||
|
@ -162,31 +158,43 @@ func (c *Controller) format(controllerName string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Same rename field
|
// 1. Same rename field
|
||||||
if pData.Rename != nil && param.Rename != nil && *pData.Rename == *param.Rename {
|
if pData.Rename == param.Rename {
|
||||||
return fmt.Errorf("Rename conflict for %s.%s parameter '%s'", controllerName, method.Name, *pData.Rename)
|
return fmt.Errorf("Rename conflict for %s.%s parameter '%s'", controllerName, method.Name, pData.Rename)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Not-renamed field matches a renamed field
|
// 2. Not-renamed field matches a renamed field
|
||||||
if pData.Rename == nil && param.Rename != nil && pName == *param.Rename {
|
if pName == param.Rename {
|
||||||
return fmt.Errorf("Name conflict for %s.%s parameter '%s'", controllerName, method.Name, pName)
|
return fmt.Errorf("Name conflict for %s.%s parameter '%s'", controllerName, method.Name, pName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Renamed field matches name
|
// 3. Renamed field matches name
|
||||||
if pData.Rename != nil && param.Rename == nil && *pData.Rename == paramName {
|
if pData.Rename == paramName {
|
||||||
return fmt.Errorf("Name conflict for %s.%s parameter '%s'", controllerName, method.Name, pName)
|
return fmt.Errorf("Name conflict for %s.%s parameter '%s'", controllerName, method.Name, pName)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (6) Fail on missing description */
|
/* (6) Manage invalid type */
|
||||||
|
if len(pData.Type) < 1 {
|
||||||
|
return fmt.Errorf("Invalid type for %s.%s parameter '%s'", controllerName, method.Name, pName)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (7) Fail on missing description */
|
||||||
if len(pData.Description) < 1 {
|
if len(pData.Description) < 1 {
|
||||||
return fmt.Errorf("Missing description for %s.%s parameter '%s'", controllerName, method.Name, pName)
|
return fmt.Errorf("Missing description for %s.%s parameter '%s'", controllerName, method.Name, pName)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (7) Fail on missing type */
|
/* (8) Fail on missing type */
|
||||||
if len(pData.Type) < 1 {
|
if len(pData.Type) < 1 {
|
||||||
return fmt.Errorf("Missing type for %s.%s parameter '%s'", controllerName, method.Name, pName)
|
return fmt.Errorf("Missing type for %s.%s parameter '%s'", controllerName, method.Name, pName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (9) Set optional + type */
|
||||||
|
if pData.Type[0] == '?' {
|
||||||
|
pData.Optional = true
|
||||||
|
pData.Type = pData.Type[1:]
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -217,54 +225,3 @@ func (c *Controller) format(controllerName string) error {
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setDefaults sets the defaults for optional configuration fields
|
|
||||||
func (c *Controller) setDefaults() {
|
|
||||||
|
|
||||||
/* (1) Get methods */
|
|
||||||
methods := []*Method{
|
|
||||||
c.GET,
|
|
||||||
c.POST,
|
|
||||||
c.PUT,
|
|
||||||
c.DELETE,
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (2) Browse methods */
|
|
||||||
for _, m := range methods {
|
|
||||||
|
|
||||||
// ignore if not set
|
|
||||||
if m == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (3) Browse parameters */
|
|
||||||
for name, param := range m.Parameters {
|
|
||||||
|
|
||||||
// 1. Default 'opt': required //
|
|
||||||
if param.Optional == nil {
|
|
||||||
param.Optional = new(bool)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Default 'rename': same as name
|
|
||||||
if param.Rename == nil {
|
|
||||||
param.Rename = new(string)
|
|
||||||
*param.Rename = name
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (4) Stop here if no children */
|
|
||||||
if c.Children == nil || len(c.Children) < 1 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (5) Iterate over children */
|
|
||||||
for _, child := range c.Children {
|
|
||||||
child.setDefaults()
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -4,17 +4,17 @@ package config
|
||||||
---------------------------------------------------------*/
|
---------------------------------------------------------*/
|
||||||
|
|
||||||
type Parameter struct {
|
type Parameter struct {
|
||||||
Description string `json:"des"`
|
Description string `json:"info"`
|
||||||
Type string `json:"typ"`
|
Type string `json:"type"`
|
||||||
Rename *string `json:"ren"`
|
Rename string `json:"name,omitempty"`
|
||||||
Optional *bool `json:"opt"`
|
Optional bool
|
||||||
Default *interface{} `json:"def"`
|
Default *interface{} `json:"default"`
|
||||||
}
|
}
|
||||||
type Method struct {
|
type Method struct {
|
||||||
Description string `json:"des"`
|
Description string `json:"info"`
|
||||||
Permission [][]string `json:"per"`
|
Permission [][]string `json:"scope"`
|
||||||
Parameters map[string]*Parameter `json:"par"`
|
Parameters map[string]*Parameter `json:"in"`
|
||||||
Options map[string]interface{} `json:"opt"`
|
Download *bool `json:"download"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
|
|
29
router.go
29
router.go
|
@ -41,20 +41,17 @@ func (s *Server) route(res http.ResponseWriter, httpReq *http.Request) {
|
||||||
parameters := make(map[string]interface{})
|
parameters := make(map[string]interface{})
|
||||||
for name, param := range method.Parameters {
|
for name, param := range method.Parameters {
|
||||||
|
|
||||||
/* (1) Rename */
|
/* (1) Extract value */
|
||||||
rename := *param.Rename
|
|
||||||
|
|
||||||
/* (2) Extract value */
|
|
||||||
p, isset := req.Data.Set[name]
|
p, isset := req.Data.Set[name]
|
||||||
|
|
||||||
/* (3) Required & missing */
|
/* (2) Required & missing */
|
||||||
if !isset && !*param.Optional {
|
if !isset && !param.Optional {
|
||||||
paramError = err.MissingParam
|
paramError = err.MissingParam
|
||||||
paramError.BindArgument(name)
|
paramError.BindArgument(name)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (4) Optional & missing: set default value */
|
/* (3) Optional & missing: set default value */
|
||||||
if !isset {
|
if !isset {
|
||||||
p = &request.Parameter{
|
p = &request.Parameter{
|
||||||
Parsed: true,
|
Parsed: true,
|
||||||
|
@ -66,42 +63,42 @@ func (s *Server) route(res http.ResponseWriter, httpReq *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// we are done
|
// we are done
|
||||||
parameters[rename] = p.Value
|
parameters[param.Rename] = p.Value
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (5) Parse parameter if not file */
|
/* (4) Parse parameter if not file */
|
||||||
if !p.File {
|
if !p.File {
|
||||||
p.Parse()
|
p.Parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (6) Fail on unexpected multipart file */
|
/* (5) Fail on unexpected multipart file */
|
||||||
waitFile, gotFile := param.Type == "FILE", p.File
|
waitFile, gotFile := param.Type == "FILE", p.File
|
||||||
if gotFile && !waitFile || !gotFile && waitFile {
|
if gotFile && !waitFile || !gotFile && waitFile {
|
||||||
paramError = err.InvalidParam
|
paramError = err.InvalidParam
|
||||||
paramError.BindArgument(rename)
|
paramError.BindArgument(param.Rename)
|
||||||
paramError.BindArgument("FILE")
|
paramError.BindArgument("FILE")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (7) Do not check if file */
|
/* (6) Do not check if file */
|
||||||
if gotFile {
|
if gotFile {
|
||||||
parameters[rename] = p.Value
|
parameters[param.Rename] = p.Value
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (8) Check type */
|
/* (7) Check type */
|
||||||
if s.Checker.Run(param.Type, p.Value) != nil {
|
if s.Checker.Run(param.Type, p.Value) != nil {
|
||||||
|
|
||||||
paramError = err.InvalidParam
|
paramError = err.InvalidParam
|
||||||
paramError.BindArgument(rename)
|
paramError.BindArgument(param.Rename)
|
||||||
paramError.BindArgument(param.Type)
|
paramError.BindArgument(param.Type)
|
||||||
paramError.BindArgument(p.Value)
|
paramError.BindArgument(p.Value)
|
||||||
break
|
break
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters[rename] = p.Value
|
parameters[param.Rename] = p.Value
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue