Skip to content

Instantly share code, notes, and snippets.

@Jacoby6000
Created March 11, 2015 22:44
Show Gist options
  • Save Jacoby6000/26714382a89723a7a681 to your computer and use it in GitHub Desktop.
Save Jacoby6000/26714382a89723a7a681 to your computer and use it in GitHub Desktop.
def jsonReader(className: TypeName, fields: List[ValDef]) = {
fields.length match {
case 0 => c.abort(c.enclosingPosition, "Cannot create json formatter for case class with no fields")
case _ =>
// use the serializer for the field
val readers = getReaders(fields)
q"""
implicit object reader extends BSONDocumentReader[$className] {
import reactivemongo.bson._
def read(bson: BSONDocument): $className = {
${className.toTermName}(..$readers)
}
}
"""
}
}
def jsonWriter(className: TypeName, fields: List[ValDef]) = {
fields.length match {
case 0 => c.abort(c.enclosingPosition, "Cannot create json formatter for case class with no fields")
case _ =>
// use the serializer for the field
val writers = getWriters(fields)
q"""
implicit object writer extends BSONDocumentWriter[$className] {
def write(obj: $className): BSONDocument = {
BSONDocument(..$writers)
}
}
"""
}
def modifiedDeclaration(classDecl: ClassDef, compDeclOpt: Option[ModuleDef] = None) = {
val (className, fields) = extractClassNameAndFields(classDecl)
val readerFormat = jsonReader(className, fields)
val writerFormat = jsonWriter(className, fields)
val readerCompDecl = modifiedCompanion(compDeclOpt, readerFormat, className)
val writerCompDecl = modifiedCompanion(compDeclOpt, writerFormat, className)
// Return both the class and companion object declarations
c.Expr(q"""
$classDecl
$readerCompDecl
$writerCompDecl
""")
}
def modifiedCompanion(compDeclOpt: Option[ModuleDef], format: ModuleDef, className: TypeName) = {
compDeclOpt map { compDecl =>
// Add the formatter to the existing companion object
val q"object $obj extends ..$bases { ..$body }" = compDecl
q"""
object $obj extends ..$bases {
..$body
$format
}
"""
} getOrElse {
// Create a companion object with the formatter
q"object ${className.toTermName} { $format }"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment