All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gem.util.Enumerated.scala Maven / Gradle / Ivy

The newest version!
// Copyright (c) 2016-2020 Association of Universities for Research in Astronomy, Inc. (AURA)
// For license information see LICENSE or https://opensource.org/licenses/BSD-3-Clause

package gem.util

import cats.Order
import cats.implicits._

/**
 * Typeclass for an enumerated type with unique string tags and a canonical ordering.
 * @group Typeclasses
 */
trait Enumerated[A] extends Order[A] {

  /** All members of this enumeration, in unspecified but canonical order. */
  def all: List[A]

  /** The tag for a given value. */
  def tag(a: A): String

  /** Select the member of this enumeration with the given tag, if any. */
  def fromTag(s: String): Option[A] = all.find(tag(_) === s)

  /** Select the member of this enumeration with the given tag, throwing if absent. */
  def unsafeFromTag(tag: String): A = fromTag(tag).getOrElse(sys.error("Invalid tag: " + tag))

  def compare(a: A, b: A): Int =
    Order[Int].compare(indexOfTag(tag(a)), indexOfTag(tag(b)))

  // Hashed index lookup, for efficient use as an `Order`.
  private lazy val indexOfTag: Map[String, Int] =
    all.zipWithIndex.iterator.map { case (a, n) => (tag(a), n) }.toMap

}

object Enumerated {
  def apply[A](implicit ev: Enumerated[A]): ev.type = ev

  def of[A <: Product](a: A, as: A*): Enumerated[A] =
    new Enumerated[A] {
      def all: List[A] = a :: as.toList
      def tag(a: A): String = a.productPrefix
    }

}

/** @group Typeclasses */
trait Obsoletable[A] {
  def isActive(a: A): Boolean
  final def isObsolete(a: A): Boolean = !isActive(a)
}


/**
 * Typeclass for things that can be shown in a user interface.
 * @group Typeclasses
 */
trait Display[A] {
  def name(a:A): String         // short name, for labels
  def elaboration(a:A): Option[String]  // an elaboration on the name, used for computing longname
  def longName(a: A): String = name(a) + elaboration(a).fold("")(n => s" ($n)")
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy