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

pipez.dsl.Converter.scala Maven / Gradle / Ivy

The newest version!
package pipez.dsl

import scala.collection.Factory

/** Effect and side-effect free conversion of types */
trait Converter[From, To] {

  def convert(value: From): To
}
object Converter
    extends pipez.PipeAutoSupport[Converter]
    with pipez.PipeSemiautoConfiguredSupport[Converter]
    with ConverterInstances0 {

  /** Utility to create `Converter` without SAM */
  def instance[From, To](f: From => To): Converter[From, To] = f(_)

  object unsafe {

    /** Import if you want to allow conversions from `Option[A]` to `B` by calling `.get` on option */
    implicit def unsafeConvertFromOption[From, To](implicit safe: Converter[From, To]): Converter[Option[From], To] =
      option => safe.convert(option.get)
  }

  implicit val pipeDerivation: pipez.PipeDerivation[Converter] = ConverterDerivationDefinition
}
private[dsl] trait ConverterInstances0 extends ConverterInstances1 { self: Converter.type =>

  implicit def convertEither[FromLeft, FromRight, ToLeft, ToRight, FromEither[L, R] <: Either[L, R]](implicit
    left:  Converter[FromLeft, ToLeft],
    right: Converter[FromRight, ToRight]
  ): Converter[FromEither[FromLeft, FromRight], Either[ToLeft, ToRight]] = either =>
    (either: Either[FromLeft, FromRight]) match {
      case Left(value)  => Left(left.convert(value))
      case Right(value) => Right(right.convert(value))
    }
  implicit def convertLeft[FromLeft, FromRight, ToLeft, ToRight](implicit
    left: Converter[FromLeft, ToLeft]
  ): Converter[Left[FromLeft, FromRight], Left[ToLeft, ToRight]] = { case Left(value) =>
    Left(left.convert(value))
  }
  implicit def convertRight[FromLeft, FromRight, ToLeft, ToRight](implicit
    right: Converter[FromRight, ToRight]
  ): Converter[Right[FromLeft, FromRight], Right[ToLeft, ToRight]] = { case Right(value) =>
    Right(right.convert(value))
  }

  implicit def covertOption[From, To, FromOption[A] <: Option[A]](implicit
    converter: Converter[From, To]
  ): Converter[FromOption[From], Option[To]] =
    _.map(converter.convert)
  implicit def covertSome[From, To](implicit converter: Converter[From, To]): Converter[Some[From], Some[To]] = {
    case Some(value) => Some(converter.convert(value))
  }

  implicit def convertCollection[From, To, FromColl[A] <: Iterable[A], ToColl[_]](implicit
    converter: Converter[From, To],
    ToColl:    Factory[To, ToColl[To]]
  ): Converter[FromColl[From], ToColl[To]] = fromColl => {
    val builder  = ToColl.newBuilder
    val iterator = fromColl.iterator
    while (iterator.hasNext)
      builder.addOne(converter.convert(iterator.next()))
    builder.result()
  }

  implicit def convertMap[FromKey, FromValue, ToKey, ToValue, FromMap[K, V] <: Map[K, V], ToMap[K, V] <: Map[K, V]](
    implicit
    key:   Converter[FromKey, ToKey],
    value: Converter[FromValue, ToValue],
    ToMap: Factory[(ToKey, ToValue), ToMap[ToKey, ToValue]]
  ): Converter[FromMap[FromKey, FromValue], ToMap[ToKey, ToValue]] = fromMap => {
    val builder  = ToMap.newBuilder
    val iterator = fromMap.iterator
    while (iterator.hasNext) {
      val (k, v) = iterator.next()
      builder.addOne(key.convert(k) -> value.convert(v))
    }
    builder.result()
  }
}
private[dsl] trait ConverterInstances1 extends ConverterInstances2 { self: Converter.type =>

  implicit def convertToOption[From, To](implicit converter: Converter[From, To]): Converter[From, Option[To]] =
    from => Some(converter.convert(from))
}
private[dsl] trait ConverterInstances2 { self: Converter.type =>

  implicit def convertToSelf[A, B >: A]: Converter[A, B] = a => a
}
private[dsl] object ConverterDerivationDefinition extends pipez.PipeDerivation.Simple[Converter] {

  override def simpleLift[In, Out](f: In => Out):                       Converter[In, Out] = f(_)
  override def simpleUnlift[In, Out](pipe: Converter[In, Out], in: In): Out                = pipe.convert(in)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy