123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- package formatter
- import (
- "encoding/json"
- "errors"
- "fmt"
- diff "github.com/yudai/gojsondiff"
- )
- const (
- DeltaDelete = 0
- DeltaTextDiff = 2
- DeltaMove = 3
- )
- func NewDeltaFormatter() *DeltaFormatter {
- return &DeltaFormatter{
- PrintIndent: true,
- }
- }
- type DeltaFormatter struct {
- PrintIndent bool
- }
- func (f *DeltaFormatter) Format(diff diff.Diff) (result string, err error) {
- jsonObject, err := f.formatObject(diff.Deltas())
- if err != nil {
- return "", err
- }
- var resultBytes []byte
- if f.PrintIndent {
- resultBytes, err = json.MarshalIndent(jsonObject, "", " ")
- } else {
- resultBytes, err = json.Marshal(jsonObject)
- }
- if err != nil {
- return "", err
- }
- return string(resultBytes) + "\n", nil
- }
- func (f *DeltaFormatter) FormatAsJson(diff diff.Diff) (json map[string]interface{}, err error) {
- return f.formatObject(diff.Deltas())
- }
- func (f *DeltaFormatter) formatObject(deltas []diff.Delta) (deltaJson map[string]interface{}, err error) {
- deltaJson = map[string]interface{}{}
- for _, delta := range deltas {
- switch delta.(type) {
- case *diff.Object:
- d := delta.(*diff.Object)
- deltaJson[d.Position.String()], err = f.formatObject(d.Deltas)
- if err != nil {
- return nil, err
- }
- case *diff.Array:
- d := delta.(*diff.Array)
- deltaJson[d.Position.String()], err = f.formatArray(d.Deltas)
- if err != nil {
- return nil, err
- }
- case *diff.Added:
- d := delta.(*diff.Added)
- deltaJson[d.PostPosition().String()] = []interface{}{d.Value}
- case *diff.Modified:
- d := delta.(*diff.Modified)
- deltaJson[d.PostPosition().String()] = []interface{}{d.OldValue, d.NewValue}
- case *diff.TextDiff:
- d := delta.(*diff.TextDiff)
- deltaJson[d.PostPosition().String()] = []interface{}{d.DiffString(), 0, DeltaTextDiff}
- case *diff.Deleted:
- d := delta.(*diff.Deleted)
- deltaJson[d.PrePosition().String()] = []interface{}{d.Value, 0, DeltaDelete}
- case *diff.Moved:
- return nil, errors.New("Delta type 'Move' is not supported in objects")
- default:
- return nil, errors.New(fmt.Sprintf("Unknown Delta type detected: %#v", delta))
- }
- }
- return
- }
- func (f *DeltaFormatter) formatArray(deltas []diff.Delta) (deltaJson map[string]interface{}, err error) {
- deltaJson = map[string]interface{}{
- "_t": "a",
- }
- for _, delta := range deltas {
- switch delta.(type) {
- case *diff.Object:
- d := delta.(*diff.Object)
- deltaJson[d.Position.String()], err = f.formatObject(d.Deltas)
- if err != nil {
- return nil, err
- }
- case *diff.Array:
- d := delta.(*diff.Array)
- deltaJson[d.Position.String()], err = f.formatArray(d.Deltas)
- if err != nil {
- return nil, err
- }
- case *diff.Added:
- d := delta.(*diff.Added)
- deltaJson[d.PostPosition().String()] = []interface{}{d.Value}
- case *diff.Modified:
- d := delta.(*diff.Modified)
- deltaJson[d.PostPosition().String()] = []interface{}{d.OldValue, d.NewValue}
- case *diff.TextDiff:
- d := delta.(*diff.TextDiff)
- deltaJson[d.PostPosition().String()] = []interface{}{d.DiffString(), 0, DeltaTextDiff}
- case *diff.Deleted:
- d := delta.(*diff.Deleted)
- deltaJson["_"+d.PrePosition().String()] = []interface{}{d.Value, 0, DeltaDelete}
- case *diff.Moved:
- d := delta.(*diff.Moved)
- deltaJson["_"+d.PrePosition().String()] = []interface{}{"", d.PostPosition(), DeltaMove}
- default:
- return nil, errors.New(fmt.Sprintf("Unknown Delta type detected: %#v", delta))
- }
- }
- return
- }
|