mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-25 07:00:48 +09:00
3739def43f
Use rune-aware truncation for user-facing text and log previews so multibyte content is not corrupted in memory context, Telegram messages, or diagnostics.
53 lines
1.2 KiB
Go
53 lines
1.2 KiB
Go
package textutil
|
|
|
|
import "unicode/utf8"
|
|
|
|
// TruncateRunes returns s truncated to at most maxRunes Unicode code points.
|
|
func TruncateRunes(s string, maxRunes int) string {
|
|
if maxRunes <= 0 || s == "" {
|
|
return ""
|
|
}
|
|
cut, truncated := byteIndexAfterRunes(s, maxRunes)
|
|
if !truncated {
|
|
return s
|
|
}
|
|
return s[:cut]
|
|
}
|
|
|
|
// TruncateRunesWithSuffix returns s truncated to at most maxRunes Unicode code
|
|
// points, appending suffix when truncation occurs.
|
|
func TruncateRunesWithSuffix(s string, maxRunes int, suffix string) string {
|
|
if maxRunes <= 0 || s == "" {
|
|
return ""
|
|
}
|
|
if _, truncated := byteIndexAfterRunes(s, maxRunes); !truncated {
|
|
return s
|
|
}
|
|
if suffix == "" {
|
|
return TruncateRunes(s, maxRunes)
|
|
}
|
|
suffixRunes := utf8.RuneCountInString(suffix)
|
|
if suffixRunes >= maxRunes {
|
|
return TruncateRunes(s, maxRunes)
|
|
}
|
|
cut, truncated := byteIndexAfterRunes(s, maxRunes-suffixRunes)
|
|
if !truncated {
|
|
return s
|
|
}
|
|
return s[:cut] + suffix
|
|
}
|
|
|
|
func byteIndexAfterRunes(s string, maxRunes int) (int, bool) {
|
|
if maxRunes <= 0 || s == "" {
|
|
return 0, len(s) > 0
|
|
}
|
|
count := 0
|
|
for i := range s {
|
|
if count == maxRunes {
|
|
return i, true
|
|
}
|
|
count++
|
|
}
|
|
return len(s), false
|
|
}
|