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  }