From c05f8f773150b4686420927535ebf9d93b71d0bb Mon Sep 17 00:00:00 2001 From: Employee 427 Date: Thu, 16 Apr 2026 21:56:49 +0000 Subject: [PATCH 1/2] refactor: replace custom sort types with slices.SortFunc Replace four custom sort types (byName, byNameDirFirst, bySize, byTime) and their Len/Swap/Less boilerplate with slices.SortFunc calls. Remove the "sort" import since slices was already in use. Generated-By: PostHog Code Task-Id: ebf74917-a9d2-4455-b94a-776bbdb1036b --- .../caddyhttp/fileserver/browsetplcontext.go | 114 ++++++------------ 1 file changed, 38 insertions(+), 76 deletions(-) diff --git a/modules/caddyhttp/fileserver/browsetplcontext.go b/modules/caddyhttp/fileserver/browsetplcontext.go index b9489c6a6dc..848484a1f01 100644 --- a/modules/caddyhttp/fileserver/browsetplcontext.go +++ b/modules/caddyhttp/fileserver/browsetplcontext.go @@ -15,6 +15,7 @@ package fileserver import ( + "cmp" "context" "io/fs" "net/url" @@ -22,7 +23,6 @@ import ( "path" "path/filepath" "slices" - "sort" "strconv" "strings" "time" @@ -221,28 +221,44 @@ func (l *browseTemplateContext) applySortAndLimit(sortParam, orderParam, limitPa l.Sort = sortParam l.Order = orderParam + switch l.Sort { + case sortByName: + slices.SortFunc(l.Items, func(a, b fileInfo) int { + return cmp.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name)) + }) + case sortByNameDirFirst: + slices.SortFunc(l.Items, func(a, b fileInfo) int { + if a.IsDir != b.IsDir { + if a.IsDir { + return -1 + } + return 1 + } + return cmp.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name)) + }) + case sortBySize: + slices.SortFunc(l.Items, func(a, b fileInfo) int { + const directoryOffset = -1 << 31 + aSize, bSize := a.Size, b.Size + if a.IsDir { + aSize = directoryOffset + } + if b.IsDir { + bSize = directoryOffset + } + if a.IsDir && b.IsDir { + return cmp.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name)) + } + return cmp.Compare(aSize, bSize) + }) + case sortByTime: + slices.SortFunc(l.Items, func(a, b fileInfo) int { + return a.ModTime.Compare(b.ModTime) + }) + } + if l.Order == "desc" { - switch l.Sort { - case sortByName: - sort.Sort(sort.Reverse(byName(*l))) - case sortByNameDirFirst: - sort.Sort(sort.Reverse(byNameDirFirst(*l))) - case sortBySize: - sort.Sort(sort.Reverse(bySize(*l))) - case sortByTime: - sort.Sort(sort.Reverse(byTime(*l))) - } - } else { - switch l.Sort { - case sortByName: - sort.Sort(byName(*l)) - case sortByNameDirFirst: - sort.Sort(byNameDirFirst(*l)) - case sortBySize: - sort.Sort(bySize(*l)) - case sortByTime: - sort.Sort(byTime(*l)) - } + slices.Reverse(l.Items) } if offsetParam != "" { @@ -318,60 +334,6 @@ func (fi fileInfo) HumanModTime(format string) string { return fi.ModTime.Format(format) } -type ( - byName browseTemplateContext - byNameDirFirst browseTemplateContext - bySize browseTemplateContext - byTime browseTemplateContext -) - -func (l byName) Len() int { return len(l.Items) } -func (l byName) Swap(i, j int) { l.Items[i], l.Items[j] = l.Items[j], l.Items[i] } - -func (l byName) Less(i, j int) bool { - return strings.ToLower(l.Items[i].Name) < strings.ToLower(l.Items[j].Name) -} - -func (l byNameDirFirst) Len() int { return len(l.Items) } -func (l byNameDirFirst) Swap(i, j int) { l.Items[i], l.Items[j] = l.Items[j], l.Items[i] } - -func (l byNameDirFirst) Less(i, j int) bool { - // sort by name if both are dir or file - if l.Items[i].IsDir == l.Items[j].IsDir { - return strings.ToLower(l.Items[i].Name) < strings.ToLower(l.Items[j].Name) - } - // sort dir ahead of file - return l.Items[i].IsDir -} - -func (l bySize) Len() int { return len(l.Items) } -func (l bySize) Swap(i, j int) { l.Items[i], l.Items[j] = l.Items[j], l.Items[i] } - -func (l bySize) Less(i, j int) bool { - const directoryOffset = -1 << 31 // = -math.MinInt32 - - iSize, jSize := l.Items[i].Size, l.Items[j].Size - - // directory sizes depend on the file system; to - // provide a consistent experience, put them up front - // and sort them by name - if l.Items[i].IsDir { - iSize = directoryOffset - } - if l.Items[j].IsDir { - jSize = directoryOffset - } - if l.Items[i].IsDir && l.Items[j].IsDir { - return strings.ToLower(l.Items[i].Name) < strings.ToLower(l.Items[j].Name) - } - - return iSize < jSize -} - -func (l byTime) Len() int { return len(l.Items) } -func (l byTime) Swap(i, j int) { l.Items[i], l.Items[j] = l.Items[j], l.Items[i] } -func (l byTime) Less(i, j int) bool { return l.Items[i].ModTime.Before(l.Items[j].ModTime) } - const ( sortByName = "name" sortByNameDirFirst = "namedirfirst" From c85b7bc1b8316b6a6bd5cad10f6f0cf0b4df067a Mon Sep 17 00:00:00 2001 From: Employee 427 Date: Thu, 16 Apr 2026 22:04:57 +0000 Subject: [PATCH 2/2] refactor: extract named comparison functions for readability Move sort comparison logic into named package-level functions (compareByName, compareByNameDirFirst, compareBySize, compareByTime) so applySortAndLimit reads cleanly as a simple switch statement. Generated-By: PostHog Code Task-Id: ebf74917-a9d2-4455-b94a-776bbdb1036b --- .../caddyhttp/fileserver/browsetplcontext.go | 72 +++++++++++-------- 1 file changed, 43 insertions(+), 29 deletions(-) diff --git a/modules/caddyhttp/fileserver/browsetplcontext.go b/modules/caddyhttp/fileserver/browsetplcontext.go index 848484a1f01..eb4828e3af4 100644 --- a/modules/caddyhttp/fileserver/browsetplcontext.go +++ b/modules/caddyhttp/fileserver/browsetplcontext.go @@ -223,38 +223,13 @@ func (l *browseTemplateContext) applySortAndLimit(sortParam, orderParam, limitPa switch l.Sort { case sortByName: - slices.SortFunc(l.Items, func(a, b fileInfo) int { - return cmp.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name)) - }) + slices.SortFunc(l.Items, compareByName) case sortByNameDirFirst: - slices.SortFunc(l.Items, func(a, b fileInfo) int { - if a.IsDir != b.IsDir { - if a.IsDir { - return -1 - } - return 1 - } - return cmp.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name)) - }) + slices.SortFunc(l.Items, compareByNameDirFirst) case sortBySize: - slices.SortFunc(l.Items, func(a, b fileInfo) int { - const directoryOffset = -1 << 31 - aSize, bSize := a.Size, b.Size - if a.IsDir { - aSize = directoryOffset - } - if b.IsDir { - bSize = directoryOffset - } - if a.IsDir && b.IsDir { - return cmp.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name)) - } - return cmp.Compare(aSize, bSize) - }) + slices.SortFunc(l.Items, compareBySize) case sortByTime: - slices.SortFunc(l.Items, func(a, b fileInfo) int { - return a.ModTime.Compare(b.ModTime) - }) + slices.SortFunc(l.Items, compareByTime) } if l.Order == "desc" { @@ -334,6 +309,45 @@ func (fi fileInfo) HumanModTime(format string) string { return fi.ModTime.Format(format) } +func compareByName(a, b fileInfo) int { + return cmp.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name)) +} + +func compareByNameDirFirst(a, b fileInfo) int { + if a.IsDir != b.IsDir { + if a.IsDir { + return -1 + } + return 1 + } + return cmp.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name)) +} + +func compareBySize(a, b fileInfo) int { + const directoryOffset = -1 << 31 // = -math.MinInt32 + + aSize, bSize := a.Size, b.Size + + // directory sizes depend on the file system; to + // provide a consistent experience, put them up front + // and sort them by name + if a.IsDir { + aSize = directoryOffset + } + if b.IsDir { + bSize = directoryOffset + } + if a.IsDir && b.IsDir { + return cmp.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name)) + } + + return cmp.Compare(aSize, bSize) +} + +func compareByTime(a, b fileInfo) int { + return a.ModTime.Compare(b.ModTime) +} + const ( sortByName = "name" sortByNameDirFirst = "namedirfirst"