-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathregistry.go
52 lines (47 loc) · 1.21 KB
/
registry.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
package godiff
import (
"reflect"
"sync"
)
//Registry represents differ registry
type Registry struct {
sync.RWMutex
differs map[reflect.Type]map[reflect.Type]*Differ
}
func (r *Registry) Get(from, to reflect.Type, tag *Tag, options ...ConfigOption) (*Differ, error) {
if tag != nil && (tag.PairSeparator != "" || tag.ItemSeparator != "") {
return New(from, to, WithRegistry(r), WithTag(tag))
}
fromDiffers := r.getFromDiffers(from)
r.RWMutex.RLock()
differ, ok := fromDiffers[to]
r.RWMutex.RUnlock()
if ok {
return differ, nil
}
var err error
options = append(options, WithRegistry(r), WithTag(tag))
if differ, err = New(from, to, options...); err != nil {
return nil, err
}
r.RWMutex.Lock()
fromDiffers[to] = differ
r.RWMutex.Unlock()
return differ, nil
}
func (r *Registry) getFromDiffers(from reflect.Type) map[reflect.Type]*Differ {
r.RWMutex.RLock()
fromDiffers, ok := r.differs[from]
r.RWMutex.RUnlock()
if ok {
return fromDiffers
}
r.RWMutex.Lock()
fromDiffers = make(map[reflect.Type]*Differ)
r.differs[from] = make(map[reflect.Type]*Differ)
r.RWMutex.Unlock()
return fromDiffers
}
func NewRegistry() *Registry {
return &Registry{differs: map[reflect.Type]map[reflect.Type]*Differ{}}
}