All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scalapb.lenses.CompatLensImplicits.scala Maven / Gradle / Ivy

The newest version!
package scalapb.lenses
import scala.collection.SeqOps
import scala.language.implicitConversions

object CompatLensImplicits {

  /** Implicit that adds some syntactic sugar if our lens watches a Seq-like collection. */
  class SeqLikeLens[U, A, CC[A] <: SeqOps[A, CC, CC[A]]](val lens: Lens[U, CC[A]]) extends AnyVal {
    private def field(getter: CC[A] => A)(setter: (CC[A], A) => CC[A]): Lens[U, A] =
      lens.compose[A](Lens[CC[A], A](getter)(setter))

    def apply(i: Int): Lens[U, A] =
      field(_.apply(i))((c, v) => c.updated(i, v))

    def head: Lens[U, A] = apply(0)

    def last: Lens[U, A] =
      field(_.last)((c, v) => c.updated(c.size - 1, v))

    def :+=(item: A) = lens.modify(_ :+ item)

    def :++=(item: IterableOnce[A]) =
      lens.modify(_ ++ item)

    def foreach(f: Lens[A, A] => Mutation[A]): Mutation[U] =
      lens.modify(s =>
        s.map { (m: A) =>
          val field: Lens[A, A] = Lens.unit[A]
          val p: Mutation[A]    = f(field)
          p(m)
        }
      )
  }

  /** Implicit that adds some syntactic sugar if our lens watches a Set-like collection. */
  class SetLens[U, A, CC[A] <: collection.immutable.SetOps[A, CC, CC[A]]](val lens: Lens[U, CC[A]])
      extends AnyVal {
    def :+=(item: A) = lens.modify(_ + item)

    def :++=(item: scala.collection.IterableOnce[A]) =
      lens.modify(_ ++ item)

    def foreach(f: Lens[A, A] => Mutation[A]): Mutation[U] =
      lens.modify(s =>
        s.map { (m: A) =>
          val field: Lens[A, A] = Lens.unit[A]
          val p: Mutation[A]    = f(field)
          p(m)
        }
      )
  }
}

trait CompatLensImplicits {
  import CompatLensImplicits._

  implicit def seqLikeLens[U, A, CC[A] <: SeqOps[A, CC, CC[A]]](
      lens: Lens[U, CC[A]]
  ): SeqLikeLens[U, A, CC] =
    new SeqLikeLens(lens)

  implicit def setLens[U, A, CC[A] <: collection.immutable.SetOps[A, CC, CC[A]]](
      lens: Lens[U, CC[A]]
  ): SetLens[U, A, CC] =
    new SetLens(lens)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy