简体   繁体   中英

Shapeless. Modify tagged type

For instance I have two tagged types:

trait Created
type CreatedDttm = LocalDateTime @@ Created
type CreatedTs = Timestamp @@ Created

This types are used to deal with models. The first one is for common model, and the second one is for db entity.

final case class Entity(created: CreatedDttm)   // Common model
final case class EntityRow(created: CreatedTs)  // DB model

I have a converter somewhere in my sources:

def toModel(e: EntityRow) = Entity(e.created.toLocalDateTime)   // Does not compile

This convertion does not compile, cause e.created.toLocalDateTime returns LocalDateTime , but Entity needs LocalDateTime tagged by Created .

So I have to change my conversion to tag[Created](e.created.toLocalDateTime) to make this code compile. It works, but, imho, it looks a kind of ugly.

Timestamp was tagged by Created , and a new LocalDateTime must be also tagged by the same Created .

Is there any way to modify tagged type without need to retag a new modified value?

Afraid not. The best I think you can do it minimize your pain. I would use an implicit class with a method like toCreatedDttm . Something like this:

implicit class LocalDateTimeOps(value: LocalDateTime) {
  def toCreatedDttm: CreatedDttm = tag[Created][LocalDateTime](value)
}

Then you can change your line to:

def toModel(e: EntityRow) = Entity(e.created.toLocalDateTime.toCreatedDttm)

Or perhaps you can have the implicit class operate directly on the Timestamp like this:

implicit class TimestampOps(value: Timestamp) {
  def toCreatedDttm: CreatedDttm = tag[Created][LocalDateTime](value.toLocalDateTime)
}

Then the line could be:

def toModel(e: EntityRow) = Entity(e.created.toCreatedDttm)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM