-
Notifications
You must be signed in to change notification settings - Fork 17
/
view.go
92 lines (74 loc) · 1.79 KB
/
view.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
// SPDX-FileCopyrightText: 2023 SAP SE or an SAP affiliate company and Open Component Model contributors.
//
// SPDX-License-Identifier: Apache-2.0
package refmgmt
import (
"io"
)
// Dup is the common interface for all
// objects following the ref counting model.
// It will provide a new view to the underlying
// object. This will only be closed if there are
// no more views (created via Dup()).
type Dup[V io.Closer] interface {
Dup() (V, error)
}
type ViewManager[V io.Closer] interface {
View(closerView CloserView) (V, error)
}
type viewManager[O, V io.Closer /* O */] struct {
refs ReferencableCloser
obj O
creator func(O, *View[V]) V
}
func WithView[O, V io.Closer](obj O, creator func(O, *View[V]) V, closer ...io.Closer) V {
var c Closers
c.Add(obj)
c.Add(closer...)
m := &viewManager[O, V]{
refs: NewRefCloser(c.Effective(), true),
obj: obj,
creator: creator,
}
v, _ := m.View(nil)
return v
}
func (m *viewManager[O, V]) View(v CloserView) (V, error) {
if v != nil {
var n V
err := v.Execute(func() (err error) {
n, err = m.view()
return
})
return n, err
}
return m.view()
}
func (m *viewManager[O, V]) view() (V, error) {
var _nil V
v, err := m.refs.View(false)
if err != nil {
return _nil, err
}
return m.creator(m.obj, NewView[V](m, v)), nil
}
type View[V io.Closer] struct {
mgr ViewManager[V]
view CloserView
}
var _ Dup[io.Closer] = (*View[io.Closer])(nil)
func NewView[V io.Closer](mgr ViewManager[V], v CloserView) *View[V] {
return &View[V]{mgr: mgr, view: v}
}
func (v *View[V]) Dup() (V, error) {
return v.mgr.View(v.view)
}
func (v *View[V]) Close() error {
return v.view.Close()
}
func (v *View[V]) IsClosed() bool {
return v.view.IsClosed()
}
func (v *View[V]) Execute(f func() error) error {
return v.view.Execute(f)
}