package router import ( "fmt" "strings" ) const ( compContextPlain int = iota compContextRegex startRegex byte = '{' stopRegex byte = '}' ) func pathCompiler(path string) (string, error) { var err error res := make([]byte, 0) var pos int = compContextPlain var depth int = 0 pattern := make([]byte, 0) for _, b := range []byte(path) { switch pos { case compContextPlain: switch b { case stopRegex: depth -= 1 res = append(res, b) case startRegex: depth += 1 pos = compContextRegex // pattern started pattern = make([]byte, 0) default: res = append(res, b) } case compContextRegex: switch b { case startRegex: depth += 1 case stopRegex: depth -= 1 if depth == 0 { pattern = convertRegexp(pattern) res = append(res, pattern...) pos = compContextPlain // pattern ended } default: pattern = append(pattern, b) } } } if depth != 0 { err = fmt.Errorf("Unbalanced brackets into pattern") } return string(res), err } const ( defaultRegexp = `[a-zA-Z0-9_][/\-\.a-zA-Z0-9_%%=:~]+` ) func convertRegexp(src []byte) []byte { var res string const patternSeps = ":" parts := strings.SplitN(string(src), patternSeps, 2) if len(parts) == 1 { parts = append(parts, defaultRegexp) } res = fmt.Sprintf("(?<%s>%s)", parts[0], parts[1]) return []byte(res) }