1package models
2
3import (
4 "fmt"
5 "sync"
6
7 "github.com/MichaelMure/git-bug/cache"
8 "github.com/MichaelMure/git-bug/entities/identity"
9 "github.com/MichaelMure/git-bug/entity"
10)
11
12// IdentityWrapper is an interface used by the GraphQL resolvers to handle an identity.
13// Depending on the situation, an Identity can already be fully loaded in memory or not.
14// This interface is used to wrap either a lazyIdentity or a loadedIdentity depending on the situation.
15type IdentityWrapper interface {
16 Id() entity.Id
17 Name() string
18 Email() (string, error)
19 Login() (string, error)
20 AvatarUrl() (string, error)
21 Keys() ([]*identity.Key, error)
22 DisplayName() string
23 IsProtected() (bool, error)
24}
25
26var _ IdentityWrapper = &lazyIdentity{}
27
28type lazyIdentity struct {
29 cache *cache.RepoCache
30 excerpt *cache.IdentityExcerpt
31
32 mu sync.Mutex
33 id *cache.IdentityCache
34}
35
36func NewLazyIdentity(cache *cache.RepoCache, excerpt *cache.IdentityExcerpt) *lazyIdentity {
37 return &lazyIdentity{
38 cache: cache,
39 excerpt: excerpt,
40 }
41}
42
43func (li *lazyIdentity) load() (*cache.IdentityCache, error) {
44 li.mu.Lock()
45 defer li.mu.Unlock()
46
47 if li.id != nil {
48 return li.id, nil
49 }
50
51 id, err := li.cache.ResolveIdentity(li.excerpt.Id)
52 if err != nil {
53 return nil, fmt.Errorf("cache: missing identity %v", li.excerpt.Id)
54 }
55 li.id = id
56 return id, nil
57}
58
59func (li *lazyIdentity) Id() entity.Id {
60 return li.excerpt.Id
61}
62
63func (li *lazyIdentity) Name() string {
64 return li.excerpt.Name
65}
66
67func (li *lazyIdentity) DisplayName() string {
68 return li.excerpt.DisplayName()
69}
70
71func (li *lazyIdentity) Email() (string, error) {
72 id, err := li.load()
73 if err != nil {
74 return "", err
75 }
76 return id.Email(), nil
77}
78
79func (li *lazyIdentity) Login() (string, error) {
80 id, err := li.load()
81 if err != nil {
82 return "", err
83 }
84 return id.Login(), nil
85}
86
87func (li *lazyIdentity) AvatarUrl() (string, error) {
88 id, err := li.load()
89 if err != nil {
90 return "", err
91 }
92 return id.AvatarUrl(), nil
93}
94
95func (li *lazyIdentity) Keys() ([]*identity.Key, error) {
96 id, err := li.load()
97 if err != nil {
98 return nil, err
99 }
100 return id.Keys(), nil
101}
102
103func (li *lazyIdentity) IsProtected() (bool, error) {
104 id, err := li.load()
105 if err != nil {
106 return false, err
107 }
108 return id.IsProtected(), nil
109}
110
111var _ IdentityWrapper = &loadedIdentity{}
112
113type loadedIdentity struct {
114 identity.Interface
115}
116
117func NewLoadedIdentity(id identity.Interface) *loadedIdentity {
118 return &loadedIdentity{Interface: id}
119}
120
121func (l loadedIdentity) Email() (string, error) {
122 return l.Interface.Email(), nil
123}
124
125func (l loadedIdentity) Login() (string, error) {
126 return l.Interface.Login(), nil
127}
128
129func (l loadedIdentity) AvatarUrl() (string, error) {
130 return l.Interface.AvatarUrl(), nil
131}
132
133func (l loadedIdentity) Keys() ([]*identity.Key, error) {
134 return l.Interface.Keys(), nil
135}
136
137func (l loadedIdentity) IsProtected() (bool, error) {
138 return l.Interface.IsProtected(), nil
139}