Skip to content
This repository has been archived by the owner on Dec 29, 2022. It is now read-only.

Allocate only one Label per tag type, and only one default Label. #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions src/main/scala/Label.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,28 @@ trait Label[A] {
}

object Label {
private[id] def default[A] = new Label[A] {
def label = ""
private val defaultLabel: Label[Nothing] = new Label[Nothing] {
val label = ""
}

private[id] def default[A]: Label[A] = defaultLabel.asInstanceOf[Label[A]]

private[id] sealed trait LabelDefinitionConflict

private def nameOf[A](implicit m: Manifest[A]) = {
val typeName = m.toString
typeName.substring(0, typeName.lastIndexOf(".type"))
}

trait MakeLabel { self =>
// See eidos.id.Format.UUID for an explanation of this
// format: off
final def `"In Eidos, you can only extend one of MakeLabel or CustomLabel"`
: LabelDefinitionConflict = null

implicit final def l(implicit ev: self.type <:< Product): Label[this.type] =
new Label[this.type] {
def label = self.productPrefix
}
implicit final val l: Label[this.type] = new Label[this.type] {
val label: String = nameOf[self.type]
}
}

trait CustomLabel {
Expand All @@ -30,10 +36,10 @@ object Label {
// format: on
def label: String

private def customLabel = label
private val customLabel = label

implicit final def l: Label[this.type] = new Label[this.type] {
def label = customLabel
implicit final val l: Label[this.type] = new Label[this.type] {
val label = customLabel
}
}
}
6 changes: 3 additions & 3 deletions src/test/scala/EidosSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,8 @@ class EidosSpec extends Specification with TypecheckMatchers with ScalaCheck {
"Tag" should {
"be case objects" in {
trait Trait

// MakeLabel is the reason why "case" is required
object Object extends MakeLabel
class Class
object Object
type Object = Object.type

case object CaseObject
Expand All @@ -96,6 +95,7 @@ class EidosSpec extends Specification with TypecheckMatchers with ScalaCheck {

// format: off
{ typecheck("""Id.of[Trait]("")""") must failWith(errorMessage("Trait")) }
{ typecheck("""Id.of[Class]("")""") must failWith(errorMessage("Class")) }
{ typecheck("""Id.of[Object]("")""") must failWith(errorMessage("Object")) }
{ typecheck("""Id.of[CaseObject]("")""") must succeed }
// format: on
Expand Down