1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-07 21:47:02 +09:00
any-sync/commonspace/settings/settingsstate/statebuilder.go
2024-08-02 11:14:12 +02:00

70 lines
1.8 KiB
Go

package settingsstate
import (
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
"github.com/anyproto/any-sync/commonspace/spacesyncproto"
"github.com/anyproto/protobuf/proto"
)
type StateBuilder interface {
Build(tree objecttree.ReadableObjectTree, state *State) (*State, error)
}
func NewStateBuilder() StateBuilder {
return &stateBuilder{}
}
type stateBuilder struct {
}
func (s *stateBuilder) Build(tr objecttree.ReadableObjectTree, oldState *State) (state *State, err error) {
var (
rootId = tr.Root().Id
startId = rootId
)
state = oldState
if state == nil {
state = NewState()
} else if state.LastIteratedId != "" {
startId = state.LastIteratedId
}
process := func(change *objecttree.Change) bool {
state = s.processChange(change, rootId, state)
state.LastIteratedId = change.Id
return true
}
convert := func(ch *objecttree.Change, decrypted []byte) (res any, err error) {
deleteChange := &spacesyncproto.SettingsData{}
err = proto.Unmarshal(decrypted, deleteChange)
if err != nil {
return nil, err
}
return deleteChange, nil
}
err = tr.IterateFrom(startId, convert, process)
return
}
func (s *stateBuilder) processChange(change *objecttree.Change, rootId string, state *State) *State {
// ignoring root change which has empty model or startId change
if len(change.PreviousIds) == 0 || state.LastIteratedId == change.Id {
return state
}
deleteChange := change.Model.(*spacesyncproto.SettingsData)
// getting data from snapshot if we start from it
if change.Id == rootId {
state = NewStateFromSnapshot(deleteChange.Snapshot, rootId)
return state
}
// otherwise getting data from content
for _, cnt := range deleteChange.Content {
switch {
case cnt.GetObjectDelete() != nil:
state.DeletedIds[cnt.GetObjectDelete().GetId()] = struct{}{}
}
}
return state
}