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

ldbc.dsl.codec.Encoder.scala Maven / Gradle / Ivy

/**
 * Copyright (c) 2023-2024 by Takahiko Tominaga
 * This software is licensed under the MIT License (MIT).
 * For more information see LICENSE or https://opensource.org/licenses/MIT
 */

package ldbc.dsl.codec

import java.time.*

import scala.compiletime.*

/**
 * Trait for converting Scala types to types that can be handled by PreparedStatement.
 *
 * @tparam A
 *   Types handled in Scala
 */
trait Encoder[A]:

  /**
   * Method to convert Scala types to types that can be handled by PreparedStatement.
   *
   * @param value
   *   Scala types
   * @return
   *   Types that can be handled by PreparedStatement
   */
  def encode(value: A): Encoder.Supported

object Encoder:

  /** Types that can be handled by PreparedStatement. */
  type Supported = Boolean | Byte | Short | Int | Long | Float | Double | BigDecimal | String | Array[Byte] |
    LocalTime | LocalDate | LocalDateTime | None.type

  given Encoder[Boolean] with
    override def encode(value: Boolean): Boolean = value

  given Encoder[Byte] with
    override def encode(value: Byte): Byte = value

  given Encoder[Short] with
    override def encode(value: Short): Short = value

  given Encoder[Int] with
    override def encode(value: Int): Int = value

  given Encoder[Long] with
    override def encode(value: Long): Long = value

  given Encoder[Float] with
    override def encode(value: Float): Float = value

  given Encoder[Double] with
    override def encode(value: Double): Double = value

  given Encoder[BigDecimal] with
    override def encode(value: BigDecimal): BigDecimal = value

  given Encoder[String] with
    override def encode(value: String): String = value

  given Encoder[Array[Byte]] with
    override def encode(value: Array[Byte]): Array[Byte] = value

  given Encoder[LocalTime] with
    override def encode(value: LocalTime): LocalTime = value

  given Encoder[LocalDate] with
    override def encode(value: LocalDate): LocalDate = value

  given Encoder[LocalDateTime] with
    override def encode(value: LocalDateTime): LocalDateTime = value

  given Encoder[Year] with
    override def encode(value: Year): String = value.toString

  given Encoder[YearMonth] with
    override def encode(value: YearMonth): String = value.toString

  given Encoder[None.type] with
    override def encode(value: None.type): None.type = value

  given [A](using encoder: Encoder[A]): Encoder[Option[A]] with
    override def encode(value: Option[A]): Encoder.Supported =
      value match
        case Some(value) => encoder.encode(value)
        case None        => None

  type MapToTuple[T] <: Tuple = T match
    case EmptyTuple      => EmptyTuple
    case h *: EmptyTuple => Encoder[h] *: EmptyTuple
    case h *: t          => Encoder[h] *: MapToTuple[t]

  inline def infer[T]: Encoder[T] =
    summonFrom[Encoder[T]] {
      case parameter: Encoder[T] => parameter
      case _                     => error("Parameter cannot be inferred")
    }

  inline def fold[T]: MapToTuple[T] =
    inline erasedValue[T] match
      case _: EmptyTuple        => EmptyTuple
      case _: (h *: EmptyTuple) => infer[h] *: EmptyTuple
      case _: (h *: t)          => infer[h] *: fold[t]




© 2015 - 2024 Weber Informatics LLC | Privacy Policy