diff --git a/README.md b/README.md index f0dc5ab..6974b94 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ Here is a list of functions in [strings](http://golang.org/pkg/strings) and [xst | [Len](https://godoc.org/github.com/huandu/xstrings#Len) | `mb_strlen` in PHP | [#23](https://github.com/huandu/xstrings/issues/23) | | [Partition](https://godoc.org/github.com/huandu/xstrings#Partition) | `str.partition` in Python; `String#partition` in Ruby | [#10](https://github.com/huandu/xstrings/issues/10) | | [Reverse](https://godoc.org/github.com/huandu/xstrings#Reverse) | `String#reverse` in Ruby; `strrev` in PHP; `reverse` in Perl | [#7](https://github.com/huandu/xstrings/issues/7) | +| [RightJustify](https://godoc.org/github.com/huandu/xstrings#RightJustify) | `str.rjust` in Python; `String#rjust` in Ruby | [#29](https://github.com/huandu/xstrings/issues/29) | | [RuneWidth](https://godoc.org/github.com/huandu/xstrings#RuneWidth) | - | [#27](https://github.com/huandu/xstrings/issues/27) | | [Scrub](https://godoc.org/github.com/huandu/xstrings#Scrub) | `String#scrub` in Ruby | [#20](https://github.com/huandu/xstrings/issues/20) | | [Shuffle](https://godoc.org/github.com/huandu/xstrings#Shuffle) | `str_shuffle` in PHP | [#13](https://github.com/huandu/xstrings/issues/13) | diff --git a/format.go b/format.go index 4d2b3ff..00a3a91 100644 --- a/format.go +++ b/format.go @@ -112,3 +112,47 @@ func LeftJustify(str string, length int, pad string) string { return output.String() } + +// RightJustify returns a string with pad string at left side if str's rune length is smaller than length. +// If str's rune length is larger than length, str itself will be returned. +// +// If pad is an empty string, str will be returned. +// +// Samples: +// LeftJustify("hello", 4, " ") => "hello" +// LeftJustify("hello", 10, " ") => " hello" +// LeftJustify("hello", 10, "123") => "12312hello" +func RightJustify(str string, length int, pad string) string { + l := Len(str) + + if l >= length || pad == "" { + return str + } + + var r rune + var size int + + paddingLen := Len(pad) + remains := length - l + repeats := remains / paddingLen + + output := &bytes.Buffer{} + output.Grow(len(str) + (repeats+1)*len(pad)) + + for i := 0; i < repeats; i++ { + output.WriteString(pad) + } + + remains = remains % paddingLen + + if remains != 0 { + for i := 0; i < remains; i++ { + r, size = utf8.DecodeRuneInString(pad) + output.WriteRune(r) + pad = pad[size:] + } + } + + output.WriteString(str) + return output.String() +} diff --git a/format_test.go b/format_test.go index 19bb02b..1f368ff 100644 --- a/format_test.go +++ b/format_test.go @@ -56,3 +56,24 @@ func TestLeftJustify(t *testing.T) { sep("hello中文test", "18", ""): "hello中文test", }) } + +func TestRightJustify(t *testing.T) { + runner := func(str string) string { + input := strings.Split(str, separator) + n, _ := strconv.Atoi(input[1]) + return RightJustify(input[0], n, input[2]) + } + + runTestCases(t, runner, _M{ + sep("hello", "4", " "): "hello", + sep("hello", "10", " "): " hello", + sep("hello", "10", "123"): "12312hello", + + sep("hello中文test", "4", " "): "hello中文test", + sep("hello中文test", "12", " "): " hello中文test", + sep("hello中文test", "18", "测试!"): "测试!测试!测hello中文test", + + sep("hello中文test", "0", "123"): "hello中文test", + sep("hello中文test", "18", ""): "hello中文test", + }) +}