github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/state/endpoint.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/juju/charm"
    10  )
    11  
    12  // counterpartRole returns the RelationRole that this RelationRole
    13  // can relate to.
    14  // This should remain an internal method because the relation
    15  // model does not guarantee that for every role there will
    16  // necessarily exist a single counterpart role that is sensible
    17  // for basing algorithms upon.
    18  func counterpartRole(r charm.RelationRole) charm.RelationRole {
    19  	switch r {
    20  	case charm.RoleProvider:
    21  		return charm.RoleRequirer
    22  	case charm.RoleRequirer:
    23  		return charm.RoleProvider
    24  	case charm.RolePeer:
    25  		return charm.RolePeer
    26  	}
    27  	panic(fmt.Errorf("unknown relation role %q", r))
    28  }
    29  
    30  // Endpoint represents one endpoint of a relation.
    31  type Endpoint struct {
    32  	ServiceName string
    33  	charm.Relation
    34  }
    35  
    36  // String returns the unique identifier of the relation endpoint.
    37  func (ep Endpoint) String() string {
    38  	return ep.ServiceName + ":" + ep.Name
    39  }
    40  
    41  // CanRelateTo returns whether a relation may be established between e and other.
    42  func (ep Endpoint) CanRelateTo(other Endpoint) bool {
    43  	return ep.ServiceName != other.ServiceName &&
    44  		ep.Interface == other.Interface &&
    45  		ep.Role != charm.RolePeer &&
    46  		counterpartRole(ep.Role) == other.Role
    47  }
    48  
    49  type epSlice []Endpoint
    50  
    51  var roleOrder = map[charm.RelationRole]int{
    52  	charm.RoleRequirer: 0,
    53  	charm.RoleProvider: 1,
    54  	charm.RolePeer:     2,
    55  }
    56  
    57  func (eps epSlice) Len() int      { return len(eps) }
    58  func (eps epSlice) Swap(i, j int) { eps[i], eps[j] = eps[j], eps[i] }
    59  func (eps epSlice) Less(i, j int) bool {
    60  	ep1 := eps[i]
    61  	ep2 := eps[j]
    62  	if ep1.Role != ep2.Role {
    63  		return roleOrder[ep1.Role] < roleOrder[ep2.Role]
    64  	}
    65  	return ep1.String() < ep2.String()
    66  }