Annotations to use on case classes that are being processed by macros
Methods with 'Opts' postfix will take additional options in the form of type parameters that will customize behavior of the macros during compilation.
Creates an instance of BSONReader and BSONWriter for case class A
Creates an instance of BSONReader and BSONWriter for case class A and takes additional options
Creates an instance of BSONReader for case class A
Creates an instance of BSONReader for case class A
Macros
Creates an instance of BSONReader for case class A and takes additional options
Creates an instance of BSONWriter for case class A
Creates an instance of BSONWriter for case class A and takes additional options
Macros for generating
BSONReader
andBSONWriter
implementations for case at compile time. Invoking these macros is equivalent to writing anonymous class implementations by hand.Example
Use
reader
to generate theBSONReader
andwriter
forBSONWriter
orhandler
for a class that extends both. Respective methods with 'Opts' appended take additional options in form of type parameters.The
A
type parameter defines case class that will be the basis for auto-generated implementation. Some other types with matching apply-unapply might work but behaviour is undefined. Since macros will match the apply-unapply pair you are free to overload these methods in the companion object.Fields in the case class get mapped into BSON properties with respective names and BSON handlers are pulled from implicit scope to (de)serialize them. In order to use custom types inside case classes just make sure appropriate handlers are in scope. Note that companion objects are searched too. For example if you have
case class Foo(bar: Bar)
and want to create a handler for it is enough to put an implicit handler forBar
in it's companion object. That handler might be macro generated or written by hand.Case classes can also be defined inside other classes, objects or traits but not inside functions(known limitation). In order to work you should have the case class in scope(where you call the macro) so you can refer to it by it's short name - without package. This is necessary because the generated implementations refer to it by the short name to support nested declarations. You can work around this with local imports.
Example
Option types are handled somewhat specially: a field of type Option[T] will only be appended to the document if it contains a value. Similarly if a document does not contain a value it will be read as None.
Also supported neat trick are 'union types' that make for easy work with algebraic data types. See the UnionType option for more details.
You can also create recursive structures by explicitly annotating types of the implicit handlers. (To let the compiler know they exist) Example
Macros.Options for specific options