-
Notifications
You must be signed in to change notification settings - Fork 0
/
contextextension.go
119 lines (100 loc) · 2.66 KB
/
contextextension.go
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
package ergo
/*
#include "ergo.h"
*/
import "C"
import (
"iter"
"runtime"
"unsafe"
)
// ContextExtension represent user-defined variables to be put into context
type ContextExtension interface {
// Keys returns iterator over all keys in the ContextExtension
Keys() iter.Seq[uint8]
// Get returns Constant at provided key or nil if it doesn't exist
Get(key uint8) (Constant, error)
// Set adds Constant at provided key
Set(key uint8, constant Constant)
// All returns iterator over all key,value pairs in the ContextExtension
All() iter.Seq2[uint8, Constant]
// Values returns iterator over all Constant in the ContextExtension
Values() iter.Seq[Constant]
pointer() C.ContextExtensionPtr
}
type contextExtension struct {
p C.ContextExtensionPtr
}
func newContextExtension(c *contextExtension) ContextExtension {
runtime.SetFinalizer(c, finalizeContextExtension)
return c
}
// NewContextExtension creates new empty ContextExtension instance
func NewContextExtension() ContextExtension {
var p C.ContextExtensionPtr
C.ergo_lib_context_extension_empty(&p)
c := &contextExtension{p: p}
return newContextExtension(c)
}
func (c *contextExtension) Keys() iter.Seq[uint8] {
bytesLength := C.ergo_lib_context_extension_len(c.p)
output := C.malloc(C.uintptr_t(bytesLength))
defer C.free(unsafe.Pointer(output))
C.ergo_lib_context_extension_keys(c.p, (*C.uint8_t)(output))
result := C.GoBytes(unsafe.Pointer(output), C.int(bytesLength))
return func(yield func(uint8) bool) {
for i := 0; i < len(result); i++ {
if !yield(result[i]) {
return
}
}
}
}
func (c *contextExtension) Get(key uint8) (Constant, error) {
var p C.ConstantPtr
res := C.ergo_lib_context_extension_get(c.p, C.uint8_t(key), &p)
err := newError(res.error)
if err.isError() {
return nil, err.error()
}
if res.is_some {
co := &constant{p: p}
return newConstant(co), nil
}
return nil, nil
}
func (c *contextExtension) Set(key uint8, constant Constant) {
C.ergo_lib_context_extension_set_pair(constant.pointer(), C.uint8_t(key), c.p)
}
func (c *contextExtension) All() iter.Seq2[uint8, Constant] {
return func(yield func(uint8, Constant) bool) {
for key := range c.Keys() {
ce, err := c.Get(key)
if err != nil {
return
}
if !yield(key, ce) {
return
}
}
}
}
func (c *contextExtension) Values() iter.Seq[Constant] {
return func(yield func(Constant) bool) {
for key := range c.Keys() {
ce, err := c.Get(key)
if err != nil {
return
}
if !yield(ce) {
return
}
}
}
}
func (c *contextExtension) pointer() C.ContextExtensionPtr {
return c.p
}
func finalizeContextExtension(c *contextExtension) {
C.ergo_lib_context_extension_delete(c.p)
}