aboutsummaryrefslogtreecommitdiff
path: root/library/src/dotty/Show.scala
blob: 2febda0e7d56adf480e1e1c170c32f9be3352c11 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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
}

object Show {
  private[this] val defaultShow = new Show[Any] {
    def show(x: Any) = x.toString
  }

  implicit class ShowValue[V](val v: V) extends AnyVal {
    def show(implicit ev: Show[V] = defaultShow): String =
      ev.show(v)
  }

  implicit val stringShow = 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 = new Show[Int] {
    def show(i: Int) = i.toString
  }

  implicit val floatShow = new Show[Float] {
    def show(f: Float) = f + "f"
  }

  implicit val doubleShow = new Show[Double] {
    def show(d: Double) = d.toString
  }

  implicit val charShow = 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]) = new Show[List[T]] {
    def show(xs: List[T]) =
      if (xs.isEmpty) "Nil"
      else "List(" + xs.map(_.show).mkString(", ") + ")"
  }

  implicit val showNil = new Show[List[Nothing]] {
    def show(xs: List[Nothing]) = "Nil"
  }

  implicit def showOption[T](implicit st: Show[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 = new Show[Option[Nothing]] {
    def show(n: Option[Nothing]) = "None"
  }

  implicit def showMap[K, V](implicit sk: Show[K], sv: Show[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 = new Show[Map[Nothing, Nothing]] {
    def show(m: Map[Nothing, Nothing]) = m.toString
  }
}