Last active
December 15, 2023 05:53
-
-
Save tarao/44e294bafa5b7cace8d2ca7f7da49855 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
original:
https://github.com/j5ik2o/oop-dop-other/blob/2ac61d3bf6486ab5a4e7bf42b8d66ce9969e5ac6/src/main/scala/example/j5ik2o/dop/domain/Item.scala