lazy_identity.go

  1package models
  2
  3import (
  4	"fmt"
  5	"sync"
  6
  7	"github.com/git-bug/git-bug/cache"
  8	"github.com/git-bug/git-bug/entities/identity"
  9	"github.com/git-bug/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	// IsEntity is a sign post-method for gqlgen, to mark compliance to an interface.
 26	IsEntity()
 27}
 28
 29var _ IdentityWrapper = &lazyIdentity{}
 30
 31type lazyIdentity struct {
 32	cache   *cache.RepoCache
 33	excerpt *cache.IdentityExcerpt
 34
 35	mu sync.Mutex
 36	id *cache.IdentityCache
 37}
 38
 39func NewLazyIdentity(cache *cache.RepoCache, excerpt *cache.IdentityExcerpt) *lazyIdentity {
 40	return &lazyIdentity{
 41		cache:   cache,
 42		excerpt: excerpt,
 43	}
 44}
 45
 46func (li *lazyIdentity) load() (*cache.IdentityCache, error) {
 47	li.mu.Lock()
 48	defer li.mu.Unlock()
 49
 50	if li.id != nil {
 51		return li.id, nil
 52	}
 53
 54	id, err := li.cache.Identities().Resolve(li.excerpt.Id())
 55	if err != nil {
 56		return nil, fmt.Errorf("cache: missing identity %v", li.excerpt.Id())
 57	}
 58	li.id = id
 59	return id, nil
 60}
 61
 62func (li *lazyIdentity) Id() entity.Id {
 63	return li.excerpt.Id()
 64}
 65
 66func (li *lazyIdentity) Name() string {
 67	return li.excerpt.Name
 68}
 69
 70func (li *lazyIdentity) DisplayName() string {
 71	return li.excerpt.DisplayName()
 72}
 73
 74func (li *lazyIdentity) Email() (string, error) {
 75	id, err := li.load()
 76	if err != nil {
 77		return "", err
 78	}
 79	return id.Email(), nil
 80}
 81
 82func (li *lazyIdentity) Login() (string, error) {
 83	id, err := li.load()
 84	if err != nil {
 85		return "", err
 86	}
 87	return id.Login(), nil
 88}
 89
 90func (li *lazyIdentity) AvatarUrl() (string, error) {
 91	id, err := li.load()
 92	if err != nil {
 93		return "", err
 94	}
 95	return id.AvatarUrl(), nil
 96}
 97
 98func (li *lazyIdentity) Keys() ([]*identity.Key, error) {
 99	id, err := li.load()
100	if err != nil {
101		return nil, err
102	}
103	return id.Keys(), nil
104}
105
106func (li *lazyIdentity) IsProtected() (bool, error) {
107	id, err := li.load()
108	if err != nil {
109		return false, err
110	}
111	return id.IsProtected(), nil
112}
113
114// IsEntity is a sign post-method for gqlgen, to mark compliance to an interface.
115func (li *lazyIdentity) IsEntity() {}
116
117var _ IdentityWrapper = &loadedIdentity{}
118
119type loadedIdentity struct {
120	identity.Interface
121}
122
123func NewLoadedIdentity(id identity.Interface) *loadedIdentity {
124	return &loadedIdentity{Interface: id}
125}
126
127func (l loadedIdentity) Email() (string, error) {
128	return l.Interface.Email(), nil
129}
130
131func (l loadedIdentity) Login() (string, error) {
132	return l.Interface.Login(), nil
133}
134
135func (l loadedIdentity) AvatarUrl() (string, error) {
136	return l.Interface.AvatarUrl(), nil
137}
138
139func (l loadedIdentity) Keys() ([]*identity.Key, error) {
140	return l.Interface.Keys(), nil
141}
142
143func (l loadedIdentity) IsProtected() (bool, error) {
144	return l.Interface.IsProtected(), nil
145}
146
147// IsEntity is a sign post-method for gqlgen, to mark compliance to an interface.
148func (l loadedIdentity) IsEntity() {}