blob: 2feeb29efbccc61ccdacdfcce78710300a32d9fb (
plain) (
tree)
|
|
package dotty
import scala.annotation.implicitNotFound
@implicitNotFound("No member of type class Show could be found for ${T}")
trait Show[-T] {
def show(t: T): String
}
/** Ideally show would only contain `defaultShow` and the pimped generic class,
* but since we can't change the current stdlib, we're stuck with providing
* default instances in this object
*/
object Show {
private[this] val defaultShow: Show[Any] = new Show[Any] {
def show(x: Any) = x.toString
}
/** This class implements pimping of all types to provide a show method.
* Currently it is quite permissive, if there's no instance of `Show[T]` for
* any `T`, we default to `T#toString`.
*/
implicit class ShowValue[V](val v: V) extends AnyVal {
def show(implicit ev: Show[V] = defaultShow): String =
ev.show(v)
}
implicit val stringShow: Show[String] = new Show[String] {
// From 2.12 spec, `charEscapeSeq`:
// ‘\‘ (‘b‘ | ‘t‘ | ‘n‘ | ‘f‘ | ‘r‘ | ‘"‘ | ‘'‘ | ‘\‘)
def show(str: String) =
"\"" + {
val sb = new StringBuilder
str.foreach {
case '\b' => sb.append("\\b")
case '\t' => sb.append("\\t")
case '\n' => sb.append("\\n")
case '\f' => sb.append("\\f")
case '\r' => sb.append("\\r")
case '\'' => sb.append("\\'")
case '\"' => sb.append("\\\"")
case c => sb.append(c)
}
sb.toString
} + "\""
}
implicit val intShow: Show[Int] = new Show[Int] {
def show(i: Int) = i.toString
}
implicit val floatShow: Show[Float] = new Show[Float] {
def show(f: Float) = f + "f"
}
implicit val doubleShow: Show[Double] = new Show[Double] {
def show(d: Double) = d.toString
}
implicit val charShow: Show[Char] = new Show[Char] {
def show(c: Char) = "'" + (c match {
case '\b' => "\\b"
case '\t' => "\\t"
case '\n' => "\\n"
case '\f' => "\\f"
case '\r' => "\\r"
case '\'' => "\\'"
case '\"' => "\\\""
case c => c
}) + "'"
}
implicit def showList[T](implicit st: Show[T]): Show[List[T]] = new Show[List[T]] {
def show(xs: List[T]) =
if (xs.isEmpty) "Nil"
else "List(" + xs.map(_.show).mkString(", ") + ")"
}
implicit val showNil: Show[Nil.type] = new Show[Nil.type] {
def show(xs: Nil.type) = "Nil"
}
implicit def showOption[T](implicit st: Show[T]): Show[Option[T]] = new Show[Option[T]] {
def show(ot: Option[T]): String = ot match {
case Some(t) => "Some("+ st.show(t) + ")"
case none => "None"
}
}
implicit val showNone: Show[None.type] = new Show[None.type] {
def show(n: None.type) = "None"
}
implicit def showMap[K,V](implicit sk: Show[K], sv: Show[V]): Show[Map[K,V]] = new Show[Map[K,V]] {
def show(m: Map[K, V]) =
"Map(" + m.map { case (k, v) => sk.show(k) + " -> " + sv.show(v) } .mkString (", ") + ")"
}
implicit def showMapOfNothing: Show[Map[Nothing,Nothing]] = new Show[Map[Nothing,Nothing]] {
def show(m: Map[Nothing, Nothing]) = m.toString
}
}
|