fluentBuilder.go 5.22 KB
Newer Older
1 2 3
package fluent

import (
tavit ohanian's avatar
tavit ohanian committed
4
	ld "gitlab.dms3.io/ld/go-ld-prime"
5 6
)

tavit ohanian's avatar
tavit ohanian committed
7
func Build(np ld.NodePrototype, fn func(NodeAssembler)) (ld.Node, error) {
8
	nb := np.NewBuilder()
9 10 11 12
	fna := WrapAssembler(nb)
	err := Recover(func() {
		fn(fna)
	})
13 14 15 16 17
	if err != nil {
		return nil, err
	}
	return nb.Build(), nil
}
tavit ohanian's avatar
tavit ohanian committed
18
func BuildMap(np ld.NodePrototype, sizeHint int64, fn func(MapAssembler)) (ld.Node, error) {
19 20
	return Build(np, func(fna NodeAssembler) { fna.CreateMap(sizeHint, fn) })
}
tavit ohanian's avatar
tavit ohanian committed
21
func BuildList(np ld.NodePrototype, sizeHint int64, fn func(ListAssembler)) (ld.Node, error) {
22
	return Build(np, func(fna NodeAssembler) { fna.CreateList(sizeHint, fn) })
23 24
}

tavit ohanian's avatar
tavit ohanian committed
25
func MustBuild(np ld.NodePrototype, fn func(NodeAssembler)) ld.Node {
26
	nb := np.NewBuilder()
27 28 29
	fn(WrapAssembler(nb))
	return nb.Build()
}
tavit ohanian's avatar
tavit ohanian committed
30
func MustBuildMap(np ld.NodePrototype, sizeHint int64, fn func(MapAssembler)) ld.Node {
31
	return MustBuild(np, func(fna NodeAssembler) { fna.CreateMap(sizeHint, fn) })
32
}
tavit ohanian's avatar
tavit ohanian committed
33
func MustBuildList(np ld.NodePrototype, sizeHint int64, fn func(ListAssembler)) ld.Node {
34
	return MustBuild(np, func(fna NodeAssembler) { fna.CreateList(sizeHint, fn) })
35 36
}

tavit ohanian's avatar
tavit ohanian committed
37
func WrapAssembler(na ld.NodeAssembler) NodeAssembler {
38 39 40 41 42 43 44 45 46
	return &nodeAssembler{na}
}

// NodeAssembler is the same as the interface in the core package, except:
// instead of returning errors, any error will cause panic
// (and you can collect these with `fluent.Recover`);
// and all recursive operations take a function as a parameter,
// within which you will receive another {Map,List,}NodeAssembler.
type NodeAssembler interface {
47 48
	CreateMap(sizeHint int64, fn func(MapAssembler))
	CreateList(sizeHint int64, fn func(ListAssembler))
49 50
	AssignNull()
	AssignBool(bool)
51
	AssignInt(int64)
52 53 54
	AssignFloat(float64)
	AssignString(string)
	AssignBytes([]byte)
tavit ohanian's avatar
tavit ohanian committed
55 56
	AssignLink(ld.Link)
	AssignNode(ld.Node)
57

tavit ohanian's avatar
tavit ohanian committed
58
	Prototype() ld.NodePrototype
59 60
}

61
// MapAssembler is the same as the interface in the core package, except:
62 63 64 65
// instead of returning errors, any error will cause panic
// (and you can collect these with `fluent.Recover`);
// and all recursive operations take a function as a parameter,
// within which you will receive another {Map,List,}NodeAssembler.
66
type MapAssembler interface {
67 68 69
	AssembleKey() NodeAssembler
	AssembleValue() NodeAssembler

70
	AssembleEntry(k string) NodeAssembler
71

tavit ohanian's avatar
tavit ohanian committed
72 73
	KeyPrototype() ld.NodePrototype
	ValuePrototype(k string) ld.NodePrototype
74 75
}

76
// ListAssembler is the same as the interface in the core package, except:
77 78 79 80
// instead of returning errors, any error will cause panic
// (and you can collect these with `fluent.Recover`);
// and all recursive operations take a function as a parameter,
// within which you will receive another {Map,List,}NodeAssembler.
81
type ListAssembler interface {
82 83
	AssembleValue() NodeAssembler

tavit ohanian's avatar
tavit ohanian committed
84
	ValuePrototype(idx int64) ld.NodePrototype
85 86 87
}

type nodeAssembler struct {
tavit ohanian's avatar
tavit ohanian committed
88
	na ld.NodeAssembler
89 90
}

91
func (fna *nodeAssembler) CreateMap(sizeHint int64, fn func(MapAssembler)) {
92 93 94 95 96 97 98 99 100
	if ma, err := fna.na.BeginMap(sizeHint); err != nil {
		panic(Error{err})
	} else {
		fn(&mapNodeAssembler{ma})
		if err := ma.Finish(); err != nil {
			panic(Error{err})
		}
	}
}
101
func (fna *nodeAssembler) CreateList(sizeHint int64, fn func(ListAssembler)) {
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
	if la, err := fna.na.BeginList(sizeHint); err != nil {
		panic(Error{err})
	} else {
		fn(&listNodeAssembler{la})
		if err := la.Finish(); err != nil {
			panic(Error{err})
		}
	}
}
func (fna *nodeAssembler) AssignNull() {
	if err := fna.na.AssignNull(); err != nil {
		panic(Error{err})
	}
}
func (fna *nodeAssembler) AssignBool(v bool) {
	if err := fna.na.AssignBool(v); err != nil {
		panic(Error{err})
	}
}
121
func (fna *nodeAssembler) AssignInt(v int64) {
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
	if err := fna.na.AssignInt(v); err != nil {
		panic(Error{err})
	}
}
func (fna *nodeAssembler) AssignFloat(v float64) {
	if err := fna.na.AssignFloat(v); err != nil {
		panic(Error{err})
	}
}
func (fna *nodeAssembler) AssignString(v string) {
	if err := fna.na.AssignString(v); err != nil {
		panic(Error{err})
	}
}
func (fna *nodeAssembler) AssignBytes(v []byte) {
	if err := fna.na.AssignBytes(v); err != nil {
		panic(Error{err})
	}
}
tavit ohanian's avatar
tavit ohanian committed
141
func (fna *nodeAssembler) AssignLink(v ld.Link) {
142 143 144 145
	if err := fna.na.AssignLink(v); err != nil {
		panic(Error{err})
	}
}
tavit ohanian's avatar
tavit ohanian committed
146
func (fna *nodeAssembler) AssignNode(v ld.Node) {
147
	if err := fna.na.AssignNode(v); err != nil {
148 149 150
		panic(Error{err})
	}
}
tavit ohanian's avatar
tavit ohanian committed
151
func (fna *nodeAssembler) Prototype() ld.NodePrototype {
152
	return fna.na.Prototype()
153 154 155
}

type mapNodeAssembler struct {
tavit ohanian's avatar
tavit ohanian committed
156
	ma ld.MapAssembler
157 158 159 160 161 162 163 164
}

func (fma *mapNodeAssembler) AssembleKey() NodeAssembler {
	return &nodeAssembler{fma.ma.AssembleKey()}
}
func (fma *mapNodeAssembler) AssembleValue() NodeAssembler {
	return &nodeAssembler{fma.ma.AssembleValue()}
}
165 166
func (fma *mapNodeAssembler) AssembleEntry(k string) NodeAssembler {
	va, err := fma.ma.AssembleEntry(k)
167 168 169 170 171
	if err != nil {
		panic(Error{err})
	}
	return &nodeAssembler{va}
}
tavit ohanian's avatar
tavit ohanian committed
172
func (fma *mapNodeAssembler) KeyPrototype() ld.NodePrototype {
173
	return fma.ma.KeyPrototype()
174
}
tavit ohanian's avatar
tavit ohanian committed
175
func (fma *mapNodeAssembler) ValuePrototype(k string) ld.NodePrototype {
176
	return fma.ma.ValuePrototype(k)
177 178 179
}

type listNodeAssembler struct {
tavit ohanian's avatar
tavit ohanian committed
180
	la ld.ListAssembler
181 182 183 184 185
}

func (fla *listNodeAssembler) AssembleValue() NodeAssembler {
	return &nodeAssembler{fla.la.AssembleValue()}
}
tavit ohanian's avatar
tavit ohanian committed
186
func (fla *listNodeAssembler) ValuePrototype(idx int64) ld.NodePrototype {
187
	return fla.la.ValuePrototype(idx)
188
}