Skip to content

Commit

Permalink
Merge branch 'main' into opsgenie
Browse files Browse the repository at this point in the history
  • Loading branch information
piksel committed Feb 21, 2021
2 parents f0c460d + fd3e82d commit 394e38c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 11 deletions.
6 changes: 5 additions & 1 deletion pkg/format/format_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package format
import (
"errors"
"github.com/containrrr/shoutrrr/pkg/types"
"github.com/fatih/color"
"reflect"

"testing"
Expand Down Expand Up @@ -30,6 +31,9 @@ func TestFormat(t *testing.T) {
var _ = Describe("the format package", func() {
BeforeSuite(func() {
// logger = log.New(GinkgoWriter, "Test", log.LstdFlags)

// Disable color output for tests to have them match the string format rather than the colors
color.NoColor = true
})

Describe("SetConfigField", func() {
Expand Down Expand Up @@ -215,7 +219,7 @@ var _ = Describe("the format package", func() {
testSetAndFormat(tv, fieldMap["SubPropPtrSlice"], "@diet,@glue", "[ @diet, @glue ]")
})
It("should format prop struct slices identical to input", func() {
testSetAndFormat(tv, fieldMap["StrMap"], "one:1,two:2", "{ one: 1, two: 2 }")
testSetAndFormat(tv, fieldMap["StrMap"], "a:1,b:2,c:3", "{ a: 1, b: 2, c: 3 }")
})
})
})
Expand Down
39 changes: 29 additions & 10 deletions pkg/format/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"reflect"
"sort"
"strconv"
"strings"
"unsafe"
Expand Down Expand Up @@ -127,11 +128,11 @@ func (fmtr *formatter) getStructFieldValueString(fieldVal reflect.Value, field F
if kind == reflect.Int {
valueStr := field.EnumFormatter.Print(int(fieldVal.Int()))
return ColorizeEnum(valueStr), len(valueStr)
} else {
err := fmt.Errorf("incorrect enum type '%s' for field '%s'", kind, field.Name)
fmtr.Errors = append(fmtr.Errors, err)
return "", 0
}
err := fmt.Errorf("incorrect enum type '%s' for field '%s'", kind, field.Name)
fmtr.Errors = append(fmtr.Errors, err)
return "", 0

} else if nextDepth >= fmtr.MaxDepth {
return
}
Expand Down Expand Up @@ -274,19 +275,34 @@ func (fmtr *formatter) getFieldValueString(field reflect.Value, base int, depth
}

if kind == reflect.Map {
sb := strings.Builder{}
sb.WriteString("{ ")

iter := field.MapRange()
// initial value for totalLen is surrounding curlies and spaces, and separating commas
totalLen := 4 + (field.Len() - 1)

keys := make([]string, field.Len())
keyFmtMap := make(map[string]string, field.Len())

for i := 0; iter.Next(); i++ {
key, keyLen := fmtr.getFieldValueString(iter.Key(), base, nextDepth)
key := iter.Key().String()
keyFmt, keyLen := fmtr.getFieldValueString(iter.Key(), base, nextDepth)
value, valueLen := fmtr.getFieldValueString(iter.Value(), base, nextDepth)

keys[i] = key
keyFmtMap[key] = fmt.Sprintf("%s: %s", keyFmt, value)
totalLen += keyLen + valueLen + 2
}

sort.Strings(keys)

sb := strings.Builder{}
sb.WriteString("{ ")
for _, key := range keys {

if sb.Len() > 2 {
sb.WriteString(", ")
}
sb.WriteString(fmt.Sprintf("%s: %s", key, value))
totalLen += keyLen + valueLen + 2
sb.WriteString(keyFmtMap[key])
}
sb.WriteString(" }")

Expand Down Expand Up @@ -434,6 +450,7 @@ func SetConfigField(config reflect.Value, field FieldInfo, inputValue string) (v

}

// GetConfigPropFromString deserializes a config property from a string representation using the ConfigProp interface
func GetConfigPropFromString(structType reflect.Type, value string) (reflect.Value, error) {
valuePtr := reflect.New(structType)
configProp, ok := valuePtr.Interface().(types.ConfigProp)
Expand All @@ -448,6 +465,7 @@ func GetConfigPropFromString(structType reflect.Type, value string) (reflect.Val
return valuePtr, nil
}

// GetConfigPropString serializes a config property to a string representation using the ConfigProp interface
func GetConfigPropString(propPtr reflect.Value) (string, error) {

if propPtr.Kind() != reflect.Ptr {
Expand Down Expand Up @@ -497,9 +515,10 @@ func GetConfigFieldString(config reflect.Value, field FieldInfo) (value string,
kvPairs := []string{}
for _, key := range configField.MapKeys() {
value := configField.MapIndex(key).Interface()

kvPairs = append(kvPairs, fmt.Sprintf("%s:%s", key, value))
}
// Map key/value-pairs are sorted after concat as it should be identical to sorting the keys before
sort.Strings(kvPairs)
return strings.Join(kvPairs, ","), nil
} else if fieldKind == reflect.Slice || fieldKind == reflect.Array {
sliceLen := configField.Len()
Expand Down
1 change: 1 addition & 0 deletions pkg/types/config_prop.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package types

// ConfigProp interface is used to de-/serialize structs from/to a string representation
type ConfigProp interface {
SetFromProp(propValue string) error
GetPropValue() (string, error)
Expand Down

0 comments on commit 394e38c

Please sign in to comment.