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.Identities().Resolve(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	entity.Identity
115}
116
117func NewLoadedIdentity(id entity.Identity) *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}