1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-09 17:44:59 +09:00
anytype-heart/util/pbtypes/copy.go
2022-12-26 20:57:06 +05:00

211 lines
4.4 KiB
Go

package pbtypes
import (
"sync"
"github.com/gogo/protobuf/types"
"github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model"
"github.com/anytypeio/go-anytype-middleware/util/slice"
)
var bytesPool = &sync.Pool{
New: func() interface{} {
return []byte{}
},
}
func CopyBlock(in *model.Block) (out *model.Block) {
buf := bytesPool.Get().([]byte)
size := in.Size()
if cap(buf) < size {
buf = make([]byte, 0, size*2)
}
size, _ = in.MarshalToSizedBuffer(buf[:size])
out = &model.Block{}
_ = out.Unmarshal(buf[:size])
bytesPool.Put(buf)
return
}
// CopyStructMap copies pb struct map, while reusing map values' pointers
func CopyStructMap(in *types.Struct) (out *types.Struct) {
if in == nil {
return nil
}
if in.Fields == nil {
return &types.Struct{}
}
out = &types.Struct{Fields: make(map[string]*types.Value, len(in.Fields))}
for k, v := range in.Fields {
out.Fields[k] = v
}
return
}
func CopyStruct(in *types.Struct) (out *types.Struct) {
if in == nil {
return nil
}
buf := bytesPool.Get().([]byte)
size := in.Size()
if cap(buf) < size {
buf = make([]byte, 0, size*2)
}
size, _ = in.MarshalToSizedBuffer(buf[:size])
out = &types.Struct{}
_ = out.Unmarshal(buf[:size])
if out.Fields == nil && in.Fields != nil {
out.Fields = make(map[string]*types.Value)
}
bytesPool.Put(buf)
return
}
func CopyVal(in *types.Value) (out *types.Value) {
if in == nil {
return nil
}
buf := bytesPool.Get().([]byte)
size := in.Size()
if cap(buf) < size {
buf = make([]byte, 0, size*2)
}
size, _ = in.MarshalToSizedBuffer(buf[:size])
out = &types.Value{}
_ = out.Unmarshal(buf[:size])
bytesPool.Put(buf)
return
}
func CopyRelationLink(in *model.RelationLink) (out *model.RelationLink) {
return &model.RelationLink{
Key: in.Key,
Format: in.Format,
}
}
func CopyRelation(in *model.Relation) (out *model.Relation) {
if in == nil {
return nil
}
buf := bytesPool.Get().([]byte)
size := in.Size()
if cap(buf) < size {
buf = make([]byte, 0, size*2)
}
size, _ = in.MarshalToSizedBuffer(buf[:size])
out = &model.Relation{}
_ = out.Unmarshal(buf[:size])
bytesPool.Put(buf)
return out
}
func CopyRelationOptions(in []*model.RelationOption) (out []*model.RelationOption) {
out = make([]*model.RelationOption, len(in))
for i := range in {
out[i] = &*in[i]
}
return
}
func CopyLayout(in *model.Layout) (out *model.Layout) {
return &model.Layout{Id: in.Id, Name: in.Name, RequiredRelations: CopyRelations(in.RequiredRelations)}
}
func CopyObjectType(in *model.ObjectType) (out *model.ObjectType) {
if in == nil {
return nil
}
buf := bytesPool.Get().([]byte)
size := in.Size()
if cap(buf) < size {
buf = make([]byte, 0, size*2)
}
size, _ = in.MarshalToSizedBuffer(buf[:size])
out = &model.ObjectType{}
_ = out.Unmarshal(buf[:size])
bytesPool.Put(buf)
return out
}
func CopyRelations(in []*model.Relation) (out []*model.Relation) {
if in == nil {
return nil
}
buf := bytesPool.Get().([]byte)
inWrapped := model.Relations{Relations: in}
size := inWrapped.Size()
if cap(buf) < size {
buf = make([]byte, 0, size*2)
}
size, _ = inWrapped.MarshalToSizedBuffer(buf[:size])
outWrapped := &model.Relations{}
_ = outWrapped.Unmarshal(buf[:size])
bytesPool.Put(buf)
return outWrapped.Relations
}
func CopyOptions(in []*model.RelationOption) (out []*model.RelationOption) {
if in == nil {
return nil
}
for _, inO := range in {
inCopy := *inO
out = append(out, &inCopy)
}
return
}
func CopyRelationsToMap(in []*model.Relation) (out map[string]*model.Relation) {
out = make(map[string]*model.Relation, len(in))
rels := CopyRelations(in)
for _, rel := range rels {
out[rel.Key] = rel
}
return
}
func CopyFilter(in *model.BlockContentDataviewFilter) (out *model.BlockContentDataviewFilter) {
buf := bytesPool.Get().([]byte)
size := in.Size()
if cap(buf) < size {
buf = make([]byte, 0, size*2)
}
size, _ = in.MarshalToSizedBuffer(buf[:size])
out = &model.BlockContentDataviewFilter{}
_ = out.Unmarshal(buf[:size])
bytesPool.Put(buf)
return
}
func RelationsFilterKeys(in []*model.Relation, keys []string) (out []*model.Relation) {
for i, inRel := range in {
if slice.FindPos(keys, inRel.Key) >= 0 {
out = append(out, in[i])
}
}
return
}
func StructNotNilKeys(st *types.Struct) (keys []string) {
if st == nil || st.Fields == nil {
return nil
}
for k, v := range st.Fields {
if v != nil {
keys = append(keys, k)
}
}
return
}