| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | // Package strmutil provides string manipulation utilities. |
| 4 | package strmutil |
| 5 | |
| 6 | import "unicode/utf8" |
| 7 | |
| 8 | // TruncateText limits text length to maxLen bytes. |
| 9 | // UTF-8 safe - does not split multi-byte characters. |
| 10 | // Appends "..." when truncation occurs. |
| 11 | func TruncateText(text string, maxLen int) string { |
| 12 | if maxLen <= 0 { |
| 13 | return "" |
| 14 | } |
| 15 | if len(text) <= maxLen { |
| 16 | return text |
| 17 | } |
| 18 | // UTF-8 safe truncation |
| 19 | cutoff := 0 |
| 20 | ellipsis := "..." |
| 21 | reserveForEllipsis := 3 |
| 22 | if maxLen < 3 { |
| 23 | // Too small for ellipsis - just truncate without it |
| 24 | ellipsis = "" |
| 25 | reserveForEllipsis = 0 |
| 26 | } |
| 27 | for i := 0; i < len(text); { |
| 28 | _, size := utf8.DecodeRuneInString(text[i:]) |
| 29 | if cutoff+size > maxLen-reserveForEllipsis { |
| 30 | break |
| 31 | } |
| 32 | cutoff += size |
| 33 | i += size |
| 34 | } |
| 35 | return text[:cutoff] + ellipsis |
| 36 | } |