diff --git a/build.sbt b/build.sbt index 3c4cb5c..77da212 100644 --- a/build.sbt +++ b/build.sbt @@ -152,6 +152,10 @@ lazy val `codec-protobuf-js` = `codec-protobuf`.js lazy val `codec-examples` = project .in(file("examples")) .settings( - commons + commons, + libraryDependencies ++= Seq( + "io.monix" %%% "monix" % "3.0.0-RC1" + ) ) .dependsOn(`codec-core-jvm`) + .dependsOn(`codec-kryo`) diff --git a/examples/src/main/scala/fluence/codec/examples/KryoCodecExample.scala b/examples/src/main/scala/fluence/codec/examples/KryoCodecExample.scala new file mode 100644 index 0000000..662c670 --- /dev/null +++ b/examples/src/main/scala/fluence/codec/examples/KryoCodecExample.scala @@ -0,0 +1,65 @@ +package fluence.codec.examples + +import cats.Id +import fluence.codec.kryo.KryoCodecs +import fluence.codec.{CodecError, PureCodec} +import monix.eval.Task +import shapeless.{::, HNil} + +object KryoCodecExample { + case class Aircraft(manufacturer: String, model: String, tailNumber: String) + case class Fuel(amount: Double) extends AnyVal + + case class UnknownClass(x: String) + + def main(args: Array[String]): Unit = { + // This way we can define a typed collection of codecs using kryo for the underlying serialization. + // + // These codecs can be used only to transform the corresponding type: i.e. it won't be possible to + // use an aircraft codec to serialize fuel (which is essentially a typed wrapper over double value). + // + // It won't be possible to obtain from this collection a codec for previously not registered class. + // Type safety FTW! + // + // Note that different methods are used to register Aircraft and Fuel – that's because one is a reference, + // and another is a value type. + val codecs: KryoCodecs[Task, ::[Fuel, ::[Aircraft, ::[Array[Byte], ::[Long, ::[String, HNil]]]]]] = KryoCodecs() + .addCase(classOf[Aircraft]) + .add[Fuel] + .build[Task]() + + val skyhawk61942 = Aircraft("Cessna", "172S G1000", "N61942") + val tabsFuel = Fuel(53) + + val aircraftCodec: PureCodec[Aircraft, Array[Byte]] = codecs.pureCodec[Aircraft] + val fuelCodec: PureCodec[Fuel, Array[Byte]] = codecs.pureCodec[Fuel] + + // This will cause a compilation error, because the class was never registered with the codecs. + // "You requested an element of type (...).UnknownClass, but there is none in the HList" + // + // val unknownCodec = codecs.pureCodec[UnknownClass] + + + // Here all the standard machinery of codecs applies (for more examples, consider checking out PureCodecExample. + // We can serialize and deserialize the object – and unsurprisingly the original and restored values match. + // + // Let's serialize an aircraft instance. + { + val ser: Id[Either[CodecError, Array[Byte]]] = aircraftCodec.direct[Id](skyhawk61942).value + val deser: Id[Either[CodecError, Aircraft]] = aircraftCodec.inverse[Id](ser.right.get).value + + println(ser.right.map(x => s"$skyhawk61942 => serialized size: ${x.length}")) + assert(deser == Right(skyhawk61942)) + } + + + // Same thing for the fuel instance (which is AnyVal fwiw). + { + val ser: Id[Either[CodecError, Array[Byte]]] = fuelCodec.direct[Id](tabsFuel).value + val deser: Id[Either[CodecError, Fuel]] = fuelCodec.inverse[Id](ser.right.get).value + + println(ser.right.map(x => s"$tabsFuel => serialized size: ${x.length}")) + assert(deser == Right(tabsFuel)) + } + } +} diff --git a/kryo/src/main/scala/fluence/codec/kryo/KryoFactory.scala b/kryo/src/main/scala/fluence/codec/kryo/KryoFactory.scala index 74e92ed..d17c2d8 100644 --- a/kryo/src/main/scala/fluence/codec/kryo/KryoFactory.scala +++ b/kryo/src/main/scala/fluence/codec/kryo/KryoFactory.scala @@ -21,8 +21,8 @@ import com.twitter.chill.{AllScalaRegistrar, KryoBase, KryoInstantiator} import org.objenesis.strategy.StdInstantiatorStrategy /** - * This Instantiator enable compulsory class registration, registers all java and scala main classes. - * This class required for [[com.twitter.chill.KryoPool]]. + * This Instantiator enables compulsory class registration and registers all java and scala main classes. + * This class is required for [[com.twitter.chill.KryoPool]]. * @param classesToReg additional classes for registration * @param registrationRequired if true, an exception is thrown when an unregistered class is encountered. */