package schema import ( "fmt" ) // MultiLevelFieldReader reads from other field readers, // merging their results along the way in a specific order. You can specify // "levels" and name them in order to read only an exact level or up to // a specific level. // // This is useful for saying things such as "read the field from the state // and config and merge them" or "read the latest value of the field". type MultiLevelFieldReader struct { Readers map[string]FieldReader Levels []string } func (r *MultiLevelFieldReader) ReadField(address []string) (FieldReadResult, error) { return r.ReadFieldMerge(address, r.Levels[len(r.Levels)-1]) } func (r *MultiLevelFieldReader) ReadFieldExact( address []string, level string) (FieldReadResult, error) { reader, ok := r.Readers[level] if !ok { return FieldReadResult{}, fmt.Errorf( "Unknown reader level: %s", level) } result, err := reader.ReadField(address) if err != nil { return FieldReadResult{}, fmt.Errorf( "Error reading level %s: %s", level, err) } return result, nil } func (r *MultiLevelFieldReader) ReadFieldMerge( address []string, level string) (FieldReadResult, error) { var result FieldReadResult for _, l := range r.Levels { if r, ok := r.Readers[l]; ok { out, err := r.ReadField(address) if err != nil { return FieldReadResult{}, fmt.Errorf( "Error reading level %s: %s", l, err) } // TODO: computed if out.Exists { result = out } } if l == level { break } } return result, nil }