These are chat archives for trueaccord/ScalaPB

3rd
Jun 2018
Mateusz Górski
@goral09
Jun 03 14:14
Hi all, I am trying to use my own collection type. I followed the MyVector implementation but my compilation still fails with:
could not find implicit value for parameter reads: scalapb.descriptors.Reads[coop.rchain.models.ParTreeSet[…]
@thesamet
Nadav Samet
@thesamet
Jun 03 16:24
@goral09 That's very strange. Can you post a full example?
Mateusz Górski
@goral09
Jun 03 16:24
sure, one sec
proto part:
repeated Par ps = 1 [(scalapb.field).collection_type = "coop.rchain.models.ParTreeSet"];
scala part:
case class ParTreeSet[A](ps: Set[A]) {
  def foreach[U](f: A => U): Unit = ps.foreach(f)

  def map[B, That](f: A => B)(implicit cbf: CanBuildFrom[ParTreeSet[A], B, That]): That = {
    val b = cbf.apply()
    ps.foreach(x => b += f(x))
    b.result()
  }


  def ++(s: TraversableOnce[A]): ParTreeSet[A] = ParTreeSet(s.toSet ++ ps)
}

object ParTreeSet {
  implicit val parOrdering: Ordering[Par] = new Ordering[Par] {
    override def compare(x: Par, y: Par): Int = ???
  }

  def apply[A](): ParTreeSet[A] = ParTreeSet(Set[A]())

  def empty[A]: ParTreeSet[A] = apply[A]()

  implicit def cbf[From, A: Ordering](
      implicit vcbf: CanBuildFrom[From, A, Set[A]]): CanBuildFrom[From, A, ParTreeSet[A]] =
    new CanBuildFrom[From, A, ParTreeSet[A]] {
      override def apply(from: From): mutable.Builder[A, ParTreeSet[A]] =
        vcbf(from).mapResult(res => ParTreeSet(res))

      override def apply(): mutable.Builder[A, ParTreeSet[A]] =
        vcbf().mapResult(_ => ParTreeSet[A]())
    }

  class Builder[A] {
    private val underlying = Set.newBuilder[A]

    def ++=(other: ParTreeSet[A]): Builder[A] = {
      underlying ++= other.ps
      this
    }

    def +=(other: A): Unit = underlying += other

    def result(): ParTreeSet[A] = ParTreeSet[A](underlying.result())
  }

  def newBuilder[A] = new Builder[A]
}
Nadav Samet
@thesamet
Jun 03 16:29
can you post a few lines around the generated code where the compilation error occurs?
Mateusz Górski
@goral09
Jun 03 16:29
implicit def messageReads: _root_.scalapb.descriptors.Reads[coop.rchain.models.ESet] = _root_.scalapb.descriptors.Reads{
    case _root_.scalapb.descriptors.PMessage(__fieldsMap) =>
      require(__fieldsMap.keys.forall(_.containingMessage == scalaDescriptor), "FieldDescriptor does not match message type.")
      coop.rchain.models.ESet(
   >>>>     __fieldsMap.get(scalaDescriptor.findFieldByNumber(1).get).map(_.as[coop.rchain.models.ParTreeSet[coop.rchain.models.Par]]).getOrElse(coop.rchain.models.ParTreeSet.empty),
        coop.rchain.models.ESet._typemapper_locallyFree.toCustom(__fieldsMap.get(scalaDescriptor.findFieldByNumber(3).get).map(_.as[_root_.com.google.protobuf.ByteString]).getOrElse(_root_.com.google.protobuf.ByteString.EMPTY)),
        __fieldsMap.get(scalaDescriptor.findFieldByNumber(4).get).map(_.as[_root_.scala.Boolean]).getOrElse(false)
      )
    case _ => throw new RuntimeException("Expected PMessage")
  }
I've marked the place where the error is reported
can it be that Par is not primitive type?
but it is also defined in *.proto file so there is a Reads instance for it:
  implicit def messageReads: _root_.scalapb.descriptors.Reads[coop.rchain.models.Par] = _root_.scalapb.descriptors.Reads{
Nadav Samet
@thesamet
Jun 03 16:35
I think I know
You have a dependency on Ordering[Par] but I think that the implicit parOrdering is not in the implicit search.
Mateusz Górski
@goral09
Jun 03 16:39
Yeah, I've removed that context bound and it passed
but I need it
do I need to import the implicit to in *.proto file?
Nadav Samet
@thesamet
Jun 03 16:40
you could get the companion object of Par to extend a trait that defined this implicit
option (scalapb.message).companion_extends = "MySuperCompanionClass";
Another option would be to have a custom Scala type for Par
(But that would be slightly less performant)
Mateusz Górski
@goral09
Jun 03 16:43
I will first check the first option
Thanks for help :)
Nadav Samet
@thesamet
Jun 03 16:43
you're welcome