Skip to content

Instantly share code, notes, and snippets.

@tarao
Last active December 15, 2023 05:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tarao/44e294bafa5b7cace8d2ca7f7da49855 to your computer and use it in GitHub Desktop.
Save tarao/44e294bafa5b7cace8d2ca7f7da49855 to your computer and use it in GitHub Desktop.
package example.j5ik2o.dop.domain
import example.j5ik2o.common.domain.ItemType
import com.github.tarao.record4s.{%, Tag}
import java.net.URL
type Item = %{
val id: ItemId
val name: ItemName
val price: Money
val itemType: ItemType
} & Tag[Item.Tag]
opaque type ItemId = String
object ItemId {
def apply(value: String): ItemId = value
def unapply(self: ItemId): Option[String] = Some(self)
given Conversion[String, ItemId] = ItemId(_)
extension (self: ItemId) {
def value: String = self
}
}
object Item {
def apply(id: ItemId, name: ItemName, price: Money, itemType: ItemType): Item =
%(id = id, name = name, price = price, itemType = itemType).tag[Item.Tag]
def id(self: Item): ItemId = self.id
def name(self: Item): ItemName = self.name
def price(self: Item): Money = self.price
def itemType(self: Item): ItemType = self.itemType
trait Tag
}
type GenericItem = Item & Tag[GenericItem.Tag]
object GenericItem {
def apply(id: ItemId, name: ItemName, price: Money): GenericItem =
Item(id, name, price, ItemType.Generic).tag[GenericItem.Tag]
def unapply(self: GenericItem): Option[(ItemId, ItemName, Money)] =
Some((self.id, self.name, self.price))
trait Tag
}
type DownloadableItem = Item & { val url: URL } & Tag[DownloadableItem.Tag]
object DownloadableItem {
def apply(id: ItemId, name: ItemName, url: URL, price: Money): DownloadableItem =
(Item(id, name, price, ItemType.Download) + (url = url))
.tag[DownloadableItem.Tag]
.asInstanceOf[DownloadableItem] // record4s bug
def unapply(self: DownloadableItem): Option[(ItemId, ItemName, URL, Money)] =
Some(
(
self.id,
self.name,
self.url,
self.price,
)
)
trait Tag
object Tag {
// (demo) Defining method on DownloadableItem
//
// ```
// val item: DownloadableItem = ???
// item.hoge
// ```
extension(self: DownloadableItem) {
def hoge: String = "hoge"
}
}
}
type CarItem = Item & Tag[CarItem.Tag]
object CarItem {
def apply(id: ItemId, name: ItemName, price: Money): CarItem =
Item(id, name, price, ItemType.Car).tag[CarItem.Tag]
def unapply(self: CarItem): Option[(ItemId, ItemName, Money)] =
Some((self.id, self.name, self.price))
trait Tag
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment