Skip to content

Commit

Permalink
Merge pull request #387 from gemini-hlsw/dynamic-enums
Browse files Browse the repository at this point in the history
Dynamic enum logic
  • Loading branch information
rpiaggio authored Dec 7, 2023
2 parents ca077e9 + dbda74f commit 6390b3c
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 31 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ val munitCatsEffectVersion = "1.0.7"
val lucumaCoreVersion = "0.88.2"
val lucumaODBSchema = "0.7.0"

ThisBuild / tlBaseVersion := "0.64"
ThisBuild / tlBaseVersion := "0.65"
ThisBuild / tlCiReleaseBranches := Seq("main")
ThisBuild / crossScalaVersions := Seq("3.3.1")
ThisBuild / tlVersionIntroduced := Map("3" -> "0.29.0")
Expand Down
61 changes: 32 additions & 29 deletions lucuma-schemas/src/clue/scala/lucuma/schemas/ObservationDB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,41 @@ import lucuma.core.math.BrightnessUnits._
trait ObservationDB {
object Scalars {
// Ids
type AtomId = Atom.Id
type ExecutionEventId = ExecutionEvent.Id
type GroupId = Group.Id
type ObsAttachmentId = ObsAttachment.Id
type ObservationId = Observation.Id
type ProgramId = Program.Id
type StepId = Step.Id
type DatasetId = Dataset.Id
type TargetId = Target.Id
type UserId = User.Id
type VisitId = Visit.Id
type AtomId = Atom.Id
type ExecutionEventId = ExecutionEvent.Id
type GroupId = Group.Id
type ObsAttachmentId = ObsAttachment.Id
type ObservationId = Observation.Id
type ProgramId = Program.Id
type StepId = Step.Id
type DatasetId = Dataset.Id
type TargetId = Target.Id
type UserId = User.Id
type VisitId = Visit.Id
// Basic types
type BigDecimal = scala.BigDecimal
type Long = scala.Long
type BigDecimal = scala.BigDecimal
type Long = scala.Long
// Formatted strings
type DatasetFilename = String
type DmsString = String
type EpochString = String
type HmsString = String
type DatasetFilename = String
type DmsString = String
type EpochString = String
type HmsString = String
// Refined
type Extinction = NonNegBigDecimal // """Non-negative floating-point value."""
type NonEmptyString = eu.timepit.refined.types.string.NonEmptyString
type NonNegBigDecimal = eu.timepit.refined.types.numeric.NonNegBigDecimal
type NonNegInt = eu.timepit.refined.types.numeric.NonNegInt
type NonNegLong = eu.timepit.refined.types.numeric.NonNegLong
type NonNegShort = eu.timepit.refined.types.numeric.NonNegShort
type PosBigDecimal = eu.timepit.refined.types.numeric.PosBigDecimal
type PosInt = eu.timepit.refined.types.numeric.PosInt
type PosLong = eu.timepit.refined.types.numeric.PosLong
type PosShort = eu.timepit.refined.types.numeric.PosShort
type Extinction = NonNegBigDecimal // """Non-negative floating-point value."""
type NonEmptyString = eu.timepit.refined.types.string.NonEmptyString
type NonNegBigDecimal = eu.timepit.refined.types.numeric.NonNegBigDecimal
type NonNegInt = eu.timepit.refined.types.numeric.NonNegInt
type NonNegLong = eu.timepit.refined.types.numeric.NonNegLong
type NonNegShort = eu.timepit.refined.types.numeric.NonNegShort
type PosBigDecimal = eu.timepit.refined.types.numeric.PosBigDecimal
type PosInt = eu.timepit.refined.types.numeric.PosInt
type PosLong = eu.timepit.refined.types.numeric.PosLong
type PosShort = eu.timepit.refined.types.numeric.PosShort
// Core Types
type SignalToNoise = lucuma.core.math.SignalToNoise
type Timestamp = lucuma.core.util.Timestamp
type SignalToNoise = lucuma.core.math.SignalToNoise
type Timestamp = lucuma.core.util.Timestamp
// Enum Meta
type ObsAttachmentTypeMeta = lucuma.schemas.enums.ObsAttachmentType
}

object Enums {
Expand Down Expand Up @@ -105,6 +107,7 @@ trait ObservationDB {
type LineFluxSurfaceUnits = Units Of LineFlux[Surface]
type MosPreImaging = enums.MosPreImaging
type ObsActiveStatus = enums.ObsActiveStatus
type ObsAttachmentType = lucuma.schemas.enums.ObsAttachmentType
type ObsStatus = enums.ObsStatus
type ObserveClass = enums.ObserveClass
type Partner = model.Partner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ query {
utc
}
... on TimingWindowEndAfter {
duration {
after {
milliseconds
}
repeat {
Expand Down
12 changes: 12 additions & 0 deletions model/.js/src/main/scala/lucuma/schemas/enums/Globals.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// 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.schemas.enums

import scala.scalajs.js
import scala.scalajs.js.annotation.JSGlobalScope

@js.native
@JSGlobalScope
private object Globals extends js.Object:
val enumMetadataString: String = js.native // Define in main.jsx
7 changes: 7 additions & 0 deletions model/.jvm/src/main/scala/lucuma/schemas/enums/Globals.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// 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.schemas.enums

private object Globals:
val enumMetadataString: String = ???
13 changes: 13 additions & 0 deletions model/src/main/scala/lucuma/schemas/enums/DynamicEnums.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// 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.schemas.enums

import io.circe.*
import io.circe.parser.*

object DynamicEnums:
val parsedEnums: ACursor =
parse(Globals.enumMetadataString) match
case Left(err) => err.printStackTrace; throw err
case Right(json) => json.hcursor
56 changes: 56 additions & 0 deletions model/src/main/scala/lucuma/schemas/enums/ObsAttachmentType.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// 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.schemas.enums

import cats.Eq
import cats.derived.*
import io.circe.*
import io.circe.generic.semiauto
import io.circe.generic.semiauto.*
import lucuma.core.util.Display
import lucuma.core.util.Enumerated
import lucuma.core.util.NewType
import monocle.Focus
import monocle.Lens

object FileExtension extends NewType[String]
type FileExtension = FileExtension.Type

case class ObsAttachmentType(
tag: String,
shortName: String,
longName: String,
fileExtensions: List[FileExtension]
) derives Eq:
def accept: String = fileExtensions.map("." + _.value).mkString(",")

object ObsAttachmentType:
given Display[ObsAttachmentType] = Display.by(_.shortName, _.longName)

val tag: Lens[ObsAttachmentType, String] = Focus[ObsAttachmentType](_.tag)
val shortName: Lens[ObsAttachmentType, String] = Focus[ObsAttachmentType](_.shortName)
val longName: Lens[ObsAttachmentType, String] = Focus[ObsAttachmentType](_.longName)
val fileExtensions: Lens[ObsAttachmentType, List[FileExtension]] =
Focus[ObsAttachmentType](_.fileExtensions)

def Finder(using e: Enumerated[ObsAttachmentType]): ObsAttachmentType = e.unsafeFromTag("FINDER")

val values: List[ObsAttachmentType] =
given Decoder[FileExtension] = Decoder.instance: c =>
c.downField("fileExtension").as[String].map(FileExtension(_))
// This is a meta decoder, not a decoder for enum instances (which comes from the `Enumerated` instance)
given Decoder[ObsAttachmentType] = semiauto.deriveDecoder

DynamicEnums.parsedEnums.downField("obsAttachmentTypeMeta").as[List[ObsAttachmentType]] match
case Left(err) => err.printStackTrace; throw err
case Right(json) => json

// The givens are apparently (probably) constructed lazily.
// See https://alexn.org/blog/2022/05/11/implicit-vs-scala-3-given/
// We want to fail immediately if there is a problem, so we'll reference
// the enumerated givens here.
Enumerated[ObsAttachmentType]

given Enumerated[ObsAttachmentType] =
Enumerated.from(values.head, values.tail: _*).withTag(_.tag)

0 comments on commit 6390b3c

Please sign in to comment.