github.com/gocaveman/caveman@v0.0.0-20191211162744-0ddf99dbdf6e/webutil/path-parse.go (about) 1 package webutil 2 3 import ( 4 "fmt" 5 "io" 6 "strings" 7 ) 8 9 // TODO: take a good look at the various go routers out there and find a good pattern for how to do this. 10 /* 11 12 Some links: 13 https://github.com/julienschmidt/httprouter 14 https://www.nicolasmerouze.com/guide-routers-golang/ 15 https://husobee.github.io/golang/url-router/2015/06/15/why-do-all-golang-url-routers-suck.html 16 17 https://github.com/gorilla/mux/blob/master/regexp.go#L27 18 19 */ 20 21 // PathParse is a thin wrapper around fmt Sscanf, substituing slashes for spaces. 22 // The path provided get slashes replaced with strings, then is whitespace trimmed. 23 // And the result is fed to `fmt.Sscanf`. An error will be returned if the argument 24 // types do not match according to Sscanf, or if it could parse too few or 25 // too many arguments. The objective is provide a very simple way to rapidly parse 26 // paths using syntax Go developers are already familiar with. 27 func PathParse(path string, format string, a ...interface{}) error { 28 29 fpath := strings.TrimSpace(strings.Replace(path, "/", " ", -1)) 30 fformat := strings.TrimSpace(strings.Replace(format, "/", " ", -1)) + " %s" // additional param so we can detect overruns 31 32 var tmps string 33 var args []interface{} 34 args = append(args, a...) 35 args = append(args, &tmps) 36 37 n, err := fmt.Sscanf(fpath, fformat, args...) 38 39 // log.Printf("fpath=%q, fformat=%q, args=%#v; n=%v, err=%v; len(a)=%v", fpath, fformat, args, n, err, len(a)) 40 41 if n == len(a) && (err == io.EOF || err == nil) { 42 return nil 43 } 44 45 if n != len(a) { 46 return fmt.Errorf("expected %d args but read %d", len(a), n) 47 } 48 49 return err 50 } 51 52 // HasPathPrefix is similar to strings' HasPrefix but intended for paths. 53 // Matches if path is equal to prefix or if it starts with prefix+"/". 54 // I.e. prefix "/thepath" will match paths "/thepath", "/thepath/", "/thepath/something/else", 55 // but not "/thepathogen". Useful for testing "is this path logically the 56 // same directory as what I'm serving." 57 func HasPathPrefix(path string, prefix string) bool { 58 if path == prefix { 59 return true 60 } 61 return strings.HasPrefix(path, prefix+"/") 62 }