From 9ae02307d62c2b60c0bbcbdd2c9420b7b9345296 Mon Sep 17 00:00:00 2001 From: "John R. Lenton" Date: Thu, 22 Nov 2018 16:20:17 +0000 Subject: strutil: add ElliptRight --- strutil/strutil.go | 16 ++++++++++++++++ strutil/strutil_test.go | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/strutil/strutil.go b/strutil/strutil.go index 5564b5b170..e794ab27ff 100644 --- a/strutil/strutil.go +++ b/strutil/strutil.go @@ -27,6 +27,7 @@ import ( "strings" "time" "unicode" + "unicode/utf8" ) func init() { @@ -182,3 +183,18 @@ func CommaSeparatedList(str string) []string { } return filtered } + +// ElliptRight returns a string that is at most n runes long, +// replacing the last rune with an ellipsis if necessary. If N is less +// than 1 it's treated as a 1. +func ElliptRight(str string, n int) string { + if n < 1 { + n = 1 + } + if utf8.RuneCountInString(str) <= n { + return str + } + + // this is expensive; look into a cheaper way maybe sometime + return string([]rune(str)[:n-1]) + "…" +} diff --git a/strutil/strutil_test.go b/strutil/strutil_test.go index bf7ae4d442..70d4aa7b3e 100644 --- a/strutil/strutil_test.go +++ b/strutil/strutil_test.go @@ -200,3 +200,25 @@ func (strutilSuite) TestCommaSeparatedList(c *check.C) { c.Check(strutil.CommaSeparatedList(test.in), check.DeepEquals, test.out, check.Commentf("%q", test.in)) } } + +func (strutilSuite) TestElliptRight(c *check.C) { + type T struct { + in string + n int + out string + } + for _, t := range []T{ + {"", 10, ""}, + {"", -1, ""}, + {"hello", 10, "hello"}, + {"hello", 5, "hello"}, + {"hello", 3, "he…"}, + {"hello", 0, "…"}, + {"héllo", 4, "hé…"}, + {"héllo", 3, "he…"}, + {"he🐧lo", 4, "he🐧…"}, + {"he🐧lo", 3, "he…"}, + } { + c.Check(strutil.ElliptRight(t.in, t.n), check.Equals, t.out, check.Commentf("%q[:%d] -> %q", t.in, t.n, t.out)) + } +} -- cgit v1.2.3