Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

+ PartnerLink, ProgramUserRole #926

Merged
merged 1 commit into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.core.enums

import lucuma.core.util.Enumerated

enum PartnerLinkType(val tag: String) derives Enumerated:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

embracing whitespace?


case HasPartner extends PartnerLinkType("has_partner")
case HasNonPartner extends PartnerLinkType("has_non_partner")
case HasUnspecifiedPartner extends PartnerLinkType("has_unspecified_partner")

end PartnerLinkType
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.core.enums

import lucuma.core.util.Enumerated

enum ProgramUserRole(val tag: String) derives Enumerated:

case Pi extends ProgramUserRole("pi")
case Coi extends ProgramUserRole("coi")
case CoiRO extends ProgramUserRole("coi_ro")
case Support extends ProgramUserRole("support")

end ProgramUserRole
102 changes: 102 additions & 0 deletions modules/core/shared/src/main/scala/lucuma/core/model/PartnerLink.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.core.model



import cats.Eq
import cats.syntax.either.*
import lucuma.core.enums.Partner
import lucuma.core.enums.PartnerLinkType
import monocle.Iso


/**
* Embodies the association between a user and a partner, if any. There are
* three possible values: `HasPartner` (meaning the user is tied to a particular
* `Partner`), `HasNonPartner` (the user is explicitly not associated with any
* `Partner`) and `HasUnspecifiedPartner` (the relationship is not yet
* determined).
*/
sealed trait PartnerLink extends Product with Serializable:

def linkType: PartnerLinkType =
fold(
PartnerLinkType.HasUnspecifiedPartner,
PartnerLinkType.HasNonPartner,
_ => PartnerLinkType.HasPartner
)

/**
* Converts to an either where Left(true) is `HasNonPartner`, Left(false) is
* `HasUnspecifiedPartner` and Right(partner) is `HasPartner`.
*/
def toEither: Either[Boolean, Partner] =
fold(false.asLeft, true.asLeft, _.asRight)

/**
* Creates an Option[Partner] which is Some when this link is `HasPartner`.
*/
def partnerOption: Option[Partner] =
toEither.toOption

/**
* True only if HasNonPartner.
*/
def isNonPartner: Boolean =
fold(false, true, _ => false)

/**
* True if HasPartner or HasNonPartner.
*/
def isSet: Boolean =
fold(false, true, _ => true)

/**
* True only if HasUnspecifiedPartner. Same as `!isSet`.
*/
def isUnspecified: Boolean =
!isSet

def fold[A](unspecified: => A, hasNonPartner: => A, hasPartner: Partner => A): A =
this match {
case PartnerLink.HasUnspecifiedPartner => unspecified
case PartnerLink.HasNonPartner => hasNonPartner
case PartnerLink.HasPartner(p) => hasPartner(p)
}
end PartnerLink

object PartnerLink:

case class HasPartner(partner: Partner) extends PartnerLink
case object HasNonPartner extends PartnerLink
case object HasUnspecifiedPartner extends PartnerLink

given Eq[PartnerLink] =
Eq.by(_.toEither)

private def fromEither(e: Either[Boolean, Partner]): PartnerLink =
e.fold(b => if (b) HasNonPartner else HasUnspecifiedPartner, HasPartner.apply)

/**
* Iso for an Either where Left(true) is HasNoPartner and Left(false) is
* HasUnspecifiedPartner.
*/
val either: Iso[PartnerLink, Either[Boolean, Partner]] =
Iso[PartnerLink, Either[Boolean, Partner]](_.toEither)(fromEither)

/**
* Creates a `PartnerLink` where a None value for `Partner` is interpreted as
* `HasNonPartner`.
*/
def asNonPartner(p: Option[Partner]): PartnerLink =
p.fold(HasNonPartner)(HasPartner.apply)

def fromLinkType(linkType: PartnerLinkType, partner: Option[Partner] = None): Either[String, PartnerLink] =
linkType match
case PartnerLinkType.HasPartner => partner.map(HasPartner.apply).toRight("HasPartner instance missing partner")
case PartnerLinkType.HasNonPartner => HasNonPartner.asRight
case PartnerLinkType.HasUnspecifiedPartner => HasUnspecifiedPartner.asRight

end PartnerLink
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.core.model
package arb

import lucuma.core.enums.Partner
import lucuma.core.enums.PartnerLinkType
import lucuma.core.util.arb.ArbEnumerated
import org.scalacheck.*
import org.scalacheck.Arbitrary.arbitrary
import org.scalacheck.Gen.const


trait ArbPartnerLink {

import ArbEnumerated.given

given Arbitrary[PartnerLink.HasPartner] =
Arbitrary {
arbitrary[Partner].map(PartnerLink.HasPartner.apply)
}

given Cogen[PartnerLink.HasPartner] =
Cogen[Partner].contramap(_.partner)

given Arbitrary[PartnerLink] =
Arbitrary {
Gen.oneOf(
arbitrary[PartnerLink.HasPartner],
const(PartnerLink.HasNonPartner),
const(PartnerLink.HasUnspecifiedPartner)
)
}

given Cogen[PartnerLink] =
Cogen[(PartnerLinkType, Option[Partner])].contramap { a => (
a.linkType,
a.partnerOption
)}

}

object ArbPartnerLink extends ArbPartnerLink
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) 2016-2023 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package lucuma.core.model

import cats.kernel.laws.discipline.EqTests
import lucuma.core.model.arb.ArbPartnerLink
import munit.*

final class PartnerLinkSuite extends DisciplineSuite:

import ArbPartnerLink.given

checkAll("PartnerLink", EqTests[PartnerLink].eqv)

end PartnerLinkSuite
Loading