Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd7b42a8

Browse files
committed
feat(coderd/util/strings): add TruncateOption to Truncate
1 parent4b74e14 commitd7b42a8

File tree

2 files changed

+91
-11
lines changed

2 files changed

+91
-11
lines changed

‎coderd/util/strings/strings.go‎

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,64 @@ func JoinWithConjunction(s []string) string {
2323
)
2424
}
2525

26-
// Truncate returns the first n characters of s.
27-
funcTruncate(sstring,nint)string {
26+
typeTruncateOptionint
27+
28+
func (oTruncateOption)String()string {
29+
switcho {
30+
caseTruncateWithEllipsis:
31+
return"TruncateWithEllipsis"
32+
caseTruncateWithFullWords:
33+
return"TruncateWithFullWords"
34+
default:
35+
returnfmt.Sprintf("TruncateOption(%d)",o)
36+
}
37+
}
38+
39+
const (
40+
// TruncateWithEllipsis adds a Unicode ellipsis character to the end of the string.
41+
TruncateWithEllipsisTruncateOption=1
42+
// TruncateWithFullWords ensures that words are not split in the middle.
43+
// As a special case, if there is no word boundary, the string is truncated.
44+
TruncateWithFullWordsTruncateOption=2
45+
)
46+
47+
// Truncate truncates s to n characters.
48+
// Additional behaviors can be specified using TruncateOptions.
49+
funcTruncate(sstring,nint,opts...TruncateOption)string {
50+
varoptionsTruncateOption
51+
for_,opt:=rangeopts {
52+
options|=opt
53+
}
2854
ifn<1 {
2955
return""
3056
}
3157
iflen(s)<=n {
3258
returns
3359
}
34-
returns[:n]
60+
61+
maxLen:=n
62+
ifoptions&TruncateWithEllipsis!=0 {
63+
maxLen--
64+
}
65+
varsb strings.Builder
66+
// If we need to truncate to full words, find the last word boundary before n.
67+
ifoptions&TruncateWithFullWords!=0 {
68+
lastWordBoundary:=strings.LastIndexFunc(s[:maxLen],unicode.IsSpace)
69+
iflastWordBoundary<0 {
70+
// We cannot find a word boundary. At this point, we'll truncate the string.
71+
// It's better than nothing.
72+
_,_=sb.WriteString(s[:maxLen])
73+
}else {// lastWordBoundary <= maxLen
74+
_,_=sb.WriteString(s[:lastWordBoundary])
75+
}
76+
}else {
77+
_,_=sb.WriteString(s[:maxLen])
78+
}
79+
80+
ifoptions&TruncateWithEllipsis!=0 {
81+
_,_=sb.WriteString("…")
82+
}
83+
returnsb.String()
3584
}
3685

3786
varbmPolicy=bluemonday.StrictPolicy()

‎coderd/util/strings/strings_test.go‎

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package strings_test
22

33
import (
4+
"fmt"
45
"testing"
56

67
"github.com/stretchr/testify/assert"
@@ -23,17 +24,47 @@ func TestTruncate(t *testing.T) {
2324
sstring
2425
nint
2526
expectedstring
27+
options []strings.TruncateOption
2628
}{
27-
{"foo",4,"foo"},
28-
{"foo",3,"foo"},
29-
{"foo",2,"fo"},
30-
{"foo",1,"f"},
31-
{"foo",0,""},
32-
{"foo",-1,""},
29+
{"foo",4,"foo",nil},
30+
{"foo",3,"foo",nil},
31+
{"foo",2,"fo",nil},
32+
{"foo",1,"f",nil},
33+
{"foo",0,"",nil},
34+
{"foo",-1,"",nil},
35+
{"foo bar",7,"foo bar", []strings.TruncateOption{strings.TruncateWithEllipsis}},
36+
{"foo bar",6,"foo b…", []strings.TruncateOption{strings.TruncateWithEllipsis}},
37+
{"foo bar",5,"foo …", []strings.TruncateOption{strings.TruncateWithEllipsis}},
38+
{"foo bar",4,"foo…", []strings.TruncateOption{strings.TruncateWithEllipsis}},
39+
{"foo bar",3,"fo…", []strings.TruncateOption{strings.TruncateWithEllipsis}},
40+
{"foo bar",2,"f…", []strings.TruncateOption{strings.TruncateWithEllipsis}},
41+
{"foo bar",1,"…", []strings.TruncateOption{strings.TruncateWithEllipsis}},
42+
{"foo bar",0,"", []strings.TruncateOption{strings.TruncateWithEllipsis}},
43+
{"foo bar",7,"foo bar", []strings.TruncateOption{strings.TruncateWithFullWords}},
44+
{"foo bar",6,"foo", []strings.TruncateOption{strings.TruncateWithFullWords}},
45+
{"foo bar",5,"foo", []strings.TruncateOption{strings.TruncateWithFullWords}},
46+
{"foo bar",4,"foo", []strings.TruncateOption{strings.TruncateWithFullWords}},
47+
{"foo bar",3,"foo", []strings.TruncateOption{strings.TruncateWithFullWords}},
48+
{"foo bar",2,"fo", []strings.TruncateOption{strings.TruncateWithFullWords}},
49+
{"foo bar",1,"f", []strings.TruncateOption{strings.TruncateWithFullWords}},
50+
{"foo bar",0,"", []strings.TruncateOption{strings.TruncateWithFullWords}},
51+
{"foo bar",7,"foo bar", []strings.TruncateOption{strings.TruncateWithFullWords,strings.TruncateWithEllipsis}},
52+
{"foo bar",6,"foo…", []strings.TruncateOption{strings.TruncateWithFullWords,strings.TruncateWithEllipsis}},
53+
{"foo bar",5,"foo…", []strings.TruncateOption{strings.TruncateWithFullWords,strings.TruncateWithEllipsis}},
54+
{"foo bar",4,"foo…", []strings.TruncateOption{strings.TruncateWithFullWords,strings.TruncateWithEllipsis}},
55+
{"foo bar",3,"fo…", []strings.TruncateOption{strings.TruncateWithFullWords,strings.TruncateWithEllipsis}},
56+
{"foo bar",2,"f…", []strings.TruncateOption{strings.TruncateWithFullWords,strings.TruncateWithEllipsis}},
57+
{"foo bar",1,"…", []strings.TruncateOption{strings.TruncateWithFullWords,strings.TruncateWithEllipsis}},
58+
{"foo bar",0,"", []strings.TruncateOption{strings.TruncateWithFullWords,strings.TruncateWithEllipsis}},
59+
{"This is a very long task prompt that should be truncated to 160 characters. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",160,"This is a very long task prompt that should be truncated to 160 characters. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor…", []strings.TruncateOption{strings.TruncateWithFullWords,strings.TruncateWithEllipsis}},
3360
} {
34-
t.Run(tt.expected,func(t*testing.T) {
61+
tName:=fmt.Sprintf("%s_%d",tt.s,tt.n)
62+
for_,opt:=rangett.options {
63+
tName+=fmt.Sprintf("_%v",opt)
64+
}
65+
t.Run(tName,func(t*testing.T) {
3566
t.Parallel()
36-
actual:=strings.Truncate(tt.s,tt.n)
67+
actual:=strings.Truncate(tt.s,tt.n,tt.options...)
3768
require.Equal(t,tt.expected,actual)
3869
})
3970
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp