// Copyright Earl Warren // Copyright Loïc Dachary // 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 }