diff --git a/util/diff/diff.go b/util/diff/diff.go index 37f900fc..9b6d91df 100644 --- a/util/diff/diff.go +++ b/util/diff/diff.go @@ -15,21 +15,19 @@ package diff import ( - "fmt" "reflect" "sort" - "strings" + "strconv" - "github.com/fatih/structs" "github.com/sergi/go-diff/diffmatchpatch" ) type Operation struct { - Op string `cork:"op,omietmpty" json:"op,omietmpty" structs:"op,omitempty"` - From string `cork:"from,omitempty" json:"from,omitempty" structs:"from,omitempty"` - Path string `cork:"path,omitempty" json:"path,omitempty" structs:"path,omitempty"` - Value interface{} `cork:"value,omitempty" json:"value,omitempty" structs:"value,omitempty"` - Before interface{} `cork:"-" json:"-" structs:"-"` + Op string `cork:"op,omietmpty" json:"op,omietmpty"` + From string `cork:"from,omitempty" json:"from,omitempty"` + Path string `cork:"path,omitempty" json:"path,omitempty"` + Value interface{} `cork:"value,omitempty" json:"value,omitempty"` + Before interface{} `cork:"-" json:"-"` } type Operations struct { @@ -57,21 +55,41 @@ func (o *Operations) Rebase(other *Operations) (ops *Operations, err error) { func (o *Operations) Out() (ops []map[string]interface{}) { for _, v := range o.Ops { - ops = append(ops, structs.Map(v)) + + op := make(map[string]interface{}) + + if len(v.Op) > 0 { + op["op"] = v.Op + } + + if len(v.From) > 0 { + op["from"] = v.From + } + + if len(v.Path) > 0 { + op["path"] = v.Path + } + + if v.Value != nil { + op["value"] = v.Value + } + + ops = append(ops, op) + } return } -func route(path string, part interface{}) string { - if path == "" { - return fmt.Sprintf("/%v", part) +func route(path string, part string) string { + if len(path) == 0 { + return "/" + part } else { - if strings.HasSuffix(path, "/") { - return path + fmt.Sprintf("%v", part) + if path[0] == '/' { + return path + part } else { - return path + fmt.Sprintf("/%v", part) + return path + "/" + part } } } @@ -220,18 +238,18 @@ func (o *Operations) arrs(old, now []interface{}, path string) { var i int for i = 0; i < len(old) && i < len(now); i++ { - o.vals(old[i], now[i], route(path, i)) + o.vals(old[i], now[i], strconv.Itoa(i)) } for j := i; j < len(now); j++ { if j >= len(old) || !reflect.DeepEqual(now[j], old[j]) { - o.op("add", "", route(path, j), nil, now[j]) + o.op("add", "", route(path, strconv.Itoa(j)), nil, now[j]) } } for j := i; j < len(old); j++ { if j >= len(now) || !reflect.DeepEqual(old[j], now[j]) { - o.op("remove", "", route(path, j), old[j], nil) + o.op("remove", "", route(path, strconv.Itoa(j)), old[j], nil) } } diff --git a/util/diff/diff_test.go b/util/diff/diff_test.go new file mode 100644 index 00000000..a2617eeb --- /dev/null +++ b/util/diff/diff_test.go @@ -0,0 +1,55 @@ +// Copyright © 2016 Abcum Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package diff + +import ( + "testing" + + . "github.com/smartystreets/goconvey/convey" +) + +func TestMain(t *testing.T) { + + Convey("Main", t, func() { + So(nil, ShouldBeNil) + }) + +} + +func BenchmarkFib1(b *testing.B) { + + old := map[string]interface{}{ + "age": 18, + "name": map[string]interface{}{ + "first": "T", + "last": "M H", + }, + "chainging": true, + } + + now := map[string]interface{}{ + "age": 29, + "name": map[string]interface{}{ + "first": "Tobie", + "last": "Morgan Hitchcock", + }, + "changing": "This is a string", + } + + for n := 0; n < b.N; n++ { + Diff(old, now) + } + +}