package router import ( "errors" "regexp" "strings" ) func strip(s string) string { return strings.TrimSpace(s) } func slice(s string) []string { var sl []string for _, p := range strings.Split(s, ",") { if str := strip(p); len(str) > 0 { sl = append(sl, strip(p)) } } return sl } // Encode encodes an endpoint to endpoint metadata. func Encode(e *Endpoint) map[string]string { if e == nil { return nil } // endpoint map ep := make(map[string]string) // set vals only if they exist set := func(k, v string) { if len(v) == 0 { return } ep[k] = v } set("endpoint", e.Name) set("description", e.Description) set("handler", e.Handler) set("method", strings.Join(e.Method, ",")) set("path", strings.Join(e.Path, ",")) set("host", strings.Join(e.Host, ",")) return ep } // Decode decodes endpoint metadata into an endpoint. func Decode(e map[string]string) *Endpoint { if e == nil { return nil } return &Endpoint{ Name: e["endpoint"], Description: e["description"], Method: slice(e["method"]), Path: slice(e["path"]), Host: slice(e["host"]), Handler: e["handler"], } } // Validate validates an endpoint to guarantee it won't blow up when being served. func Validate(e *Endpoint) error { if e == nil { return errors.New("endpoint is nil") } if len(e.Name) == 0 { return errors.New("name required") } for _, p := range e.Path { ps := p[0] pe := p[len(p)-1] if ps == '^' && pe == '$' { _, err := regexp.CompilePOSIX(p) if err != nil { return err } } else if ps == '^' && pe != '$' { return errors.New("invalid path") } else if ps != '^' && pe == '$' { return errors.New("invalid path") } } if len(e.Handler) == 0 { return errors.New("invalid handler") } return nil }