Crosspath: add IsRoot(path) bool
function
Add a function that can determine whether the given path is considered a "root path". Considers `/`, `X:`, `X:\` and `X:/` root paths, where `X` is any upper or lower case Latin letters.
This commit is contained in:
parent
b441f3f3de
commit
fd730351b5
@ -75,3 +75,32 @@ func ToNative(path string) string {
|
|||||||
panic(fmt.Sprintf("this platform has an unknown path separator: %q", filepath.Separator))
|
panic(fmt.Sprintf("this platform has an unknown path separator: %q", filepath.Separator))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validDriveLetter(r rune) bool {
|
||||||
|
return ('A' <= r && r <= 'Z') || ('a' <= r && r <= 'z')
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsRoot returns whether the given path is a root path or not.
|
||||||
|
// Paths "/", "C:", "C:\", and "C:/" are considered root, for all latin drive
|
||||||
|
// letters A-Z.
|
||||||
|
//
|
||||||
|
// NOTE: this does NOT resolve symlinks or `..` entries.
|
||||||
|
func IsRoot(path string) bool {
|
||||||
|
switch {
|
||||||
|
case path == "":
|
||||||
|
return false
|
||||||
|
case path == "/":
|
||||||
|
return true
|
||||||
|
// From here on, it can only be a DOS root, so must have a drive letter and a colon.
|
||||||
|
case len(path) < 2, len(path) > 3:
|
||||||
|
return false
|
||||||
|
case path[1] != ':':
|
||||||
|
return false
|
||||||
|
// C:\ and C:/ are both considered roots.
|
||||||
|
case len(path) == 3 && path[2] != '/' && path[2] != '\\':
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
runes := []rune(path)
|
||||||
|
return validDriveLetter(runes[0])
|
||||||
|
}
|
||||||
|
@ -169,3 +169,34 @@ func TestToNative_unsupported(t *testing.T) {
|
|||||||
t.Fatalf("ToNative not supported on this platform %q with path separator %q",
|
t.Fatalf("ToNative not supported on this platform %q with path separator %q",
|
||||||
runtime.GOOS, filepath.Separator)
|
runtime.GOOS, filepath.Separator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsRoot(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
path string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{"empty", "", false},
|
||||||
|
|
||||||
|
{"UNIX", "/", true},
|
||||||
|
{"Drive only", "C:", true},
|
||||||
|
{"Drive and slash", "C:/", true},
|
||||||
|
{"Drive and backslash", `C:\`, true},
|
||||||
|
|
||||||
|
{"backslash", `\`, false},
|
||||||
|
{"just letters", "just letters", false},
|
||||||
|
{"subdir of root", "/subdir", false},
|
||||||
|
{"subdir of drive", "C:\\subdir", false},
|
||||||
|
|
||||||
|
{"indirectly root", "/subdir/..", false},
|
||||||
|
{"UNC notation", `\\NAS\Share\`, false},
|
||||||
|
{"Slashed UNC notation", `//NAS/Share/`, false},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := IsRoot(tt.path); got != tt.want {
|
||||||
|
t.Errorf("IsRoot() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user