Skip to content
This repository has been archived by the owner on Jul 25, 2023. It is now read-only.

Commit

Permalink
Split incremental/custom encoder/decoder from Decoder/Encoder
Browse files Browse the repository at this point in the history
This in order to obtain the expected behavior of:
```
import io.protoless.generic.semiauto._
```
  • Loading branch information
rootmos committed May 19, 2018
1 parent a63c5df commit 1cdeed9
Show file tree
Hide file tree
Showing 13 changed files with 176 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import io.protoless.messages.Decoder
*/
@implicitNotFound("No CustomMappingDecoder found for type ${A} and ${L}.")
@annotation.inductive
trait CustomMappingDecoder[A, L <: HList] extends Decoder[A]
class CustomMappingDecoder[A, L <: HList](val underlying: Decoder[A])

/**
* Utilities for [[CustomMappingDecoder]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import io.protoless.messages.Decoder
*/
@implicitNotFound("No IncrementalDecoder found for type ${A} and ${N}.")
@annotation.inductive
trait IncrementalDecoder[A, N <: Nat] extends Decoder[A]
class IncrementalDecoder[A, N <: Nat](val underlying: Decoder[A])

/**
* Utilities for [[IncrementalDecoder]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.protoless.messages.Encoder

@implicitNotFound("No CustomMappingEncoder found for type ${A} and ${L}.")
@annotation.inductive
trait CustomMappingEncoder[A, L <: HList] extends Encoder[A]
class CustomMappingEncoder[A, L <: HList](val underlying: Encoder[A])

/**
* Utilities for [[CustomMappingEncoder]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.protoless.messages.Encoder

@implicitNotFound("No IncrementalEncoder found for type ${A} and ${N}.")
@annotation.inductive
trait IncrementalEncoder[A, N <: Nat] extends Encoder[A]
class IncrementalEncoder[A, N <: Nat](val underlying: Encoder[A])

/**
* Utilities for [[IncrementalEncoder]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import io.protoless.messages.Decoder.Result
import io.protoless.messages.decoders.{AutoDecoder, IncrementalDecoder}
import io.protoless.messages.encoders.{AutoEncoder, IncrementalEncoder}

trait AutoEncoderDecoderInstances extends IncrementalEncoderDecoderInstances {
trait AutoEncoderDecoderInstances {

implicit def decodeAuto[A, R <: HList](implicit
gen: Generic.Aux[A, R],
decoder: IncrementalDecoder[R, Nat._1]
): AutoDecoder[A] = new AutoDecoder[A] {
override def decode(input: CodedInputStream): Result[A] = {
decoder.decode(input) match {
decoder.underlying.decode(input) match {
case Right(repr) => Right(gen.from(repr))
case l @ Left(_) => l.asInstanceOf[Result[A]]
}
Expand All @@ -26,7 +26,7 @@ trait AutoEncoderDecoderInstances extends IncrementalEncoderDecoderInstances {
encoder: IncrementalEncoder[R, Nat._1]
): AutoEncoder[A] = new AutoEncoder[A] {
override def encode(a: A, output: CodedOutputStream): Unit = {
encoder.encode(gen.to(a), output)
encoder.underlying.encode(gen.to(a), output)
output.flush()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,95 +5,119 @@ import com.google.protobuf.{CodedInputStream, CodedOutputStream}
import shapeless.{::, Generic, HList, HNil, Nat}
import shapeless.ops.nat.ToInt

import io.protoless.messages.{Decoder, Encoder}
import io.protoless.messages.decoders.CustomMappingDecoder
import io.protoless.messages.encoders.CustomMappingEncoder
import io.protoless.fields.{FieldEncoder, FieldDecoder}
import io.protoless.messages.Decoder.Result

trait CustomMappingEncoderDecoderInstances extends IncrementalDecoderInstances {
trait CustomMappingEncoderDecoderInstances {

implicit val decodeCustomMappingHNil: CustomMappingDecoder[HNil, HNil] = new CustomMappingDecoder[HNil, HNil] {
override def decode(input: CodedInputStream): Result[HNil] = Right(HNil)
}
implicit val decodeCustomMappingHNil: CustomMappingDecoder[HNil, HNil] =
new CustomMappingDecoder[HNil, HNil](
new Decoder[HNil] {
override def decode(input: CodedInputStream): Result[HNil] = Right(HNil)
}
)

// Decode mapping specified with Nat (Nat._1 :: Nat._3 :: HNil)
implicit def decodeCustomMappingHList[H, T <: HList, L <: Nat, TN <: HList](implicit
hDecoder: FieldDecoder[H],
index: ToInt[L],
tDecoder: CustomMappingDecoder[T, TN]
): CustomMappingDecoder[H :: T, L :: TN] = new CustomMappingDecoder[H :: T, L :: TN] {
override def decode(input: CodedInputStream): Result[H :: T] = {
for {
h <- hDecoder.read(input, index()).right
t <- tDecoder.decode(input).right
} yield h :: t
}
}
): CustomMappingDecoder[H :: T, L :: TN] =
new CustomMappingDecoder[H :: T, L :: TN](
new Decoder[H :: T] {
override def decode(input: CodedInputStream): Result[H :: T] = {
for {
h <- hDecoder.read(input, index()).right
t <- tDecoder.underlying.decode(input).right
} yield h :: t
}
}
)

// Decode mapping specified with Literal types (-Yliteral-types) (1 :: 3 :: HNil)
implicit def decodeCustomMappingHListLiteral[H, T <: HList, L <: Int, TN <: HList](implicit
hDecoder: FieldDecoder[H],
index: ValueOf[L],
tDecoder: CustomMappingDecoder[T, TN]
): CustomMappingDecoder[H :: T, L :: TN] = new CustomMappingDecoder[H :: T, L :: TN] {
override def decode(input: CodedInputStream): Result[H :: T] = {
for {
h <- hDecoder.read(input, valueOf[L]).right
t <- tDecoder.decode(input).right
} yield h :: t
}
}
): CustomMappingDecoder[H :: T, L :: TN] =
new CustomMappingDecoder[H :: T, L :: TN](
new Decoder[H :: T] {
override def decode(input: CodedInputStream): Result[H :: T] = {
for {
h <- hDecoder.read(input, valueOf[L]).right
t <- tDecoder.underlying.decode(input).right
} yield h :: t
}
}
)

implicit def decodeCustomMapping[A, L <: HList, R <: HList](implicit
gen: Generic.Aux[A, R],
decoder: CustomMappingDecoder[R, L]
): CustomMappingDecoder[A, L] = new CustomMappingDecoder[A, L] {
override def decode(input: CodedInputStream): Result[A] = {
decoder.decode(input) match {
case Right(repr) => Right(gen.from(repr))
case l @ Left(_) => l.asInstanceOf[Result[A]]
): CustomMappingDecoder[A, L] = new CustomMappingDecoder[A, L](
new Decoder[A] {
override def decode(input: CodedInputStream): Result[A] = {
decoder.underlying.decode(input) match {
case Right(repr) => Right(gen.from(repr))
case l @ Left(_) => l.asInstanceOf[Result[A]]
}
}
}
}
)

implicit val encodeCustomMappingHNil: CustomMappingEncoder[HNil, HNil] = new CustomMappingEncoder[HNil, HNil] {
override def encode(a: HNil, output: CodedOutputStream): Unit = {}
}
implicit val encodeCustomMappingHNil: CustomMappingEncoder[HNil, HNil] =
new CustomMappingEncoder[HNil, HNil](
new Encoder[HNil] {
override def encode(a: HNil, output: CodedOutputStream): Unit = {}
}
)

// Encode mapping specified with Nat (Nat._1 :: Nat._3 :: HNil)
implicit def encodeCustomMappingHList[H, T <: HList, L <: Nat, TN <: HList](implicit
hEncoder: FieldEncoder[H],
index: ToInt[L],
tEncoder: CustomMappingEncoder[T, TN]
): CustomMappingEncoder[H :: T, L :: TN] = new CustomMappingEncoder[H :: T, L :: TN] {
override def encode(a: H :: T, output: CodedOutputStream): Unit = {
val (h :: t) = a
hEncoder.write(index(), h, output)
tEncoder.encode(t, output)
}
}
): CustomMappingEncoder[H :: T, L :: TN] =
new CustomMappingEncoder[H :: T, L :: TN](
new Encoder[H :: T] {
override def encode(a: H :: T, output: CodedOutputStream): Unit = {
val (h :: t) = a
hEncoder.write(index(), h, output)
tEncoder.underlying.encode(t, output)
}
}
)

// Encode mapping specified with Literal (1 :: 3 :: HNil)
implicit def encodeCustomMappingHListLiteral[H, T <: HList, L <: Int, TN <: HList](implicit
hEncoder: FieldEncoder[H],
index: ValueOf[L],
tEncoder: CustomMappingEncoder[T, TN]
): CustomMappingEncoder[H :: T, L :: TN] = new CustomMappingEncoder[H :: T, L :: TN] {
override def encode(a: H :: T, output: CodedOutputStream): Unit = {
val (h :: t) = a
hEncoder.write(valueOf[L], h, output)
tEncoder.encode(t, output)
}
}
): CustomMappingEncoder[H :: T, L :: TN] =
new CustomMappingEncoder[H :: T, L :: TN](
new Encoder[H :: T] {
override def encode(a: H :: T, output: CodedOutputStream): Unit = {
val (h :: t) = a
hEncoder.write(valueOf[L], h, output)
tEncoder.underlying.encode(t, output)
}
}
)

implicit def encodeCustomMapping[A, L <: HList, R <: HList](implicit
gen: Generic.Aux[A, R],
encoder: CustomMappingEncoder[R, L]
): CustomMappingEncoder[A, L] = new CustomMappingEncoder[A, L] {
override def encode(a: A, output: CodedOutputStream): Unit = {
encoder.encode(gen.to(a), output)
output.flush()
}
}
): CustomMappingEncoder[A, L] =
new CustomMappingEncoder[A, L](
new Encoder[A] {
override def encode(a: A, output: CodedOutputStream): Unit = {
encoder.underlying.encode(gen.to(a), output)
output.flush()
}
}
)

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package io.protoless.generic

import com.google.protobuf.CodedOutputStream
import com.google.protobuf.CodedInputStream
import shapeless.{::, Generic, HList, HNil, Nat, Succ}
import shapeless.ops.nat.ToInt

import io.protoless.messages.{Decoder, Encoder}
import io.protoless.messages.encoders.IncrementalEncoder
import io.protoless.fields.FieldEncoder
import io.protoless.messages.Decoder.Result
import io.protoless.messages.decoders.IncrementalDecoder
import io.protoless.fields.FieldDecoder

trait IncrementalEncoderDecoderInstances {

implicit def encodeIncrementalHNil[N <: Nat]: IncrementalEncoder[HNil, N] =
new IncrementalEncoder[HNil, N](
new Encoder[HNil] {
override def encode(a: HNil, output: CodedOutputStream): Unit = {}
}
)

implicit def encodeIncrementalHList[H, T <: HList, N <: Nat](implicit
hEncoder: FieldEncoder[H],
index: ToInt[N],
tEncoder: IncrementalEncoder[T, Succ[N]]
): IncrementalEncoder[H :: T, N] = new IncrementalEncoder[H :: T, N](
new Encoder[H :: T] {
override def encode(a: H :: T, output: CodedOutputStream): Unit = {
val (h :: t) = a
hEncoder.write(index(), h, output)
tEncoder.underlying.encode(t, output)
}
}
)

implicit def encodeIncremental[A, N <: Nat, R <: HList](implicit
gen: Generic.Aux[A, R],
encoder: IncrementalEncoder[R, N]
): IncrementalEncoder[A, N] = new IncrementalEncoder[A, N](
new Encoder[A] {
override def encode(a: A, output: CodedOutputStream): Unit = {
encoder.underlying.encode(gen.to(a), output)
output.flush()
}
}
)

implicit def decodeIncrementalHNil[N <: Nat]: IncrementalDecoder[HNil, N] =
new IncrementalDecoder[HNil, N](
new Decoder[HNil] {
override def decode(input: CodedInputStream): Result[HNil] = Right(HNil)
}
)

implicit def decodeIncrementalHList[H, T <: HList, N <: Nat](implicit
hDecoder: FieldDecoder[H],
index: shapeless.ops.nat.ToInt[N],
tDecoder: IncrementalDecoder[T, Succ[N]]
): IncrementalDecoder[H :: T, N] = new IncrementalDecoder[H :: T, N](
new Decoder[H :: T] {
override def decode(input: CodedInputStream): Result[H :: T] = {
for {
h <- hDecoder.read(input, index()).right
t <- tDecoder.underlying.decode(input).right
} yield h :: t
}
}
)

implicit def decodeIncremental[A, N <: Nat, R <: HList](implicit
gen: Generic.Aux[A, R],
decoder: IncrementalDecoder[R, N]
): IncrementalDecoder[A, N] = new IncrementalDecoder[A, N](
new Decoder[A] {
override def decode(input: CodedInputStream): Result[A] = {
decoder.underlying.decode(input) match {
case Right(repr) => Right(gen.from(repr))
case l @ Left(_) => l.asInstanceOf[Result[A]]
}
}
}
)
}

This file was deleted.

Loading

0 comments on commit 1cdeed9

Please sign in to comment.