Add validator interface to unify and for readability #11
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"git.xdrm.io/go/aicra/datatype"
|
"git.xdrm.io/go/aicra/datatype"
|
||||||
)
|
)
|
||||||
|
@ -17,29 +16,40 @@ func Parse(r io.Reader, dtypes ...datatype.T) (*Server, error) {
|
||||||
Types: make([]datatype.T, 0),
|
Types: make([]datatype.T, 0),
|
||||||
Services: make([]*Service, 0),
|
Services: make([]*Service, 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
// add data types
|
// add data types
|
||||||
for _, dtype := range dtypes {
|
for _, dtype := range dtypes {
|
||||||
server.Types = append(server.Types, dtype)
|
server.Types = append(server.Types, dtype)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse JSON
|
|
||||||
if err := json.NewDecoder(r).Decode(&server.Services); err != nil {
|
if err := json.NewDecoder(r).Decode(&server.Services); err != nil {
|
||||||
return nil, fmt.Errorf("%s: %w", ErrRead, err)
|
return nil, fmt.Errorf("%s: %w", ErrRead, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check services
|
if err := server.Validate(); err != nil {
|
||||||
if err := server.checkAndFormat(); err != nil {
|
|
||||||
return nil, fmt.Errorf("%s: %w", ErrFormat, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check collisions
|
|
||||||
if err := server.collide(); err != nil {
|
|
||||||
return nil, fmt.Errorf("%s: %w", ErrFormat, err)
|
return nil, fmt.Errorf("%s: %w", ErrFormat, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return server, nil
|
return server, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate implements the validator interface
|
||||||
|
func (server Server) Validate(datatypes ...datatype.T) error {
|
||||||
|
for _, service := range server.Services {
|
||||||
|
err := service.Validate(server.Types...)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s '%s': %w", service.Method, service.Pattern, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for collisions
|
||||||
|
if err := server.collide(); err != nil {
|
||||||
|
return fmt.Errorf("%s: %w", ErrFormat, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Find a service matching an incoming HTTP request
|
// Find a service matching an incoming HTTP request
|
||||||
func (server Server) Find(r *http.Request) *Service {
|
func (server Server) Find(r *http.Request) *Service {
|
||||||
for _, service := range server.Services {
|
for _, service := range server.Services {
|
||||||
|
@ -157,42 +167,3 @@ func (server *Server) collide() error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkAndFormat checks for errors and missing fields and sets default values for optional fields.
|
|
||||||
func (server Server) checkAndFormat() error {
|
|
||||||
for _, service := range server.Services {
|
|
||||||
|
|
||||||
// check method
|
|
||||||
err := service.checkMethod()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s '%s' [method]: %w", service.Method, service.Pattern, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check pattern
|
|
||||||
service.Pattern = strings.Trim(service.Pattern, " \t\r\n")
|
|
||||||
err = service.checkPattern()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s '%s' [path]: %w", service.Method, service.Pattern, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check description
|
|
||||||
if len(strings.Trim(service.Description, " \t\r\n")) < 1 {
|
|
||||||
return fmt.Errorf("%s '%s' [description]: %w", service.Method, service.Pattern, ErrMissingDescription)
|
|
||||||
}
|
|
||||||
|
|
||||||
// check input parameters
|
|
||||||
err = service.checkAndFormatInput(server.Types)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%s '%s' [in]: %w", service.Method, service.Pattern, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// fail if a brace capture remains undefined
|
|
||||||
for _, capture := range service.Captures {
|
|
||||||
if capture.Ref == nil {
|
|
||||||
return fmt.Errorf("%s '%s' [in]: %s: %w", service.Method, service.Pattern, capture.Name, ErrUndefinedBraceCapture)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue