Skip to content
This repository has been archived by the owner on May 10, 2019. It is now read-only.
/ field-names Public archive

Scala annotation `@FieldNames` that provides case class field names as string constants.

License

Notifications You must be signed in to change notification settings

lorandszakacs/field-names

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

field-names: simple macro annotation

Build Status

field-names is a simple scala library—built on top of scala-meta—that provides a simple type annotation called @FieldNames which makes the field names of a case class available as runtime String values.

Quickstart:

TODO: publishLocal

Unfortunately, you will have to publish the library locally, simply clone this repository, and run sbt + publishLocal locally, to make the library available to your local sbt build. This will be fixed as soon as I figure out how to create an account on one of those central repositories 😩

sbt

Add the following to your sbt build:

libraryDependencies += "com.lorandszakacs" %% "field-names" % "0.1.0"

Unfortunately you need to also add a dependency both on scala-meta, and on the macro paradise compiler-plugin. Include the following settings into your build (N.B. that bellow the settings are only defined, and not used):

lazy val macroAnnotationSettings = Seq(
  libraryDependencies += "org.scalameta" %% "scalameta" % "1.8.0" % Provided,
  addCompilerPlugin("org.scalameta" % "paradise" % "3.0.0-M9" cross CrossVersion.full),
  scalacOptions += "-Xplugin-require:macroparadise",
  scalacOptions in(Compile, console) ~= (_ filterNot (_ contains "paradise")) // macroparadise plugin doesn't work in repl yet.
)

Example of fully working sbt build:

lazy val root = (project in file(".")).
  settings(
    scalaVersion := "2.12.2", // or "2.11.11"
    libraryDependencies += "com.lorandszakacs" %% "field-names" % "0.1.0"
  ).
  settings(macroAnnotationSettings)


lazy val macroAnnotationSettings = Seq(
  libraryDependencies += "org.scalameta" %% "scalameta" % "1.8.0" % Provided,
  addCompilerPlugin("org.scalameta" % "paradise" % "3.0.0-M9" cross CrossVersion.full),
  scalacOptions += "-Xplugin-require:macroparadise",
  scalacOptions in(Compile, console) ~= (_ filterNot (_ contains "paradise")) // macroparadise plugin doesn't work in repl yet.
)

Supported Scala versions

This library is currently being built against Scala versions 2.12.2 and 2.11.11

Example:

import fieldnames.FieldNames

@FieldNames
case class User(
  id: Long,
  name: String,
  email: String,
  username: String
)

object Test extends App {
  if (User.fields.id == "id")
    println(s"yay! we have an ${User.fields.id} field")

  if (User.fields.name == "name")
    println(s"yay! we have an ${User.fields.name} field")

  if (User.fields.email == "email")
    println(s"yay! we have an ${User.fields.id} field")

  if (User.fields.username == "username")
    println(s"yay! we have an ${User.fields.id} field")
}

Essentially, it is roughly equivalent to writing something like:

object User {

  object fields {
    val id: String = "id"
    val name: String = "name"
    val email: String = "email"
    val username: String = "username"
  }

}

The macro ensures that if a companion object is explicitly defined, then all pre-existing definitions will be preserved.

Check out the test to see various scenarios: src/test/scala/fieldnames/FieldNamesTest.scala

About

Scala annotation `@FieldNames` that provides case class field names as string constants.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages