Airframe Surface: An Object Shape Inspector

Gitter Chat Build Status Latest version Scala.js Scaladoc

Airframe Surface is an object surface inspection library, which is compatible between Scala and Scala.js

Overview

Surface provides functionalities to read the surface of an object, which includes:

  • Object parameter names and its types.
  • Object methods defined in an object with method argument names and types.

Surface is useful for:

  • Writing object serializer / deserializer without using any boilerplates.
  • Automatically generating code based on class parameters, method definitions, etc.
  • Dependency injection based on object shapes (e.g., Airframe)

Usage

Maven Central

build.sbt

libraryDependencies += "org.wvlet.airframe" %% "airframe-surface" % "(version)"

// For Scala.js
libraryDependencies += "org.wvlet.airframe" %%% "airframe-surface" % "(version)"

Surface.of[X]

import wvlet.airframe.surface.Surface

case class A(id:Int, name:String)

val s = Surface.of[A]
println(s.toString) // This will show A(id:Int, name:String)

// Find object parameters
s.params.mkString(", ") // Returns "id:Int, name:String"

// Object factory
s.objectFactory.map{ f =>
  f.newInstance(Seq(1, "leo"))
}
// Some(A(1, "leo"))

Type alias


type UserName = String

Surface.of[UserName] //  Returns UserName:=String

Tagged Type

To have different surfaces for the same type, you can use tagged type (@@):

import wvlet.airframe.surface.Surface
import wvlet.airframe.surface.tag._

class Fruit
trait Apple
trait Banana

Surface.of[Fruit @@ Apple]
Surface.of[Fruit @@ Banana]

Runtime Annotation

Reading runtime-annotation is supported for JVM projects. Import wvlet.airframe.surface.reflect._ to use this feature.

import wvlet.airframe.surface.Surface
import wvlet.airframe.surface.reflect._
import javax.annotation.Resource
 
@Resource(name="my resource")
class A(@Resource(name = "param 1") a:String)

val s = Surface.of[A]
// Reading class annotation
val a = s.findAnnotationOf[Resource]
a.get.name // "my resource"

// Reading parameter annotation
val r = s.params.find(_.name == "a").findAnnotationOf[Resource]
r.get.name // "param 1"