github.com/altipla-consulting/ravendb-go-client@v0.1.3/lazy.go (about)

     1  package ravendb
     2  
     3  import "sync"
     4  
     5  // Lazy represents a lazy operation
     6  type Lazy struct {
     7  	// function which, when called, executes lazy operation
     8  	valueFactory func(interface{}) error
     9  	err          error
    10  	valueCreated bool
    11  	Value        interface{}
    12  	mu           sync.Mutex
    13  }
    14  
    15  func newLazy(valueFactory func(interface{}) error) *Lazy {
    16  	return &Lazy{
    17  		valueFactory: valueFactory,
    18  	}
    19  }
    20  
    21  // IsValueCreated returns true if lazy value has been created
    22  func (l *Lazy) IsValueCreated() bool {
    23  	l.mu.Lock()
    24  	defer l.mu.Unlock()
    25  
    26  	if l.err != nil {
    27  		return false
    28  	}
    29  
    30  	return l.valueCreated
    31  }
    32  
    33  // GetValue executes lazy operation and ensures the Value is set in result variable
    34  // provided in NewLazy()
    35  func (l *Lazy) GetValue(result interface{}) error {
    36  	if result == nil {
    37  		return newIllegalArgumentError("result cannot be nil")
    38  	}
    39  	l.mu.Lock()
    40  	defer l.mu.Unlock()
    41  
    42  	if !l.valueCreated {
    43  		l.err = l.valueFactory(result)
    44  		l.valueCreated = true
    45  		if l.err != nil {
    46  			l.Value = result
    47  		}
    48  	}
    49  
    50  	if l.err != nil {
    51  		return l.err
    52  	}
    53  
    54  	if l.Value == nil {
    55  		return nil
    56  	}
    57  
    58  	// can call with nil to force evaluation of lazy operations
    59  	if result != nil {
    60  		setInterfaceToValue(result, l.Value)
    61  	}
    62  
    63  	return nil
    64  }