From 1298398922ccd5c4f12ff63e1df7fed88c8c40bf Mon Sep 17 00:00:00 2001 From: George Suntres Date: Sat, 18 Apr 2026 19:40:51 -0400 Subject: [PATCH] Add JsonPrint, StringMissing --- go.mod | 1 + go.sum | 16 ++++++++++++++++ json.go | 16 ++++++++++++++++ json_test.go | 30 +++++++++++++++++++++++++++++- strings.go | 18 ++++++++++++++++++ struct.go | 33 ++++++++++++++++++++++++++++++++- 6 files changed, 112 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index d27fdbc..e30f138 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.25.0 require ( github.com/go-viper/mapstructure/v2 v2.5.0 github.com/ianlancetaylor/jsonschema v0.0.0-20251021232724-46ecbf32a0a5 + github.com/sergi/go-diff v1.4.0 go.mongodb.org/mongo-driver/v2 v2.5.0 golang.org/x/text v0.30.0 ) diff --git a/go.sum b/go.sum index a03e372..83ce7e4 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= @@ -6,7 +7,22 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/ianlancetaylor/jsonschema v0.0.0-20251021232724-46ecbf32a0a5 h1:x2QxKV4w/sBEwwUUmBH/8cFjeOBZqwaB5dz5rcuFspU= github.com/ianlancetaylor/jsonschema v0.0.0-20251021232724-46ecbf32a0a5/go.mod h1:KtN3dTgXsLnC5GJBRNmOPd/HUInNcQ84lUCrKJPrvDc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= +github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE= go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/json.go b/json.go index 4f184f7..d24f974 100644 --- a/json.go +++ b/json.go @@ -44,4 +44,20 @@ func JsonEqual(a, b string) bool { } return reflect.DeepEqual(o1, o2) +} + +// JsonPrint bson.M +func JsonSprint(a any) string { + raw, err := json.Marshal(a) + if err != nil { + log.Printf("Failed to read json: %s", err) + + return "" + } + + return string(raw) +} + +func JsonPrint(a any) { + log.Printf("%s", JsonSprint(a)) } \ No newline at end of file diff --git a/json_test.go b/json_test.go index ed9377d..c6db10a 100644 --- a/json_test.go +++ b/json_test.go @@ -5,7 +5,7 @@ import ( "fmt" "bytes" "encoding/json" - "testing" + "testing" ) func TestJsonPrintError(t *testing.T) { @@ -65,4 +65,32 @@ func TestJsonSprintError(t *testing.T) { if s == "" { t.Fatal("should have printed the error") } +} + +func TestJsonPrint(t *testing.T) { + m := map[string]any{ + "name": "George", + "age": 87, + "active": false, + "properties": map[string]any{ + "one": "two", + "three": "four", + }, + } + + var buf bytes.Buffer + log.SetFlags(0) + log.SetOutput(&buf) + + JsonPrint(m) + + out := fmt.Sprintf("%s", buf.String()) + + expected := `{"active":false,"age":87,"name":"George","properties":{"one":"two","three":"four"}}` + + missing := StringMissing(expected, out) + + if missing != "" { + t.Fatalf("Not expected %s", missing) + } } \ No newline at end of file diff --git a/strings.go b/strings.go index f7620e4..5be85cf 100644 --- a/strings.go +++ b/strings.go @@ -6,6 +6,8 @@ import ( "golang.org/x/text/cases" "golang.org/x/text/language" + + "github.com/sergi/go-diff/diffmatchpatch" ) var caserTitle cases.Caser = cases.Title(language.English, cases.NoLower) @@ -32,3 +34,19 @@ func StringIsBlank(s string) bool { func StringIsNotBlank(s string) bool { return !StringIsBlank(s) } + + +func StringMissing(a, b string) string { + dmp := diffmatchpatch.New() + diffs := dmp.DiffMain(a, b, false) + + var missing string + + for _, d := range diffs { + if d.Type == diffmatchpatch.DiffDelete { + missing += d.Text + } + } + + return missing +} diff --git a/struct.go b/struct.go index 11e31b6..09f23ab 100644 --- a/struct.go +++ b/struct.go @@ -200,8 +200,39 @@ func MapToStruct(m map[string]any, o any) error { return nil } +func BsonAnyToMap(v any) any { + switch v.(type) { + case bson.D: + m := map[string]any{} + val := v.(bson.D) + for _, elem := range val { + m[elem.Key] = BsonAnyToMap(elem.Value) + } + return m + + case bson.M: + m := map[string]any{} + val := v.(bson.M) + for k, v2 := range val { + m[k] = BsonAnyToMap(v2) + } + return m + + case bson.A: + val := v.(bson.A) + arr := make([]any, len(val)) + for i, v2 := range val { + arr[i] = BsonAnyToMap(v2) + } + return arr + + default: + return v + } +} + func BsonToMap(b bson.M) map[string]any { - result := make(map[string]any) + result := map[string]any{} for k, v := range b { switch val := v.(type) {