launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/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  	"launchpad.net/errgo/errors"
     8  	"launchpad.net/juju-core/charm"
     9  )
    10  
    11  // counterpartRole returns the RelationRole that this RelationRole
    12  // can relate to.
    13  // This should remain an internal method because the relation
    14  // model does not guarantee that for every role there will
    15  // necessarily exist a single counterpart role that is sensible
    16  // for basing algorithms upon.
    17  func counterpartRole(r charm.RelationRole) charm.RelationRole {
    18  	switch r {
    19  	case charm.RoleProvider:
    20  		return charm.RoleRequirer
    21  	case charm.RoleRequirer:
    22  		return charm.RoleProvider
    23  	case charm.RolePeer:
    24  		return charm.RolePeer
    25  	}
    26  	panic(errors.Newf("unknown relation role %q", r))
    27  }
    28  
    29  // Endpoint represents one endpoint of a relation.
    30  type Endpoint struct {
    31  	ServiceName string
    32  	charm.Relation
    33  }
    34  
    35  // String returns the unique identifier of the relation endpoint.
    36  func (ep Endpoint) String() string {
    37  	return ep.ServiceName + ":" + ep.Name
    38  }
    39  
    40  // CanRelateTo returns whether a relation may be established between e and other.
    41  func (ep Endpoint) CanRelateTo(other Endpoint) bool {
    42  	return ep.ServiceName != other.ServiceName &&
    43  		ep.Interface == other.Interface &&
    44  		ep.Role != charm.RolePeer &&
    45  		counterpartRole(ep.Role) == other.Role
    46  }
    47  
    48  type epSlice []Endpoint
    49  
    50  var roleOrder = map[charm.RelationRole]int{
    51  	charm.RoleRequirer: 0,
    52  	charm.RoleProvider: 1,
    53  	charm.RolePeer:     2,
    54  }
    55  
    56  func (eps epSlice) Len() int      { return len(eps) }
    57  func (eps epSlice) Swap(i, j int) { eps[i], eps[j] = eps[j], eps[i] }
    58  func (eps epSlice) Less(i, j int) bool {
    59  	ep1 := eps[i]
    60  	ep2 := eps[j]
    61  	if ep1.Role != ep2.Role {
    62  		return roleOrder[ep1.Role] < roleOrder[ep2.Role]
    63  	}
    64  	return ep1.String() < ep2.String()
    65  }