1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-09-16 09:36:18 +02:00

Refactor structdiff package

This commit is contained in:
DarthSim
2025-03-04 22:05:26 +03:00
parent bead5a2380
commit 0bf347b1fe
2 changed files with 47 additions and 38 deletions

View File

@@ -71,11 +71,7 @@ func setMetadata(ctx context.Context, key string, value any) {
}
func SetMetadata(ctx context.Context, key string, value any) {
type diffable interface {
Diff() structdiff.Entries
}
if diff, ok := value.(diffable); ok {
if diff, ok := value.(structdiff.Diffable); ok {
m := diff.Diff().Flatten()
for k, v := range m {
setMetadata(ctx, fmt.Sprintf("%s.%s", key, k), v)

View File

@@ -6,19 +6,10 @@ import (
"fmt"
"reflect"
"strings"
"sync"
)
var bufPool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)
},
}
var builderPool = sync.Pool{
New: func() interface{} {
return new(strings.Builder)
},
type Diffable interface {
Diff() Entries
}
type Entry struct {
@@ -29,11 +20,9 @@ type Entry struct {
type Entries []Entry
func (d Entries) String() string {
buf := builderPool.Get().(*strings.Builder)
buf := new(strings.Builder)
last := len(d) - 1
buf.Reset()
for i, e := range d {
buf.WriteString(e.Name)
buf.WriteString(": ")
@@ -43,7 +32,7 @@ func (d Entries) String() string {
buf.WriteString(dd.String())
buf.WriteByte('}')
} else {
fmt.Fprint(buf, e.Value)
fmt.Fprintf(buf, "%+v", e.Value)
}
if i != last {
@@ -55,11 +44,9 @@ func (d Entries) String() string {
}
func (d Entries) MarshalJSON() ([]byte, error) {
buf := bufPool.Get().(*bytes.Buffer)
buf := new(bytes.Buffer)
last := len(d) - 1
buf.Reset()
buf.WriteByte('{')
for i, e := range d {
@@ -101,6 +88,45 @@ func (d Entries) Flatten() map[string]interface{} {
return m
}
func valDiff(a, b reflect.Value) (any, bool) {
if !a.CanInterface() || !b.CanInterface() {
return nil, false
}
typeB := b.Type()
if a.Type() != typeB {
return b.Interface(), true
}
intA := a.Interface()
intB := b.Interface()
if reflect.DeepEqual(intA, intB) {
return nil, false
}
if typeB.Kind() == reflect.Struct {
return Diff(intA, intB), true
}
if typeB.Kind() == reflect.Ptr && typeB.Elem().Kind() == reflect.Struct {
if !a.IsNil() && !b.IsNil() {
return Diff(intA, intB), true
}
if !b.IsNil() {
if diffable, ok := intB.(Diffable); ok {
return diffable.Diff(), true
}
}
return nil, true
}
return intB, true
}
func Diff(a, b interface{}) Entries {
valA := reflect.Indirect(reflect.ValueOf(a))
valB := reflect.Indirect(reflect.ValueOf(b))
@@ -115,22 +141,9 @@ func Diff(a, b interface{}) Entries {
fieldA := valA.Field(i)
fieldB := valB.Field(i)
if !fieldA.CanInterface() || !fieldB.CanInterface() {
continue
}
intA := fieldA.Interface()
intB := fieldB.Interface()
if !reflect.DeepEqual(intA, intB) {
if v, ok := valDiff(fieldA, fieldB); ok {
name := valB.Type().Field(i).Name
value := intB
if fieldB.Kind() == reflect.Struct {
value = Diff(intA, intB)
}
d = append(d, Entry{name, value})
d = append(d, Entry{name, v})
}
}