Skip to content

Commit 3c1b7cd

Browse files
authored
refactor: Move prefix ordering logic to a separate type to better encapsulate it. (#85)
1 parent debebf9 commit 3c1b7cd

File tree

2 files changed

+45
-23
lines changed

2 files changed

+45
-23
lines changed

keepsorted/block.go

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -407,31 +407,13 @@ func (b block) lessFn() cmpFunc[lineGroup] {
407407
return b.metadata.opts.regexTransform(lg.joinedLines())
408408
}
409409

410-
// Assign a weight to each prefix so that they will be sorted into their
411-
// predetermined order.
412-
// Weights are negative so that entries with matching prefixes are put before
413-
// any non-matching line (which will have a weight of 0).
414-
//
415-
// An empty prefix can be used to move "non-matching" entries to a position
416-
// between other prefixes.
417-
prefixWeights := make(map[string]int)
418-
for i, p := range b.metadata.opts.PrefixOrder {
419-
prefixWeights[p] = i - len(b.metadata.opts.PrefixOrder)
420-
}
421-
// Sort prefixes longest -> shortest to find the most appropriate weight.
422-
longestFirst := comparing(func(s string) int { return len(s) }).reversed()
423-
prefixes := slices.SortedStableFunc(slices.Values(b.metadata.opts.PrefixOrder), longestFirst)
424-
425-
prefixOrder := comparing(func(s []string) int {
410+
ord := newPrefixOrder(b.metadata.opts)
411+
prefixOrder := comparingFunc(func(s []string) orderedPrefix {
426412
if len(s) == 0 {
427-
return 0
413+
return orderedPrefix{}
428414
}
429-
p, ok := b.metadata.opts.hasPrefix(s[0], slices.Values(prefixes))
430-
if !ok {
431-
return 0
432-
}
433-
return prefixWeights[p]
434-
})
415+
return ord.match(s[0])
416+
}, orderedPrefix.compare)
435417

436418
// Combinations of switches (for example, case-insensitive and numeric
437419
// ordering) which must be applied to create a single comparison key,

keepsorted/options.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package keepsorted
1616

1717
import (
18+
"cmp"
1819
"errors"
1920
"fmt"
2021
"iter"
@@ -493,3 +494,42 @@ func (t numericTokens) compare(o numericTokens) int {
493494
// smaller is less than the other.
494495
return t.len() - o.len()
495496
}
497+
498+
type prefixOrder struct {
499+
opts blockOptions
500+
prefixWeights map[string]int
501+
prefixes []string
502+
}
503+
504+
func newPrefixOrder(opts blockOptions) *prefixOrder {
505+
// Assign a weight to each prefix so that they will be sorted into their
506+
// predetermined order.
507+
// Weights are negative so that entries with matching prefixes are put before
508+
// any non-matching line (which will have a weight of 0).
509+
//
510+
// An empty prefix can be used to move "non-matching" entries to a position
511+
// between other prefixes.
512+
prefixWeights := make(map[string]int)
513+
for i, p := range opts.PrefixOrder {
514+
prefixWeights[p] = i - len(opts.PrefixOrder)
515+
}
516+
// Sort prefixes longest -> shortest to find the most appropriate weight.
517+
longestFirst := comparing(func(s string) int { return len(s) }).reversed()
518+
prefixes := slices.SortedStableFunc(slices.Values(opts.PrefixOrder), longestFirst)
519+
520+
return &prefixOrder{opts, prefixWeights, prefixes}
521+
}
522+
523+
func (o prefixOrder) match(s string) orderedPrefix {
524+
pre, _ := o.opts.hasPrefix(s, slices.Values(o.prefixes))
525+
return orderedPrefix{pre, o.prefixWeights[pre]}
526+
}
527+
528+
type orderedPrefix struct {
529+
prefix string
530+
weight int
531+
}
532+
533+
func (pre orderedPrefix) compare(other orderedPrefix) int {
534+
return cmp.Compare(pre.weight, other.weight)
535+
}

0 commit comments

Comments
 (0)