mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-02 21:23:20 -04:00
The goutil that OpenCloud currently uses is one version from the release that adds FreeBSD support, this now compiles successfully on FreeBSD.
222 lines
5.6 KiB
Go
222 lines
5.6 KiB
Go
package strutil
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/gookit/goutil/comdef"
|
|
)
|
|
|
|
// PosFlag type
|
|
type PosFlag = comdef.Position
|
|
|
|
// Position for padding/resize string
|
|
const (
|
|
PosLeft PosFlag = iota
|
|
PosMiddle
|
|
PosRight
|
|
PosAuto
|
|
)
|
|
|
|
/*************************************************************
|
|
* String padding operation
|
|
*************************************************************/
|
|
|
|
// Padding Fill the string to the specified length.
|
|
//
|
|
// params:
|
|
// - s: 原始字符串
|
|
// - pad: 用于填充的字符或字符串
|
|
// - length: 目标长度
|
|
// - padPos: 填充位置标志(左填充或右填充)
|
|
func Padding(s, pad string, length int, padPos PosFlag) string {
|
|
return padding(s, pad, len(s), length, padPos)
|
|
}
|
|
|
|
// Utf8Padding Fill the string to the specified length. use utf8 width.
|
|
func Utf8Padding(s, pad string, wantLen int, padPos PosFlag) string {
|
|
return padding(s, pad, Utf8Width(s), wantLen, padPos)
|
|
}
|
|
|
|
func padding(s, pad string, sLen, wantLen int, padPos PosFlag) string {
|
|
diff := sLen - wantLen
|
|
if diff >= 0 { // do not need padding.
|
|
return s
|
|
}
|
|
|
|
// pad space.
|
|
if len(s) == sLen && (pad == "" || pad == " ") {
|
|
// Sprintf: 是按字数来填充的,不管中英文都是一个字符 - 有问题
|
|
if padPos == PosRight { // to right
|
|
return s + strings.Repeat(" ", -diff)
|
|
}
|
|
return strings.Repeat(" ", -diff) + s
|
|
}
|
|
|
|
// other character.
|
|
if padPos == PosRight { // to right
|
|
return s + Repeat(pad, -diff)
|
|
}
|
|
return Repeat(pad, -diff) + s
|
|
}
|
|
|
|
// PadLeft a string.
|
|
func PadLeft(s, pad string, length int) string {
|
|
return Padding(s, pad, length, PosLeft)
|
|
}
|
|
|
|
// PadRight a string.
|
|
func PadRight(s, pad string, length int) string {
|
|
return Padding(s, pad, length, PosRight)
|
|
}
|
|
|
|
// PadChars padding a rune/byte to want length and with position flag
|
|
func PadChars[T byte | rune](cs []T, pad T, length int, pos PosFlag) []T {
|
|
ln := len(cs)
|
|
if ln >= length {
|
|
ns := make([]T, length)
|
|
copy(ns, cs[:length])
|
|
return ns
|
|
}
|
|
|
|
idx := length - ln
|
|
ns := make([]T, length)
|
|
if pos == PosRight {
|
|
copy(ns, 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
|
|
}
|
|
|
|
// PadBytes padding a byte to want length and with position flag
|
|
func PadBytes(bs []byte, pad byte, length int, pos PosFlag) []byte {
|
|
return PadChars(bs, pad, length, pos)
|
|
}
|
|
|
|
// PadBytesLeft a byte to want length
|
|
func PadBytesLeft(bs []byte, pad byte, length int) []byte {
|
|
return PadChars(bs, pad, length, PosLeft)
|
|
}
|
|
|
|
// PadBytesRight a byte to want length
|
|
func PadBytesRight(bs []byte, pad byte, length int) []byte {
|
|
return PadChars(bs, pad, length, PosRight)
|
|
}
|
|
|
|
// PadRunes padding a rune to want length and with position flag
|
|
func PadRunes(rs []rune, pad rune, length int, pos PosFlag) []rune {
|
|
return PadChars(rs, pad, length, pos)
|
|
}
|
|
|
|
// PadRunesLeft a rune to want length
|
|
func PadRunesLeft(rs []rune, pad rune, length int) []rune {
|
|
return PadChars(rs, pad, length, PosLeft)
|
|
}
|
|
|
|
// PadRunesRight a rune to want length
|
|
func PadRunesRight(rs []rune, pad rune, length int) []rune {
|
|
return PadChars(rs, pad, length, PosRight)
|
|
}
|
|
|
|
// Align a string by given length and align settings. alias of Resize
|
|
func Align(s string, length int, align comdef.Align) string {
|
|
return resize(s, len(s), length, align, false)
|
|
}
|
|
|
|
// Utf8Align a string by given length and align settings. alias of Utf8Resize
|
|
func Utf8Align(s string, length int, align comdef.Align) string {
|
|
return resize(s, Utf8Width(s), length, align, false)
|
|
}
|
|
|
|
// Resize a string by given length and align settings. use padding space.
|
|
// If len(s) > wantLen, will truncate it.
|
|
func Resize(s string, length int, align comdef.Align) string {
|
|
return resize(s, len(s), length, align, true)
|
|
}
|
|
|
|
// Utf8Resize a string by given length and align settings. use padding space.
|
|
// If width(s) > wantLen, will truncate it.
|
|
func Utf8Resize(s string, length int, align comdef.Align) string {
|
|
return resize(s, Utf8Width(s), length, align, true)
|
|
}
|
|
|
|
// resize a string by given length and align settings. use padding space.
|
|
func resize(s string, sLen, wantLen int, align comdef.Align, cutOverflow bool) string {
|
|
diff := sLen - wantLen
|
|
if diff >= 0 { // do not need padding.
|
|
// cutOverflow: truncate on sLen > wantLen
|
|
if cutOverflow && sLen > wantLen {
|
|
if len(s) == sLen {
|
|
return s[:wantLen]
|
|
}
|
|
return utf8Truncate(s, sLen, wantLen, "")
|
|
}
|
|
return s
|
|
}
|
|
|
|
if align == comdef.Center {
|
|
padLn := (wantLen - sLen) / 2
|
|
if diff = wantLen - padLn*2; diff > 0 {
|
|
s += " "
|
|
}
|
|
padStr := string(RepeatBytes(' ', padLn))
|
|
return padStr + s + padStr
|
|
}
|
|
|
|
padStr := string(RepeatBytes(' ', wantLen-sLen))
|
|
// tip: 左对齐 - 使用空白填充右边
|
|
if align == comdef.Left || align == comdef.PosAuto {
|
|
return s + padStr
|
|
}
|
|
return padStr + s
|
|
}
|
|
|
|
/*************************************************************
|
|
* String repeat operation
|
|
*************************************************************/
|
|
|
|
// Repeat a string by given times.
|
|
func Repeat(s string, times int) string {
|
|
if times < 1 {
|
|
return ""
|
|
}
|
|
if times == 1 {
|
|
return s
|
|
}
|
|
|
|
var sb strings.Builder
|
|
sb.Grow(len(s) * times)
|
|
|
|
for i := 0; i < times; i++ {
|
|
sb.WriteString(s)
|
|
}
|
|
return sb.String()
|
|
}
|
|
|
|
// RepeatRune repeat a rune char.
|
|
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) }
|
|
|
|
// 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, times)
|
|
for i := 0; i < times; i++ {
|
|
chars[i] = char
|
|
}
|
|
return chars
|
|
}
|