github.com/bigkraig/terraform@v0.6.4-0.20151219155159-c90d1b074e31/helper/schema/field_reader_multi.go (about)

     1  package schema
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  // MultiLevelFieldReader reads from other field readers,
     8  // merging their results along the way in a specific order. You can specify
     9  // "levels" and name them in order to read only an exact level or up to
    10  // a specific level.
    11  //
    12  // This is useful for saying things such as "read the field from the state
    13  // and config and merge them" or "read the latest value of the field".
    14  type MultiLevelFieldReader struct {
    15  	Readers map[string]FieldReader
    16  	Levels  []string
    17  }
    18  
    19  func (r *MultiLevelFieldReader) ReadField(address []string) (FieldReadResult, error) {
    20  	return r.ReadFieldMerge(address, r.Levels[len(r.Levels)-1])
    21  }
    22  
    23  func (r *MultiLevelFieldReader) ReadFieldExact(
    24  	address []string, level string) (FieldReadResult, error) {
    25  	reader, ok := r.Readers[level]
    26  	if !ok {
    27  		return FieldReadResult{}, fmt.Errorf(
    28  			"Unknown reader level: %s", level)
    29  	}
    30  
    31  	result, err := reader.ReadField(address)
    32  	if err != nil {
    33  		return FieldReadResult{}, fmt.Errorf(
    34  			"Error reading level %s: %s", level, err)
    35  	}
    36  
    37  	return result, nil
    38  }
    39  
    40  func (r *MultiLevelFieldReader) ReadFieldMerge(
    41  	address []string, level string) (FieldReadResult, error) {
    42  	var result FieldReadResult
    43  	for _, l := range r.Levels {
    44  		if r, ok := r.Readers[l]; ok {
    45  			out, err := r.ReadField(address)
    46  			if err != nil {
    47  				return FieldReadResult{}, fmt.Errorf(
    48  					"Error reading level %s: %s", l, err)
    49  			}
    50  
    51  			// TODO: computed
    52  			if out.Exists {
    53  				result = out
    54  			}
    55  		}
    56  
    57  		if l == level {
    58  			break
    59  		}
    60  	}
    61  
    62  	return result, nil
    63  }