Skip to content

Commit

Permalink
👔 up: strutil - add some new method and add more unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Jun 29, 2023
1 parent e083d92 commit 7a83b80
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 103 deletions.
64 changes: 0 additions & 64 deletions arrutil/enum.go

This file was deleted.

154 changes: 154 additions & 0 deletions arrutil/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package arrutil

import (
"sort"
"strconv"
"strings"

"github.com/gookit/goutil/comdef"
)

// Ints type
type Ints []int

// String to string
func (is Ints) String() string {
ss := make([]string, len(is))
for i, iv := range is {
ss[i] = strconv.Itoa(iv)
}
return strings.Join(ss, ",")
}

// Has given element
func (is Ints) Has(i int) bool {
for _, iv := range is {
if i == iv {
return true
}
}
return false
}

// First element value.
func (is Ints) First() int {
if len(is) > 0 {
return is[0]
}
panic("empty int slice")
}

// Last element value.
func (is Ints) Last() int {
if len(is) > 0 {
return is[len(is)-1]
}
panic("empty int slice")
}

// Sort the int slice
func (is Ints) Sort() {
sort.Ints(is)
}

// Strings type
type Strings []string

// String to string
func (ss Strings) String() string {
return strings.Join(ss, ",")
}

// Join to string
func (ss Strings) Join(sep string) string {
return strings.Join(ss, sep)
}

// Has given element
func (ss Strings) Has(sub string) bool {
return ss.Contains(sub)
}

// Contains given element
func (ss Strings) Contains(sub string) bool {
for _, s := range ss {
if s == sub {
return true
}
}
return false
}

// First element value.
func (ss Strings) First() string {
if len(ss) > 0 {
return ss[0]
}
return ""
}

// ScalarList definition for any type
type ScalarList[T comdef.ScalarType] []T

// IsEmpty check
func (ls ScalarList[T]) IsEmpty() bool {
return len(ls) == 0
}

// String to string
func (ls ScalarList[T]) String() string {
return ToString(ls)
}

// Has given element
func (ls ScalarList[T]) Has(el T) bool {
return ls.Contains(el)
}

// Contains given element
func (ls ScalarList[T]) Contains(el T) bool {
for _, v := range ls {
if v == el {
return true
}
}
return false
}

// First element value.
func (ls ScalarList[T]) First() T {
if len(ls) > 0 {
return ls[0]
}
panic("empty list")
}

// Last element value.
func (ls ScalarList[T]) Last() T {
if ln := len(ls); ln > 0 {
return ls[ln-1]
}
panic("empty list")
}

// Remove given element
func (ls ScalarList[T]) Remove(el T) ScalarList[T] {
return Filter(ls, func(v T) bool {
return v != el
})
}

// Filter the slice, default will filter zero value.
func (ls ScalarList[T]) Filter(filter ...comdef.MatchFunc[T]) ScalarList[T] {
return Filter(ls, filter...)
}

// Map the slice to new slice. TODO syntax ERROR: Method cannot have type parameters
// func (ls ScalarList[T]) Map[V any](mapFn MapFn[T, V]) ScalarList[V] {
// return Map(ls, mapFn)
// }

// Sort the slice
// func (ls ScalarList[T]) Sort() {
// sort.Sort(ls)
// }
1 change: 1 addition & 0 deletions strutil/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ func TestToByteSize(t *testing.T) {
{12341739, "11.77 M"},
{1202590842, "1.12GB"},
{1231453023109, "1.12 TB"},
{1351079888211148, "1.2PB"},
}

for _, tt := range tests {
Expand Down
7 changes: 7 additions & 0 deletions strutil/ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,10 @@ func (b *Builder) WriteStrings(ss ...string) {
_, _ = b.Builder.WriteString(s)
}
}

// ResetGet return current string and reset builder
func (b *Builder) ResetGet() string {
s := b.String()
b.Reset()
return s
}
14 changes: 7 additions & 7 deletions strutil/ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,19 @@ func TestBuilder_WriteAny(t *testing.T) {

sb.Writef("ab-%s", "c")
sb.WriteByteNE('d')
assert.Eq(t, "ab-cd", sb.String())
sb.WriteMulti('-', 'e', 'f')
assert.Eq(t, "ab-cd-ef", sb.ResetGet())

sb.Reset()
sb.WriteStrings("ab", "-", "cd")
sb.WriteString("-ef")
assert.Eq(t, "ab-cd-ef", sb.String())
assert.Eq(t, "ab-cd-ef", sb.ResetGet())

sb.Reset()
sb.WriteAny("abc")
sb.WriteAnys(23, "def")
assert.Eq(t, "abc23def", sb.String())
assert.Eq(t, "abc23def", sb.ResetGet())

sb.Reset()
sb.Write([]byte("abc"))
sb.WriteRune('-')
sb.Writeln("abc")
assert.Eq(t, "abc\n", sb.String())
assert.Eq(t, "abc-abc\n", sb.ResetGet())
}
49 changes: 23 additions & 26 deletions strutil/padding.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,12 @@ func Resize(s string, length int, align PosFlag) string {
}

if align == PosMiddle {
strLn := len(s)
padLn := (length - strLn) / 2
padStr := string(make([]byte, padLn))

padLn := (length - len(s)) / 2
if diff := length - padLn*2; diff > 0 {
s += " "
}

padStr := string(RepeatBytes(' ', padLn))
return padStr + s + padStr
}

Expand All @@ -85,15 +84,19 @@ func PadChars[T byte | rune](cs []T, pad T, length int, pos PosFlag) []T {

idx := length - ln
ns := make([]T, length)
ps := RepeatChars(pad, idx)
if pos == PosRight {
copy(ns, cs)
copy(ns[idx:], ps)
} else { // to left
copy(ns[:idx], ps)
copy(ns[idx:], cs)
for i := ln; i < length; i++ {
ns[i] = pad
}
return ns
}

// to left
for i := 0; i < idx; i++ {
ns[i] = pad
}
copy(ns[idx:], cs)
return ns
}

Expand Down Expand Up @@ -131,42 +134,36 @@ func PadRunesRight(rs []rune, pad rune, length int) []rune {
* String repeat operation
*************************************************************/

// Repeat a string
// Repeat a string by given times.
func Repeat(s string, times int) string {
if times <= 0 {
return ""
}
if times == 1 {
if times <= 1 {
return s
}

ss := make([]string, 0, times)
var sb strings.Builder
sb.Grow(len(s) * times)

for i := 0; i < times; i++ {
ss = append(ss, s)
sb.WriteString(s)
}

return strings.Join(ss, "")
return sb.String()
}

// RepeatRune repeat a rune char.
func RepeatRune(char rune, times int) []rune {
return RepeatChars(char, times)
}
func RepeatRune(char rune, times int) []rune { return RepeatChars(char, times) }

// RepeatBytes repeat a byte char.
func RepeatBytes(char byte, times int) []byte {
return RepeatChars(char, times)
}
func RepeatBytes(char byte, times int) []byte { return RepeatChars(char, times) }

// RepeatChars repeat a byte char.
func RepeatChars[T byte | rune](char T, times int) []T {
if times <= 0 {
return make([]T, 0)
}

chars := make([]T, 0, times)
chars := make([]T, times)
for i := 0; i < times; i++ {
chars = append(chars, char)
chars[i] = char
}
return chars
}
Loading

0 comments on commit 7a83b80

Please sign in to comment.