-
Notifications
You must be signed in to change notification settings - Fork 23
Expand file tree
/
Copy pathvalue_spec.go
More file actions
72 lines (60 loc) · 1.85 KB
/
value_spec.go
File metadata and controls
72 lines (60 loc) · 1.85 KB
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
package quickjs
import (
"errors"
"fmt"
)
var errValueSpecFactoryRequired = errors.New("value spec factory is required")
// ValueSpec describes how to materialize a JavaScript value for a target Context.
// Module/Class builders use ValueSpec to store definitions instead of long-lived JSValue pointers.
// ValueSpec implementations are expected to be immutable after being added to a builder.
// Builder snapshots only shallow-copy entries, so mutating pointer-backed specs after
// Build can change later module initialization or class construction behavior.
type ValueSpec interface {
Materialize(ctx *Context) (*Value, error)
}
func materializeValueSpecSafely(ctx *Context, spec ValueSpec) (value *Value, err error) {
defer func() {
if recovered := recover(); recovered != nil {
err = fmt.Errorf("panic during materialize: %v", recovered)
}
}()
return spec.Materialize(ctx)
}
// MarshalSpec materializes a value via Context.Marshal.
type MarshalSpec struct {
Value interface{}
}
func (s MarshalSpec) Materialize(ctx *Context) (*Value, error) {
return ctx.Marshal(s.Value)
}
// FactorySpec materializes a value by running a Context-aware factory.
type FactorySpec struct {
Factory func(ctx *Context) (*Value, error)
}
func (s FactorySpec) Materialize(ctx *Context) (*Value, error) {
if s.Factory == nil {
return nil, errValueSpecFactoryRequired
}
return s.Factory(ctx)
}
// contextValueSpec preserves legacy, context-bound Export(name, *Value) behavior.
type contextValueSpec struct {
value *Value
}
func (s contextValueSpec) Materialize(_ *Context) (*Value, error) {
if s.value == nil {
return nil, errors.New("context-bound value is nil")
}
return s.value, nil
}
func isContextValueSpec(spec ValueSpec) bool {
if spec == nil {
return false
}
_, ok := spec.(contextValueSpec)
if ok {
return true
}
_, ok = spec.(*contextValueSpec)
return ok
}