Adversaria
Adversaria is a tiny library which provides a few tools to make it easier to work with static annotations in Scala, by making them available through typeclass interfaces.
Features
- access all annotations on a type through a typeclass
- resolve a typeclass instance only if a type has an annotated field
- makes annotations more useful and accessible in Scala
- no macro code is required to use annotations
Getting Started
The nature of annotations in Scala is that they are very rarely the best solution for any task. The can, however, be convenient in certain circumstances, and this small domain is where Adversaria aims to help.
Currently three use cases are supported:
- getting all the annotations applied to a particular type
- finding the parameter of a case class to which a particular annotation has been applied
- getting all the annotations applied to a particular case class field
The list of supported use cases may grow as additional suggestions are received.
Examples
If we were to define the following annotations,
import scala.annotation.StaticAnnotation
final case class id() extends StaticAnnotation
final case class count(n: Int) extends StaticAnnotation
we could apply them to some case classes, such as,
@count(10)
case class Company(name: String)
case class Person(name: String, @id email: String)
Perhaps we would like to find out the annotations on Company
. We can get this information by requesting an implicit TypeMetadata[Company]
value, and accessing its annotations
field, like so,
import adversaria._
val info = implicitly[TypeMetadata[Company]]
println(info.annotations)
> List(count(10))
The TypeMetadata
implicit should resolve for any type, regardless of whether it has any annotations or not. Its annotations
method will return a list of annotations on that case class.
Another supported use case is to find the field of a case class which has been annotated with a particular annotation, if and only if that annotation exists. We use the FindMetadata
typeclass for this. It takes two type parameters: the type of the annotation, and the type to check for, respectively,
import adversaria._
val idField = implicitly[FindMetadata[id, Person]]
println(idField.get(Person("John Smith", "[email protected])))
> [email protected]
However, attempting to resolve such an implicit on a case class which has no field annotated with that annotation, for example,
val idField = implicitly[FindMetadata[id, Company]]
will fail with at compiletime with the message,
adversaria: could not find a parameter annotated with type @id
Status
Adversaria is classified as fledgling. Propensive defines the following five stability levels for open-source projects:
- embryonic: for experimental or demonstrative purposes only, without guarantee of longevity
- fledgling: of proven utility, seeking contributions, but liable to significant redesigns
- maturescent: major design decisions broady settled, seeking probatory adoption and refinement of designs
- dependable: production-ready, subject to controlled ongoing maintenance and enhancement; tagged as version
1.0
or later - adamantine: proven, reliable and production-ready, with no further breaking changes ever anticipated
Availability
Adversaria’s source is available on GitHub, and may be built with Fury by cloning the layer propensive/adversaria
.
fury layer clone -i propensive/adversaria
or imported into an existing layer with,
fury layer import -i propensive/adversaria
A binary is available on Maven Central as com.propensive:adversaria-core_<scala-version>:0.18.0
. This may be added to an sbt build with:
libraryDependencies += "com.propensive" %% "adversaria-core" % "0.18.0"
Contributing
Contributors to Adversaria are welcome and encouraged. New contributors may like to look for issues marked .
We suggest that all contributors read the Contributing Guide to make the process of contributing to Adversaria easier.
Please do not contact project maintainers privately with questions, as other users cannot then benefit from the answers.
Author
Adversaria was designed and developed by Jon Pretty, and commercial support and training is available from Propensive OÜ.
License
Adversaria is copyright © 2017-20 Jon Pretty & Propensive OÜ, and is made available under the Apache 2.0 License.