new configuration format (more explicit + cleaner)

This commit is contained in:
Adrien Marquès 2018-06-03 15:08:47 +02:00
parent aef8d74bb9
commit 43779b8644
3 changed files with 42 additions and 88 deletions

View File

@ -42,9 +42,6 @@ func Load(path string) (*Controller, error) {
return nil, err
}
/* (5) Set default optional fields */
receiver.setDefaults()
return receiver, nil
}
@ -148,9 +145,8 @@ func (c *Controller) format(controllerName string) error {
/* check parameters */
for pName, pData := range method.Ptr.Parameters {
/* (4) Fail on invalid rename (set but empty) */
if pData.Rename != nil && len(*pData.Rename) < 1 {
return fmt.Errorf("Empty rename for %s.%s parameter '%s'", controllerName, method.Name, pName)
if len(pData.Rename) < 1 {
pData.Rename = pName
}
/* (5) Check for name/rename conflict */
@ -162,31 +158,43 @@ func (c *Controller) format(controllerName string) error {
}
// 1. Same rename field
if pData.Rename != nil && param.Rename != nil && *pData.Rename == *param.Rename {
return fmt.Errorf("Rename conflict for %s.%s parameter '%s'", controllerName, method.Name, *pData.Rename)
if pData.Rename == param.Rename {
return fmt.Errorf("Rename conflict for %s.%s parameter '%s'", controllerName, method.Name, pData.Rename)
}
// 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)
}
// 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)
}
}
/* (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 {
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 {
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
}
// 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
}

View File

@ -4,17 +4,17 @@ package config
---------------------------------------------------------*/
type Parameter struct {
Description string `json:"des"`
Type string `json:"typ"`
Rename *string `json:"ren"`
Optional *bool `json:"opt"`
Default *interface{} `json:"def"`
Description string `json:"info"`
Type string `json:"type"`
Rename string `json:"name,omitempty"`
Optional bool
Default *interface{} `json:"default"`
}
type Method struct {
Description string `json:"des"`
Permission [][]string `json:"per"`
Parameters map[string]*Parameter `json:"par"`
Options map[string]interface{} `json:"opt"`
Description string `json:"info"`
Permission [][]string `json:"scope"`
Parameters map[string]*Parameter `json:"in"`
Download *bool `json:"download"`
}
type Controller struct {

View File

@ -41,20 +41,17 @@ func (s *Server) route(res http.ResponseWriter, httpReq *http.Request) {
parameters := make(map[string]interface{})
for name, param := range method.Parameters {
/* (1) Rename */
rename := *param.Rename
/* (2) Extract value */
/* (1) Extract value */
p, isset := req.Data.Set[name]
/* (3) Required & missing */
if !isset && !*param.Optional {
/* (2) Required & missing */
if !isset && !param.Optional {
paramError = err.MissingParam
paramError.BindArgument(name)
break
}
/* (4) Optional & missing: set default value */
/* (3) Optional & missing: set default value */
if !isset {
p = &request.Parameter{
Parsed: true,
@ -66,42 +63,42 @@ func (s *Server) route(res http.ResponseWriter, httpReq *http.Request) {
}
// we are done
parameters[rename] = p.Value
parameters[param.Rename] = p.Value
continue
}
/* (5) Parse parameter if not file */
/* (4) Parse parameter if not file */
if !p.File {
p.Parse()
}
/* (6) Fail on unexpected multipart file */
/* (5) Fail on unexpected multipart file */
waitFile, gotFile := param.Type == "FILE", p.File
if gotFile && !waitFile || !gotFile && waitFile {
paramError = err.InvalidParam
paramError.BindArgument(rename)
paramError.BindArgument(param.Rename)
paramError.BindArgument("FILE")
break
}
/* (7) Do not check if file */
/* (6) Do not check if file */
if gotFile {
parameters[rename] = p.Value
parameters[param.Rename] = p.Value
continue
}
/* (8) Check type */
/* (7) Check type */
if s.Checker.Run(param.Type, p.Value) != nil {
paramError = err.InvalidParam
paramError.BindArgument(rename)
paramError.BindArgument(param.Rename)
paramError.BindArgument(param.Type)
paramError.BindArgument(p.Value)
break
}
parameters[rename] = p.Value
parameters[param.Rename] = p.Value
}