1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-08 13:57:12 +09:00
anytype-heart/util/pbtypes/compare.go
2024-07-30 18:38:25 +02:00

231 lines
4.8 KiB
Go

package pbtypes
import (
"sort"
"github.com/gogo/protobuf/types"
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
"github.com/anyproto/anytype-heart/util/slice"
)
func StructEqualIgnore(det1 *types.Struct, det2 *types.Struct, excludeKeys []string) (equal bool) {
var m1, m2 map[string]*types.Value
if det1 == nil || det1.Fields == nil {
m1 = make(map[string]*types.Value)
} else {
m1 = det1.Fields
}
if det2 == nil || det2.Fields == nil {
m2 = make(map[string]*types.Value)
} else {
m2 = det2.Fields
}
for key, v1 := range m1 {
if slice.FindPos(excludeKeys, key) >= 0 {
continue
}
if v2, exists := m2[key]; !exists {
return false
} else if !v2.Equal(v1) {
return false
}
}
for key, _ := range m2 {
if slice.FindPos(excludeKeys, key) >= 0 {
continue
}
if _, exists := m1[key]; !exists {
return false
}
}
return true
}
// StructFilterKeys returns provided keys reusing underlying pb values pointers
func StructFilterKeys(st *types.Struct, filteredKeys []string) *types.Struct {
return StructFilterKeysFunc(st, func(key string, _ *types.Value) bool {
return slice.FindPos(filteredKeys, key) > -1
})
}
func StructFilterKeysFunc(st *types.Struct, filter func(key string, val *types.Value) bool) *types.Struct {
if st == nil || st.Fields == nil {
return st
}
m := make(map[string]*types.Value, len(st.Fields))
for k, v := range st.Fields {
if filter(k, v) {
m[k] = v
}
}
return &types.Struct{Fields: m}
}
// StructCutKeys excludes provided keys reusing underlying pb values pointers
func StructCutKeys(st *types.Struct, excludeKeys []string) *types.Struct {
return StructFilterKeysFunc(st, func(key string, _ *types.Value) bool {
return slice.FindPos(excludeKeys, key) == -1
})
}
func StructMerge(st1, st2 *types.Struct, copyVals bool) *types.Struct {
var res *types.Struct
if st1 == nil || st1.Fields == nil {
return CopyStruct(st2, copyVals)
}
if st2 == nil || st2.Fields == nil {
return CopyStruct(st1, copyVals)
}
res = CopyStruct(st1, copyVals)
for k, v := range st2.Fields {
if copyVals {
res.Fields[k] = CopyVal(v)
} else {
res.Fields[k] = v
}
}
return res
}
func DataviewSortsEqualSorted(sorts1, sorts2 []*model.BlockContentDataviewSort) bool {
if len(sorts1) != len(sorts2) {
return false
}
for i := range sorts1 {
if !DataviewSortEqual(sorts1[i], sorts2[i]) {
return false
}
}
return true
}
func DataviewFiltersEqualSorted(filters1, filters2 []*model.BlockContentDataviewFilter) bool {
if len(filters1) != len(filters2) {
return false
}
for i := range filters1 {
if !DataviewFilterEqual(filters1[i], filters2[i]) {
return false
}
}
return true
}
func DataviewViewsEqualSorted(views1, views2 []*model.BlockContentDataviewView) bool {
if len(views1) != len(views2) {
return false
}
for i := range views1 {
if !DataviewViewEqual(views1[i], views2[i]) {
return false
}
}
return true
}
func DataviewSortEqual(sort1, sort2 *model.BlockContentDataviewSort) bool {
if sort1 == nil && sort2 != nil {
return false
}
if sort1 != nil && sort2 == nil {
return false
}
if sort1 == nil && sort2 == nil {
return true
}
if sort1.RelationKey != sort2.RelationKey {
return false
}
if sort1.Type != sort2.Type {
return false
}
return true
}
func DataviewFilterEqual(filter1, filter2 *model.BlockContentDataviewFilter) bool {
if filter1 == nil && filter2 != nil {
return false
}
if filter1 != nil && filter2 == nil {
return false
}
if filter1 == nil && filter2 == nil {
return true
}
if filter1.RelationKey != filter2.RelationKey {
return false
}
if filter1.Condition != filter2.Condition {
return false
}
if filter1.Operator != filter2.Operator {
return false
}
if filter1.RelationProperty != filter2.RelationProperty {
return false
}
if filter1.Value.Compare(filter2.Value) != 0 {
return false
}
return true
}
func DataviewViewEqual(view1, view2 *model.BlockContentDataviewView) bool {
if view1 == nil && view2 != nil {
return false
}
if view1 != nil && view2 == nil {
return false
}
if view1 == nil && view2 == nil {
return true
}
if view1.Id != view2.Id {
return false
}
if view1.Name != view2.Name {
return false
}
if view1.Type != view2.Type {
return false
}
if !DataviewFiltersEqualSorted(view1.Filters, view2.Filters) {
return false
}
if !DataviewSortsEqualSorted(view1.Sorts, view2.Sorts) {
return false
}
if len(view1.Relations) != len(view2.Relations) {
return false
// todo add relations check
}
return true
}
func SortedRange(s *types.Struct, f func(k string, v *types.Value)) {
if s == nil || s.Fields == nil {
return
}
var keys = make([]string, 0, len(s.Fields))
for k := range s.Fields {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
f(k, s.Fields[k])
}
}