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

no.kodeworks.kvarg.ember.package.scala Maven / Gradle / Ivy

There is a newer version: 0.7
Show newest version
package no.kodeworks.kvarg

import no.kodeworks.kvarg.util.hlistToList
import shapeless._
import shapeless.ops.hlist.Mapper
import shapeless.ops.record.UnzipFields
import no.kodeworks.kvarg.util._
package object ember {

  sealed class EmberGen[Model] {
    def apply[
    ModelFields <: HList
    , Keys <: HList
    , Values <: HList
    , ValueStrings <: HList
    , JsonValueStrings <: HList
    ]
    (
      implicit
      lg: LabelledGeneric.Aux[Model, ModelFields]
      , uz: UnzipFields.Aux[ModelFields, Keys, Values]
      , valueStrings: ValueStrings.Aux[Values, ValueStrings]
      , jsonValueStrings0: Mapper.Aux[jsonValueStrings.type, ValueStrings, JsonValueStrings]
    )
    : String
    =
      hlistToList[Symbol](uz.keys()).map(_.name).zip(
        hlistToList[String](jsonValueStrings0(valueStrings()))).collect {
        case (key, value) if "id" != key => s"""\t$key: DS.attr('$value')"""
      }.mkString("export default DS.Model.extend({\n", ",\n\n", "\n});")
  }

  object EmberGen {
    def apply[Model]: EmberGen[Model] = new EmberGen[Model]
  }

  trait jsonValueStringsLP {
    this: Poly1 =>
    implicit def any[T <: Any]: Case.Aux[ValueString[T], String] = at[ValueString[T]] { kv =>
      kv.value
    }
  }

  // @formatter:off
  object jsonValueStrings extends Poly1 with jsonValueStringsLP {
    implicit def boolean[T <: Boolean]: Case.Aux[ValueString[T], String] = at[ValueString[T]](_ => "boolean")
    implicit def short[T <: Short]: Case.Aux[ValueString[T], String] = at[ValueString[T]](_ => "number")
    implicit def int[T <: Int]: Case.Aux[ValueString[T], String] = at[ValueString[T]](_ => "number")
    implicit def long[T <: Long]: Case.Aux[ValueString[T], String] = at[ValueString[T]](_ => "number")
    implicit def double[T <: Double]: Case.Aux[ValueString[T], String] = at[ValueString[T]](_ => "number")
    implicit def string[T <: String]: Case.Aux[ValueString[T], String] = at[ValueString[T]](_ => "string")
    implicit def oboolean[T <: Boolean]: Case.Aux[ValueString[Option[T]], String] = at[ValueString[Option[T]]](_ => "boolean")
    implicit def oshort[T <: Short]: Case.Aux[ValueString[Option[T]], String] = at[ValueString[Option[T]]](_ => "number")
    implicit def oint[T <: Int]: Case.Aux[ValueString[Option[T]], String] = at[ValueString[Option[T]]](_ => "number")
    implicit def olong[T <: Long]: Case.Aux[ValueString[Option[T]], String] = at[ValueString[Option[T]]](_ => "number")
    implicit def odouble[T <: Double]: Case.Aux[ValueString[Option[T]], String] = at[ValueString[Option[T]]](_ => "number")
    implicit def ostring[T <: String]: Case.Aux[ValueString[Option[T]], String] = at[ValueString[Option[T]]](_ => "string")
  }
  // @formatter:on

  case class ValueString[Value](value: String)

  trait ValueStrings[L <: HList] extends DepFn0 {
    type Out <: HList
  }

  object ValueStrings {

    type Aux[L <: HList, Out0 <: HList] = ValueStrings[L] {type Out = Out0}

    def apply[L <: HList](implicit valueStrings: ValueStrings[L]): valueStrings.Out = valueStrings.apply()

    implicit def hnilValueStrings[L <: HNil]: Aux[L, HNil] = new ValueStrings[L] {
      type Out = HNil

      def apply(): Out = HNil
    }

    implicit def hlistValueStrings[V, Rest <: HList]
    (implicit
     valueStringsRest: ValueStrings[Rest]
     , tt: Typeable[V]
    ): ValueStrings.Aux[V :: Rest, ValueString[V] :: valueStringsRest.Out] =
      new ValueStrings[V :: Rest] {
        type Out = ValueString[V] :: valueStringsRest.Out

        def apply(): Out =
          ValueString[V](typeableToSimpleName(tt, false)) ::
            valueStringsRest()
      }
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy