Introduce FilepathPathBridge
authorbep <bjorn.erik.pedersen@gmail.com>
Tue, 27 Jan 2015 10:44:41 +0000 (11:44 +0100)
committerbep <bjorn.erik.pedersen@gmail.com>
Tue, 27 Jan 2015 10:44:41 +0000 (11:44 +0100)
This commit introduces the new interface FilepathPathBridge to remove some code that differs only in their use of either the path or filepath package.

helpers/path.go
helpers/path_test.go
helpers/url.go

index f236f30aab9cca10b3ba302c165a5c282f0652fa..351b7a11a2948599bb1b6297a0b1c49f21d12cbb 100644 (file)
@@ -26,6 +26,44 @@ import (
        "unicode"
 )
 
+// Bridge for common functionality in filepath vs path
+type FilepathPathBridge interface {
+       Base(in string) string
+       Clean(in string) string
+       Dir(in string) string
+       Ext(in string) string
+       Join(elem ...string) string
+       Separator() string
+}
+
+type FilepathBridge struct {
+}
+
+func (FilepathBridge) Base(in string) string {
+       return filepath.Base(in)
+}
+
+func (FilepathBridge) Clean(in string) string {
+       return filepath.Clean(in)
+}
+
+func (FilepathBridge) Dir(in string) string {
+       return filepath.Dir(in)
+}
+
+func (FilepathBridge) Ext(in string) string {
+       return filepath.Ext(in)
+}
+
+func (FilepathBridge) Join(elem ...string) string {
+       return filepath.Join(elem...)
+}
+
+func (FilepathBridge) Separator() string {
+       return FilePathSeparator
+}
+
+var filepathBridge FilepathBridge
 var sanitizeRegexp = regexp.MustCompile("[^a-zA-Z0-9./_-]")
 
 // MakePath takes a string with any characters and replace it
@@ -64,7 +102,7 @@ func UnicodeSanitize(s string) string {
 // ReplaceExtension takes a path and an extension, strips the old extension
 // and returns the path with the new extension.
 func ReplaceExtension(path string, newExt string) string {
-       f, _ := FileAndExt(path)
+       f, _ := FileAndExt(path, filepathBridge)
        return f + "." + newExt
 }
 
@@ -155,7 +193,7 @@ func MakePathRelative(inPath string, possibleDirectories ...string) (string, err
 // Filename takes a path, strips out the extension,
 // and returns the name of the file.
 func Filename(in string) (name string) {
-       name, _ = FileAndExt(in)
+       name, _ = FileAndExt(in, filepathBridge)
        return
 }
 
@@ -175,11 +213,11 @@ func Filename(in string) (name string) {
 // If the path, in, represents a filename with an extension,
 // then name will be the filename minus any extension - including the dot
 // and ext will contain the extension - minus the dot.
-func FileAndExt(in string) (name string, ext string) {
-       ext = filepath.Ext(in)
-       base := filepath.Base(in) // path.Base strips any trailing slash!
+func FileAndExt(in string, b FilepathPathBridge) (name string, ext string) {
+       ext = b.Ext(in)
+       base := b.Base(in)
 
-       return extractFilename(in, ext, base, FilePathSeparator), ext
+       return extractFilename(in, ext, base, b.Separator()), ext
 }
 
 func extractFilename(in, ext, base, pathSeparator string) (name string) {
@@ -267,20 +305,24 @@ func PathPrep(ugly bool, in string) string {
 //     /section/name/           becomes /section/name/index.html
 //     /section/name/index.html becomes /section/name/index.html
 func PrettifyPath(in string) string {
+       return PrettiyPath(in, filepathBridge)
+}
+
+func PrettiyPath(in string, b FilepathPathBridge) string {
        if filepath.Ext(in) == "" {
                // /section/name/  -> /section/name/index.html
                if len(in) < 2 {
-                       return FilePathSeparator
+                       return b.Separator()
                }
-               return filepath.Join(filepath.Clean(in), "index.html")
+               return b.Join(b.Clean(in), "index.html")
        } else {
-               name, ext := FileAndExt(in)
+               name, ext := FileAndExt(in, b)
                if name == "index" {
                        // /section/name/index.html -> /section/name/index.html
-                       return filepath.Clean(in)
+                       return b.Clean(in)
                } else {
                        // /section/name.html -> /section/name/index.html
-                       return filepath.Join(filepath.Dir(in), name, "index"+ext)
+                       return b.Join(b.Dir(in), name, "index"+ext)
                }
        }
 }
index 0da8835a2eaefb6f3e861243056c26ae770e48f7..52f8791741b44a1a4acca18b6ecce3861ee42d32 100644 (file)
@@ -461,7 +461,7 @@ func TestFileAndExt(t *testing.T) {
        }
 
        for i, d := range data {
-               file, ext := FileAndExt(filepath.FromSlash(d.input))
+               file, ext := FileAndExt(filepath.FromSlash(d.input), filepathBridge)
                if d.expectedFile != file {
                        t.Errorf("Test %d failed. Expected filename %q got %q.", i, d.expectedFile, file)
                }
index 558ed9c97408f0b2cd8bffb89f73450e861edab0..e4db6ceb7b2d348cc48e208caf04f91604186e7d 100644 (file)
@@ -22,6 +22,35 @@ import (
        "strings"
 )
 
+type PathBridge struct {
+}
+
+func (PathBridge) Base(in string) string {
+       return path.Base(in)
+}
+
+func (PathBridge) Clean(in string) string {
+       return path.Clean(in)
+}
+
+func (PathBridge) Dir(in string) string {
+       return path.Dir(in)
+}
+
+func (PathBridge) Ext(in string) string {
+       return path.Ext(in)
+}
+
+func (PathBridge) Join(elem ...string) string {
+       return path.Join(elem...)
+}
+
+func (PathBridge) Separator() string {
+       return "/"
+}
+
+var pathBridge PathBridge
+
 // SanitizeUrl sanitizes the input URL string.
 func SanitizeUrl(in string) string {
        url, err := purell.NormalizeURLString(in, purell.FlagsSafe|purell.FlagRemoveTrailingSlash|purell.FlagRemoveDotSegments|purell.FlagRemoveDuplicateSlashes|purell.FlagRemoveUnnecessaryHostDots|purell.FlagRemoveEmptyPortSeparator)
@@ -141,22 +170,7 @@ func PrettifyUrl(in string) string {
 //     /section/name/           becomes /section/name/index.html
 //     /section/name/index.html becomes /section/name/index.html
 func PrettifyUrlPath(in string) string {
-       if path.Ext(in) == "" {
-               // /section/name/  -> /section/name/index.html
-               if len(in) < 2 {
-                       return "/"
-               }
-               return path.Join(path.Clean(in), "index.html")
-       } else {
-               name, ext := ResourceAndExt(in)
-               if name == "index" {
-                       // /section/name/index.html -> /section/name/index.html
-                       return path.Clean(in)
-               } else {
-                       // /section/name.html -> /section/name/index.html
-                       return path.Join(path.Dir(in), name, "index"+ext)
-               }
-       }
+       return PrettiyPath(in, pathBridge)
 }
 
 // Uglify does the opposite of PrettifyUrlPath().
@@ -171,7 +185,7 @@ func Uglify(in string) string {
                // /section/name/  -> /section/name.html
                return path.Clean(in) + ".html"
        } else {
-               name, ext := ResourceAndExt(in)
+               name, ext := FileAndExt(in, pathBridge)
                if name == "index" {
                        // /section/name/index.html -> /section/name.html
                        d := path.Dir(in)
@@ -186,11 +200,3 @@ func Uglify(in string) string {
                }
        }
 }
-
-// Same as FileAndExt, but for URLs.
-func ResourceAndExt(in string) (name string, ext string) {
-       ext = path.Ext(in)
-       base := path.Base(in)
-
-       return extractFilename(in, ext, base, "/"), ext
-}