github.com/dahs81/otto@v0.2.1-0.20160126165905-6400716cf085/foundation/tuple.go (about)

     1  package foundation
     2  
     3  import (
     4  	"fmt"
     5  )
     6  
     7  // Tuple is the tupled used for looking up the Foundation implementation
     8  // for an Appfile. This struct is usually used in its non-pointer form, to be
     9  // a key for maps.
    10  type Tuple struct {
    11  	Type        string // Type is the foundation type, i.e. "consul"
    12  	Infra       string // Infra is the infra type, i.e. "aws"
    13  	InfraFlavor string // InfraFlavor is the flavor, i.e. "vpc-public-private"
    14  }
    15  
    16  func (t Tuple) String() string {
    17  	return fmt.Sprintf("(%q, %q, %q)", t.Type, t.Infra, t.InfraFlavor)
    18  }
    19  
    20  // TupleSlice is an alias of []Tuple that implements sort.Interface for
    21  // sorting tuples. See the tests in tuple_test.go to see the sorting order.
    22  type TupleSlice []Tuple
    23  
    24  // sort.Interface impl.
    25  func (s TupleSlice) Len() int      { return len(s) }
    26  func (s TupleSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
    27  func (s TupleSlice) Less(i, j int) bool {
    28  	if s[i].Type != s[j].Type {
    29  		return s[i].Type < s[j].Type
    30  	}
    31  
    32  	if s[i].Infra != s[j].Infra {
    33  		return s[i].Infra < s[j].Infra
    34  	}
    35  
    36  	if s[i].InfraFlavor != s[j].InfraFlavor {
    37  		return s[i].InfraFlavor < s[j].InfraFlavor
    38  	}
    39  
    40  	return false
    41  }
    42  
    43  // Map turns a TupleSlice into a map where all the tuples in the slice
    44  // are mapped to a single factory function.
    45  func (s TupleSlice) Map(f Factory) TupleMap {
    46  	m := make(TupleMap, len(s))
    47  	for _, t := range s {
    48  		m[t] = f
    49  	}
    50  
    51  	return m
    52  }
    53  
    54  // TupleMap is an alias of map[Tuple]Factory that adds additional helper
    55  // methods on top to help work with app tuples.
    56  type TupleMap map[Tuple]Factory
    57  
    58  // Lookup looks up a Tuple. This should be used instead of direct [] access
    59  // since it respects wildcards ('*') within the Tuple.
    60  func (m TupleMap) Lookup(t Tuple) Factory {
    61  	// If it just exists, return it
    62  	if f, ok := m[t]; ok {
    63  		return f
    64  	}
    65  
    66  	// Eh, this isn't terrible complexity, but we should probably look
    67  	// to do better than this at some point.
    68  	for h, f := range m {
    69  		if h.Type != "*" && h.Type != t.Type {
    70  			continue
    71  		}
    72  		if h.Infra != "*" && h.Infra != t.Infra {
    73  			continue
    74  		}
    75  		if h.InfraFlavor != "*" && h.InfraFlavor != t.InfraFlavor {
    76  			continue
    77  		}
    78  
    79  		return f
    80  	}
    81  
    82  	return nil
    83  }
    84  
    85  // Add is a helper to add another map to this one.
    86  func (m TupleMap) Add(m2 TupleMap) {
    87  	for k, v := range m2 {
    88  		m[k] = v
    89  	}
    90  }