from __future__ import annotations
from typing import Tuple, NamedTuple, FrozenSet, TYPE_CHECKING
if TYPE_CHECKING:
from nrel.hive.util.typealiases import MembershipId
PUBLIC_MEMBERSHIP_ID = "public"
[docs]class Membership(NamedTuple):
"""
class representing a collection of membership ids.
"""
memberships: FrozenSet[MembershipId] = frozenset()
[docs] @classmethod
def from_tuple(cls, member_ids: Tuple[MembershipId, ...]) -> Membership:
"""
build membership from tuple.
:param member_ids:
:return:
"""
if any([m == PUBLIC_MEMBERSHIP_ID for m in member_ids]):
raise TypeError(f"{PUBLIC_MEMBERSHIP_ID} is reserved, please use another membership id")
return Membership(frozenset(member_ids))
[docs] @classmethod
def single_membership(cls, membership_id: MembershipId) -> Membership:
"""
build membership with single member id
:param membership_id:
:return:
"""
if membership_id == PUBLIC_MEMBERSHIP_ID:
raise TypeError(f"{PUBLIC_MEMBERSHIP_ID} is reserved, please use another membership id")
return Membership(frozenset((membership_id,)))
@property
def public(self) -> bool:
return len(self.memberships) == 0
[docs] def add_membership(self, membership_id: MembershipId) -> Membership:
"""
add a single membership id
:param membership_id:
:return:
"""
if membership_id == PUBLIC_MEMBERSHIP_ID:
raise TypeError(f"{PUBLIC_MEMBERSHIP_ID} is reserved, please use another membership id")
new_member_ids = [m for m in self.memberships] + [membership_id]
return self._replace(memberships=frozenset(new_member_ids))
[docs] def memberships_in_common(self, other_membership: Membership) -> FrozenSet[MembershipId]:
"""
lists the MembershipIds in common with another Membership, such as to identify
which ride hail service provider was used to pick up a request
:param other_membership: the memberships of another entity in the simulation
:return: the memberships in common
"""
return self.memberships.intersection(other_membership.memberships)
[docs] def grant_access_to_membership(self, other_membership: Membership) -> bool:
"""
returns true if another membership has access to this membership
:param other_membership:
:return:
"""
if self.public:
return True
else:
return len(self.memberships_in_common(other_membership)) > 0
[docs] def grant_access_to_membership_id(self, membership_id: MembershipId) -> bool:
"""
returns true if the membership id is valid for this membership
:param membership_id:
:return:
"""
if self.public:
return True
else:
return membership_id in self.memberships
[docs] def as_tuple(self) -> Tuple[MembershipId, ...]:
return tuple(m for m in self.memberships)
[docs] def __str__(self):
"""
string representation of memberships
:return: a comma-delimited string of the membership ids
"""
return ",".join(self.memberships)
[docs] def to_json(self):
if len(self.memberships) > 0:
return list(self.memberships)
else:
return None