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))
|
||||
}
|
||||
}
|
||||
|
||||
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",
|
||||
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