134 lines
3.5 KiB
Go
134 lines
3.5 KiB
Go
// Copyright Earl Warren <contact@earl-warren.org>
|
|
// Copyright Loïc Dachary <loic@dachary.org>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package generic
|
|
|
|
import (
|
|
"context"
|
|
|
|
"code.forgejo.org/f3/gof3/v3/kind"
|
|
"code.forgejo.org/f3/gof3/v3/logger"
|
|
"code.forgejo.org/f3/gof3/v3/options"
|
|
"code.forgejo.org/f3/gof3/v3/path"
|
|
)
|
|
|
|
type FactoryFun func(ctx context.Context, kind kind.Kind) NodeInterface
|
|
|
|
type kindMap map[kind.Kind]FactoryFun
|
|
|
|
type Tree struct {
|
|
logger.Logger
|
|
|
|
opts options.Interface
|
|
self TreeInterface
|
|
driver TreeDriverInterface
|
|
root NodeInterface
|
|
kind kindMap
|
|
}
|
|
|
|
func NewTree(opts options.Interface) TreeInterface {
|
|
tree := &Tree{}
|
|
return tree.Init(tree, opts)
|
|
}
|
|
|
|
func (o *Tree) Init(self TreeInterface, opts options.Interface) TreeInterface {
|
|
o.self = self
|
|
o.kind = make(kindMap)
|
|
o.SetDriver(NewNullTreeDriver())
|
|
o.SetOptions(opts)
|
|
o.SetLogger(opts.(options.LoggerInterface).GetLogger())
|
|
return o
|
|
}
|
|
|
|
func (o *Tree) GetOptions() options.Interface { return o.opts }
|
|
func (o *Tree) SetOptions(opts options.Interface) { o.opts = opts }
|
|
|
|
func (o *Tree) GetSelf() TreeInterface { return o.self }
|
|
func (o *Tree) SetSelf(self TreeInterface) { o.self = self }
|
|
|
|
func (o *Tree) GetRoot() NodeInterface { return o.root }
|
|
func (o *Tree) SetRoot(root NodeInterface) { o.root = root }
|
|
|
|
func (o *Tree) GetDriver() TreeDriverInterface { return o.driver }
|
|
func (o *Tree) SetDriver(driver TreeDriverInterface) {
|
|
driver.SetTree(o.GetSelf())
|
|
o.driver = driver
|
|
}
|
|
|
|
func (o *Tree) GetChildrenKind(parentKind kind.Kind) kind.Kind {
|
|
return kind.KindNil
|
|
}
|
|
|
|
func (o *Tree) GetPageSize() int { return o.GetDriver().GetPageSize() }
|
|
|
|
func (o *Tree) AllocateID() bool { return o.GetDriver().AllocateID() }
|
|
|
|
func (o *Tree) Walk(ctx context.Context, options *WalkOptions) {
|
|
o.GetRoot().Walk(ctx, path.NewPath(), options)
|
|
}
|
|
|
|
func (o *Tree) WalkAndGet(ctx context.Context, options *WalkOptions) {
|
|
o.GetRoot().WalkAndGet(ctx, path.NewPath(), options)
|
|
}
|
|
|
|
func (o *Tree) Clear(ctx context.Context) {
|
|
rootKind := o.GetRoot().GetKind()
|
|
o.SetRoot(o.Factory(ctx, rootKind))
|
|
}
|
|
|
|
func (o *Tree) Exists(ctx context.Context, path path.Path) bool {
|
|
return o.Find(path) != NilNode
|
|
}
|
|
|
|
func (o *Tree) MustFind(path path.Path) NodeInterface {
|
|
return o.GetRoot().MustFind(path.RemoveFirst())
|
|
}
|
|
|
|
func (o *Tree) Find(path path.Path) NodeInterface {
|
|
return o.GetRoot().Find(path.RemoveFirst())
|
|
}
|
|
|
|
func (o *Tree) FindAndGet(ctx context.Context, path path.Path) NodeInterface {
|
|
return o.GetRoot().FindAndGet(ctx, path.RemoveFirst())
|
|
}
|
|
|
|
func (o *Tree) Diff(a, b NodeInterface) string {
|
|
return o.GetDriver().Diff(a.GetDriver(), b.GetDriver())
|
|
}
|
|
|
|
func (o *Tree) Apply(ctx context.Context, p path.Path, options *ApplyOptions) bool {
|
|
if p.Empty() {
|
|
return true
|
|
}
|
|
return o.GetRoot().Apply(ctx, path.NewPath(), p.RemoveFirst(), options)
|
|
}
|
|
|
|
func (o *Tree) ApplyAndGet(ctx context.Context, path path.Path, options *ApplyOptions) bool {
|
|
if path.Empty() {
|
|
return true
|
|
}
|
|
return o.GetRoot().ApplyAndGet(ctx, path.RemoveFirst(), options)
|
|
}
|
|
|
|
func (o *Tree) Factory(ctx context.Context, kind kind.Kind) NodeInterface {
|
|
var node NodeInterface
|
|
if factory, ok := o.kind[kind]; ok {
|
|
node = factory(ctx, kind)
|
|
} else {
|
|
node = NewNode()
|
|
}
|
|
node.SetIsNil(false)
|
|
node.SetKind(kind)
|
|
node.SetTree(o.GetSelf())
|
|
if o.GetDriver() != nil {
|
|
nodeDriver := o.GetDriver().Factory(ctx, kind)
|
|
nodeDriver.SetTreeDriver(o.GetDriver())
|
|
node.SetDriver(nodeDriver)
|
|
}
|
|
return node
|
|
}
|
|
|
|
func (o *Tree) Register(kind kind.Kind, factory FactoryFun) {
|
|
o.kind[kind] = factory
|
|
}
|