github.com/adamar/terraform@v0.2.2-0.20141016210445-2e703afdad0e/flatmap/map.go (about)

     1  package flatmap
     2  
     3  import (
     4  	"strings"
     5  )
     6  
     7  // Map is a wrapper around map[string]string that provides some helpers
     8  // above it that assume the map is in the format that flatmap expects
     9  // (the result of Flatten).
    10  //
    11  // All modifying functions such as Delete are done in-place unless
    12  // otherwise noted.
    13  type Map map[string]string
    14  
    15  // Contains returns true if the map contains the given key.
    16  func (m Map) Contains(key string) bool {
    17  	for _, k := range m.Keys() {
    18  		if k == key {
    19  			return true
    20  		}
    21  	}
    22  
    23  	return false
    24  }
    25  
    26  // Delete deletes a key out of the map with the given prefix.
    27  func (m Map) Delete(prefix string) {
    28  	for k, _ := range m {
    29  		match := k == prefix
    30  		if !match {
    31  			if !strings.HasPrefix(k, prefix) {
    32  				continue
    33  			}
    34  
    35  			if k[len(prefix):len(prefix)+1] != "." {
    36  				continue
    37  			}
    38  		}
    39  
    40  		delete(m, k)
    41  	}
    42  }
    43  
    44  // Keys returns all of the top-level keys in this map
    45  func (m Map) Keys() []string {
    46  	ks := make(map[string]struct{})
    47  	for k, _ := range m {
    48  		idx := strings.Index(k, ".")
    49  		if idx == -1 {
    50  			idx = len(k)
    51  		}
    52  
    53  		ks[k[:idx]] = struct{}{}
    54  	}
    55  
    56  	result := make([]string, 0, len(ks))
    57  	for k, _ := range ks {
    58  		result = append(result, k)
    59  	}
    60  
    61  	return result
    62  }
    63  
    64  // Merge merges the contents of the other Map into this one.
    65  //
    66  // This merge is smarter than a simple map iteration because it
    67  // will fully replace arrays and other complex structures that
    68  // are present in this map with the other map's. For example, if
    69  // this map has a 3 element "foo" list, and m2 has a 2 element "foo"
    70  // list, then the result will be that m has a 2 element "foo"
    71  // list.
    72  func (m Map) Merge(m2 Map) {
    73  	for _, prefix := range m2.Keys() {
    74  		m.Delete(prefix)
    75  
    76  		for k, v := range m2 {
    77  			if strings.HasPrefix(k, prefix) {
    78  				m[k] = v
    79  			}
    80  		}
    81  	}
    82  }