func lookupUser(userPHID string) (*user, error) {
	return userCacheLookup(userPHID, userLookupCache, func() (*user, error) {
		queryRequest := userQueryRequest{IDs: []string{userPHID}}
		var queryResponse userQueryResponse
		runArcCommandOrDie("user.query", queryRequest, &queryResponse)
		if queryResponse.Error != "" {
			return nil, fmt.Errorf("Failed to query the Phabricator users: %s", queryResponse.ErrorMessage)
		}
		if len(queryResponse.Response) != 1 {
			return nil, nil
		}
		return &queryResponse.Response[0], nil
	})
}
lookupUser reads the Phabricator user given the corresponding unique ID.
package arcanist
import (
	"fmt"
	"time"
)
type userQueryRequest struct {
	Emails    []string `json:"emails,omitempty"`
	UserNames []string `json:"usernames,omitempty"`
	IDs       []string `json:"phids,omitempty"`
}
type user struct {
	PHID     string `json:"phid"`
	UserName string `json:"userName,omitempty"`
	RealName string `json:"realName,omitempty"`
	Email    string `json:"primaryEmail,omitempty"`
}
type cachedUser struct {
	User *user
	Time time.Time
}
type userQueryResponse struct {
	Error        string `json:"error,omitempty"`
	ErrorMessage string `json:"errorMessage,omitempty"`
	Response     []user `json:"response,omitempty"`
}
type whoAmIResponse struct {
	Error        string `json:"error,omitempty"`
	ErrorMessage string `json:"errorMessage,omitempty"`
	Response     user   `json:"response,omitempty"`
}
var userQueryCache = make(map[string]cachedUser)
var userLookupCache = make(map[string]cachedUser)
var userCacheDuration = -(time.Minute * 5)
func userCacheLookup(key string, cache map[string]cachedUser, f func() (*user, error)) (*user, error) {
	if cachedValue, ok := cache[key]; ok {
		if cachedValue.Time.After(time.Now().Add(userCacheDuration)) {
			return cachedValue.User, nil
		}
	}
	result, err := f()
	if err != nil {
		return result, err
	}
	cache[key] = cachedUser{
		User: result,
		Time: time.Now(),
	}
	return result, nil
}
func queryUser(name string) (*user, error) {
	return userCacheLookup(name, userQueryCache, func() (*user, error) {
		emailQueryRequest := userQueryRequest{Emails: []string{name}}
		var queryResponse userQueryResponse
		runArcCommandOrDie("user.query", emailQueryRequest, &queryResponse)
		if queryResponse.Error != "" {
			return nil, fmt.Errorf("Failed to query the Phabricator users: %s", queryResponse.ErrorMessage)
		}
		if len(queryResponse.Response) == 0 {
			usernameQueryRequest := userQueryRequest{UserNames: []string{name}}
			runArcCommandOrDie("user.query", usernameQueryRequest, &queryResponse)
			if queryResponse.Error != "" {
				return nil, fmt.Errorf("Failed to query the Phabricator users: %s", queryResponse.ErrorMessage)
			}
		}
		if len(queryResponse.Response) != 1 {
			return nil, nil
		}
		return &queryResponse.Response[0], nil
	})
}
type UserLookup func(userPHID string) (*user, error)