Skip to content

bishabosha/enum-extensions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Enum Extensions

CI status javadoc

The Enum Extensions library provides type classes to work generically with enumerations in Scala 3

Usage

Type classes are provided in the enumextensions package.

Enum Mirror

EnumMirror[E] is a type class that provides reflection over an enumeration type E. It provides several capabilities:

  • cached values as an IArray[E]
  • reflection of name (String) or ordinal (Int) for any individual case.
  • safe lookup individual cases by name or ordinal,
  • unsafe (efficient) lookup of individual cases by name or ordinal.

See the above use cases in action below:

import enumextensions.EnumMirror

def enumName[E: EnumMirror]: String =
  EnumMirror[E].mirroredName // e.g. example.Color

def sortedCases[E: EnumMirror]: IArray[E] =
  EnumMirror[E].values // cached IArray

def nameOrdinalPairs[E: EnumMirror]: Map[String, Int] =
  Map.from( //                      ┌ NAME    ┌ ORDINAL
    for e <- sortedCases[E] yield e.name -> e.ordinal
  )

// Lookups returning `Option[E]`
def safeLookup[E: EnumMirror](name: String): Option[E] =
  EnumMirror[E].valueOf(name)
def safeLookup[E: EnumMirror](ordinal: Int): Option[E] =
  EnumMirror[E].fromOrdinal(ordinal)

// assert that name/ordinal exists for convenience
def unsafeLookup[E: EnumMirror](name: String): E =
  EnumMirror[E].valueOfUnsafe(name)
def unsafeLookup[E: EnumMirror](ordinal: Int): E =
  EnumMirror[E].fromOrdinalUnsafe(ordinal)

given instances of EnumMirror are not provided automatically, you must explicitly opt in as follows:

enum Color derives EnumMirror:
  case Red, Green, Blue

Numeric

In the enumextensions.numeric package we provide NumericOps, which extends types with a given EnumMirror[E] into a given scala.math.Integral[E], as well as providing standard numeric operations over the enum, it is simple to create sub-ranges of values.

Let's define a WeekDays enumeration, opting into numeric derivation by derives NumericOps, and declare ranges for both the daysOfWeek and weekend:

import enumextensions.EnumMirror
import enumextensions.numeric.NumericOps

enum WeekDays derives EnumMirror, NumericOps:
  case Monday, Tuesday, Wednesday, Thursday, Friday
  case Saturday, Sunday

object WeekDays:
  val daysOfWeek = Monday to Friday
  val weekend    = Saturday to Sunday

here is a demonstration of using the numeric operators, e.g.

scala> -(-Wednesday) == Wednesday
true

About

Generic Framework over Scala 3 enumerations

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages