Introduce FilepathPathBridge

This commit introduces the new interface FilepathPathBridge to remove some code that differs only in their use of either the path or filepath package.
This commit is contained in:
bep 2015-01-27 11:44:41 +01:00
parent 5f9596e68c
commit bedc2d8488
3 changed files with 85 additions and 37 deletions

View 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)
}
}
}

View 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)
}

View 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
}