-
Notifications
You must be signed in to change notification settings - Fork 7
/
result.go
85 lines (74 loc) · 1.78 KB
/
result.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
package automerge
/*
#include "automerge.h"
#cgo LDFLAGS: -L${SRCDIR}/deps
#cgo darwin,arm64 LDFLAGS: -lautomerge_core_darwin_arm64
#cgo darwin,amd64 LDFLAGS: -lautomerge_core_darwin_amd64
#cgo linux,arm64 LDFLAGS: -lautomerge_core_linux_arm64 -lm
#cgo linux,amd64 LDFLAGS: -lautomerge_core_linux_amd64 -lm
*/
import "C"
import (
"fmt"
"runtime"
_ "github.com/automerge/automerge-go/deps"
)
// result wraps an AMresult, and arranges for it to be AMfree'd after
// the result is garbage collected.
type result struct {
cResult *C.AMresult
}
func wrap(r *C.AMresult) *result {
ret := &result{r}
runtime.SetFinalizer(ret, func(*result) { C.AMresultFree(r) })
return ret
}
func (r *result) void() error {
item, err := r.item()
if err != nil {
return err
}
if err == nil && item.Kind() != KindVoid {
return fmt.Errorf("expected KindVoid, got: %s", item.Kind())
}
return nil
}
func (r *result) item() (*item, error) {
items, err := r.items()
if err != nil {
return nil, err
}
if len(items) != 1 {
return nil, fmt.Errorf("automerge: expected single return value, got %v", len(items))
}
return items[0], nil
}
func (r *result) items() ([]*item, error) {
defer runtime.KeepAlive(r)
switch C.AMresultStatus(r.cResult) {
case C.AM_STATUS_OK:
items := C.AMresultItems(r.cResult)
ret := []*item{}
for {
i := C.AMitemsNext(&items, 1)
if i == nil {
break
}
ret = append(ret, &item{result: r, cItem: i})
}
return ret, nil
case C.AM_STATUS_ERROR:
msg := fromByteSpanStr(C.AMresultError(r.cResult))
return nil, fmt.Errorf(msg)
case C.AM_STATUS_INVALID_RESULT:
return nil, fmt.Errorf("automerge: invalid result")
default:
return nil, fmt.Errorf("automerge: invalid result status")
}
}
func must[T any](r T, e error) T {
if e != nil {
panic(e)
}
return r
}