Files
2025-04-10 20:57:42 +03:00

66 lines
1.6 KiB
Go

package safepath
import (
"fmt"
"path"
"strings"
)
// IsDir returns true if the filePath ends with a slash.
// Empty string is considered a directory.
func IsDir(filePath string) bool {
if filePath == "" || filePath == "." {
return true
}
return strings.HasSuffix(filePath, "/")
}
// Dir behaves exactly as path.Dir, but returns "" for the root directory.
// and returns a trailing slash for all other directories.
func Dir(filePath string) string {
if filePath == "" {
return ""
}
// Trim trailing slash before getting the directory
cleanPath := strings.TrimSuffix(filePath, "/")
dir := path.Dir(cleanPath)
if dir == "." || dir == "/" {
return ""
}
return dir + "/"
}
// InDir returns true if the filePath is a subdirectory of the given directory.
func InDir(filePath, dir string) bool {
return strings.HasPrefix(filePath, dir)
}
// RelativeTo returns the relative path of the filePath to the given directory.
// It handles cases where either filePath or dir have leading or trailing slashes.
func RelativeTo(filePath, dir string) (string, error) {
if dir == "/" || dir == "" {
return filePath, nil
}
// Normalize paths by trimming leading and trailing slashes
normalizedDir := strings.Trim(dir, "/")
if normalizedDir != "" {
normalizedDir += "/"
}
normalizedPath := strings.TrimPrefix(filePath, "/")
// Check if the normalized path is in the normalized directory
if !strings.HasPrefix(normalizedPath, normalizedDir) {
return "", fmt.Errorf("filePath is not a subdirectory of dir")
}
// Get the relative path by trimming the directory prefix
relativePath := strings.TrimPrefix(normalizedPath, normalizedDir)
return relativePath, nil
}