File: tree.go

package info (click to toggle)
golang-code.forgejo-f3-gof3 3.11.0-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 1,952 kB
  • sloc: sh: 100; makefile: 65
file content (134 lines) | stat: -rw-r--r-- 3,553 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// 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
}