1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
package jl
import (
"bytes"
"fmt"
"strings"
"unicode/utf8"
)
// Context provides the current transformation context, to be used by Transformers and Stringers.
type Context struct {
// The original string before any transformations were applied.
Original string
// Indicates that terminal color escape sequences should be disabled.
DisableColor bool
// Indicates that fields should not be truncated.
DisableTruncate bool
}
// Transformer transforms a string and returns the result.
type Transformer interface {
Transform(ctx *Context, input string) string
}
// TransformFunc is an adapter to allow the use of ordinary functions as Transformers.
type TransformFunc func(string) string
func (f TransformFunc) Transform(ctx *Context, input string) string {
return f(input)
}
var (
// UpperCase transforms the input string to upper case.
UpperCase = TransformFunc(strings.ToUpper)
// LowerCase transforms the input string to lower case.
LowerCase = TransformFunc(strings.ToLower)
)
// Truncate truncates the string to the a requested number of digits.
type Truncate int
func (t Truncate) Transform(ctx *Context, input string) string {
if ctx.DisableTruncate {
return input
}
if utf8.RuneCountInString(input) <= int(t) {
return input
}
return input[:t]
}
// Ellipsize replaces characters in the middle of the string with a single "…" character so that it fits within the
// requested length.
type Ellipsize int
func (remain Ellipsize) Transform(ctx *Context, input string) string {
if ctx.DisableTruncate {
return input
}
length := utf8.RuneCountInString(input)
if length <= int(remain) {
return input
}
remain -= 1 // account for the ellipsis
chomped := length - int(remain)
start := int(remain)/2
end := start + chomped
return input[:start] + "…" + input[end:]
}
// LeftPad pads the left side of the string with spaces so that the string becomes the requested length.
type LeftPad int
func (t LeftPad) Transform(ctx *Context, input string) string {
spaces := int(t) - utf8.RuneCountInString(input)
if spaces <= 0 {
return input
}
buf := bytes.NewBuffer(make([]byte, 0, spaces+len(input)))
for i := 0; i < spaces; i++ {
buf.WriteRune(' ')
}
buf.WriteString(input)
return buf.String()
}
// LeftPad pads the right side of the string with spaces so that the string becomes the requested length.
type RightPad int
func (t RightPad) Transform(ctx *Context, input string) string {
pad := int(t) - utf8.RuneCountInString(input)
if pad <= 0 {
return input
}
buf := bytes.NewBuffer(make([]byte, 0, pad+len(input)))
buf.WriteString(input)
for i := 0; i < pad; i++ {
buf.WriteRune(' ')
}
return buf.String()
}
// Format calls fmt.Sprintf() with the requested format string.
type Format string
func (t Format) Transform(ctx *Context, input string) string {
return fmt.Sprintf(string(t), input)
}
|