Adding upstream version 0.8.9.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
3b2c48b5e4
commit
c0c4addb85
285 changed files with 25880 additions and 0 deletions
201
pkg/format/render_console.go
Normal file
201
pkg/format/render_console.go
Normal file
|
@ -0,0 +1,201 @@
|
|||
package format
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
|
||||
"github.com/nicholas-fedor/shoutrrr/pkg/util"
|
||||
)
|
||||
|
||||
// Constants for console rendering.
|
||||
const (
|
||||
DescriptionColumnWidth = 60 // Width of the description column in console output
|
||||
ItemSeparatorLength = 2 // Length of the ", " separator between container items
|
||||
DefaultValueOffset = 16 // Minimum offset before description when no values are shown
|
||||
ValueOffset = 30 // Offset before description when values are shown
|
||||
ContainerBracketLength = 4 // Length of container delimiters (e.g., "{ }" or "[ ]")
|
||||
KeySeparatorLength = 2 // Length of the ": " separator after a key in containers
|
||||
)
|
||||
|
||||
// ConsoleTreeRenderer renders a ContainerNode tree into an ansi-colored console string.
|
||||
type ConsoleTreeRenderer struct {
|
||||
WithValues bool
|
||||
}
|
||||
|
||||
// RenderTree renders a ContainerNode tree into an ansi-colored console string.
|
||||
func (r ConsoleTreeRenderer) RenderTree(root *ContainerNode, _ string) string {
|
||||
stringBuilder := strings.Builder{}
|
||||
|
||||
for _, node := range root.Items {
|
||||
fieldKey := node.Field().Name
|
||||
stringBuilder.WriteString(fieldKey)
|
||||
|
||||
for i := len(fieldKey); i <= root.MaxKeyLength; i++ {
|
||||
stringBuilder.WriteRune(' ')
|
||||
}
|
||||
|
||||
var valueLen int // Initialize without assignment; set later
|
||||
|
||||
preLen := DefaultValueOffset // Default spacing before the description when no values are rendered
|
||||
|
||||
field := node.Field()
|
||||
|
||||
if r.WithValues {
|
||||
preLen = ValueOffset // Adjusts the spacing when values are included
|
||||
valueLen = r.writeNodeValue(&stringBuilder, node)
|
||||
} else {
|
||||
// Since no values were supplied, substitute the value with the type
|
||||
typeName := field.Type.String()
|
||||
|
||||
// If the value is an enum type, providing the name is a bit pointless
|
||||
// Instead, use a common string "option" to signify the type
|
||||
if field.EnumFormatter != nil {
|
||||
typeName = "option"
|
||||
}
|
||||
|
||||
valueLen = len(typeName)
|
||||
stringBuilder.WriteString(color.CyanString(typeName))
|
||||
}
|
||||
|
||||
stringBuilder.WriteString(strings.Repeat(" ", util.Max(preLen-valueLen, 1)))
|
||||
stringBuilder.WriteString(ColorizeDesc(field.Description))
|
||||
stringBuilder.WriteString(
|
||||
strings.Repeat(" ", util.Max(DescriptionColumnWidth-len(field.Description), 1)),
|
||||
)
|
||||
|
||||
if len(field.URLParts) > 0 && field.URLParts[0] != URLQuery {
|
||||
stringBuilder.WriteString(" <URL: ")
|
||||
|
||||
for i, part := range field.URLParts {
|
||||
if i > 0 {
|
||||
stringBuilder.WriteString(", ")
|
||||
}
|
||||
|
||||
if part > URLPath {
|
||||
part = URLPath
|
||||
}
|
||||
|
||||
stringBuilder.WriteString(ColorizeEnum(part))
|
||||
}
|
||||
|
||||
stringBuilder.WriteString(">")
|
||||
}
|
||||
|
||||
if len(field.Template) > 0 {
|
||||
stringBuilder.WriteString(
|
||||
fmt.Sprintf(" <Template: %s>", ColorizeString(field.Template)),
|
||||
)
|
||||
}
|
||||
|
||||
if len(field.DefaultValue) > 0 {
|
||||
stringBuilder.WriteString(
|
||||
fmt.Sprintf(
|
||||
" <Default: %s>",
|
||||
ColorizeValue(field.DefaultValue, field.EnumFormatter != nil),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
if field.Required {
|
||||
stringBuilder.WriteString(fmt.Sprintf(" <%s>", ColorizeFalse("Required")))
|
||||
}
|
||||
|
||||
if len(field.Keys) > 1 {
|
||||
stringBuilder.WriteString(" <Aliases: ")
|
||||
|
||||
for i, key := range field.Keys {
|
||||
if i == 0 {
|
||||
// Skip primary alias (as it's the same as the field name)
|
||||
continue
|
||||
}
|
||||
|
||||
if i > 1 {
|
||||
stringBuilder.WriteString(", ")
|
||||
}
|
||||
|
||||
stringBuilder.WriteString(ColorizeString(key))
|
||||
}
|
||||
|
||||
stringBuilder.WriteString(">")
|
||||
}
|
||||
|
||||
if field.EnumFormatter != nil {
|
||||
stringBuilder.WriteString(ColorizeContainer(" ["))
|
||||
|
||||
for i, name := range field.EnumFormatter.Names() {
|
||||
if i != 0 {
|
||||
stringBuilder.WriteString(", ")
|
||||
}
|
||||
|
||||
stringBuilder.WriteString(ColorizeEnum(name))
|
||||
}
|
||||
|
||||
stringBuilder.WriteString(ColorizeContainer("]"))
|
||||
}
|
||||
|
||||
stringBuilder.WriteRune('\n')
|
||||
}
|
||||
|
||||
return stringBuilder.String()
|
||||
}
|
||||
|
||||
func (r ConsoleTreeRenderer) writeNodeValue(stringBuilder *strings.Builder, node Node) int {
|
||||
if contNode, isContainer := node.(*ContainerNode); isContainer {
|
||||
return r.writeContainer(stringBuilder, contNode)
|
||||
}
|
||||
|
||||
if valNode, isValue := node.(*ValueNode); isValue {
|
||||
stringBuilder.WriteString(ColorizeToken(valNode.Value, valNode.tokenType))
|
||||
|
||||
return len(valNode.Value)
|
||||
}
|
||||
|
||||
stringBuilder.WriteRune('?')
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
func (r ConsoleTreeRenderer) writeContainer(
|
||||
stringBuilder *strings.Builder,
|
||||
node *ContainerNode,
|
||||
) int {
|
||||
kind := node.Type.Kind()
|
||||
hasKeys := !util.IsCollection(kind)
|
||||
|
||||
totalLen := ContainerBracketLength // Length of the opening and closing brackets ({ } or [ ])
|
||||
|
||||
if hasKeys {
|
||||
stringBuilder.WriteString("{ ")
|
||||
} else {
|
||||
stringBuilder.WriteString("[ ")
|
||||
}
|
||||
|
||||
for i, itemNode := range node.Items {
|
||||
if i != 0 {
|
||||
stringBuilder.WriteString(", ")
|
||||
|
||||
totalLen += KeySeparatorLength // Accounts for the : separator between keys and values in containers
|
||||
}
|
||||
|
||||
if hasKeys {
|
||||
itemKey := itemNode.Field().Name
|
||||
stringBuilder.WriteString(itemKey)
|
||||
stringBuilder.WriteString(": ")
|
||||
|
||||
totalLen += len(itemKey) + ItemSeparatorLength
|
||||
}
|
||||
|
||||
valLen := r.writeNodeValue(stringBuilder, itemNode)
|
||||
totalLen += valLen
|
||||
}
|
||||
|
||||
if hasKeys {
|
||||
stringBuilder.WriteString(" }")
|
||||
} else {
|
||||
stringBuilder.WriteString(" ]")
|
||||
}
|
||||
|
||||
return totalLen
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue