aboutsummaryrefslogtreecommitdiff
path: root/library
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-11-30 14:21:51 +0100
committerFelix Mulder <felix.mulder@gmail.com>2016-11-30 16:55:59 +0100
commit5c607cd402001b57721afef8153d9bec5e68c933 (patch)
tree9965e195914374899c523c9b375a374804bfd52f /library
parent3f7614ae60263c937f7b2d97f45ef6e7c803ec01 (diff)
downloaddotty-5c607cd402001b57721afef8153d9bec5e68c933.tar.gz
dotty-5c607cd402001b57721afef8153d9bec5e68c933.tar.bz2
dotty-5c607cd402001b57721afef8153d9bec5e68c933.zip
Add basic Show capability
Diffstat (limited to 'library')
-rw-r--r--library/src/dotty/Show.scala88
-rw-r--r--library/test/dotty/ShowTests.scala76
2 files changed, 164 insertions, 0 deletions
diff --git a/library/src/dotty/Show.scala b/library/src/dotty/Show.scala
new file mode 100644
index 000000000..123fffdc7
--- /dev/null
+++ b/library/src/dotty/Show.scala
@@ -0,0 +1,88 @@
+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 {
+ implicit class ShowValue[V](val v: V) extends AnyVal {
+ def show(implicit ev: Show[V] = null): String =
+ if (ev != null) ev.show(v)
+ else v.toString
+ }
+
+ implicit val stringShow = new Show[String] {
+ //charEscapeSeq ::= ‘\‘ (‘b‘ | ‘t‘ | ‘n‘ | ‘f‘ | ‘r‘ | ‘"‘ | ‘'‘ | ‘\‘)
+ def show(str: String) =
+ "\"" +
+ str
+ .replaceAll("\b", "\\\\b")
+ .replaceAll("\t", "\\\\t")
+ .replaceAll("\n", "\\\\n")
+ .replaceAll("\f", "\\\\f")
+ .replaceAll("\r", "\\\\r")
+ .replaceAll("\'", "\\\\'")
+ .replaceAll("\"", "\\\\\"") +
+ "\""
+ }
+
+ 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
+ }) + "'"
+ }
+
+ object List {
+ 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"
+ }
+ }
+
+ object Option {
+ 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"
+ }
+ }
+
+ object Map {
+ 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 (", ") + ")"
+ }
+ }
+}
diff --git a/library/test/dotty/ShowTests.scala b/library/test/dotty/ShowTests.scala
new file mode 100644
index 000000000..ef259e5d8
--- /dev/null
+++ b/library/test/dotty/ShowTests.scala
@@ -0,0 +1,76 @@
+package dotty
+
+import org.junit.Test
+import org.junit.Assert._
+
+class ShowTests {
+ import Show._
+
+ @Test def showString = {
+ assertEquals("\"\\thello world!\"", "\thello world!".show)
+ assertEquals("\"\\nhello world!\"", "\nhello world!".show)
+ assertEquals("\"\\rhello world!\"", "\rhello world!".show)
+ assertEquals("\"\\b\\t\\n\\f\\r\\\'\\\"\"", "\b\t\n\f\r\'\"".show)
+ }
+
+ @Test def showFloat = {
+ assertEquals("1.0f", 1.0f.show)
+ assertEquals("1.0f", 1.0F.show)
+ }
+
+ @Test def showDouble = {
+ assertEquals("1.0", 1.0d.show)
+ assertEquals("1.0", 1.0.show)
+ }
+
+ @Test def showChar = {
+ assertEquals("'\\b'", '\b'.show)
+ assertEquals("'\\t'", '\t'.show)
+ assertEquals("'\\n'", '\n'.show)
+ assertEquals("'\\f'", '\f'.show)
+ assertEquals("'\\r'", '\r'.show)
+ assertEquals("'\\''", '\''.show)
+ assertEquals("'\\\"'", '\"'.show)
+ }
+
+ @Test def showCar = {
+ import Show.List._
+ case class Car(model: String, manufacturer: String, year: Int)
+ implicit val showCar = new Show[Car] {
+ def show(c: Car) =
+ "Car(" + c.model.show + ", " + c.manufacturer.show + ", " + c.year.show + ")"
+ }
+
+ case class Shop(xs: List[Car], name: String)
+ implicit val showShop = new Show[Shop] {
+ def show(sh: Shop) =
+ "Shop(" + sh.xs.show + ", " + sh.name.show + ")"
+ }
+
+ assertEquals("Car(\"Mustang\", \"Ford\", 1967)", Car("Mustang", "Ford", 1967).show)
+ }
+
+ @Test def showOptions = {
+ import Show.Option._
+ // TODO: first case is not possible since there's no Show[Nothing] - yet
+ //assertEquals("None", None.show)
+ assertEquals("None", (None: Option[String]).show)
+ assertEquals("Some(\"hello opt\")", Some("hello opt").show)
+ }
+
+ @Test def showMaps = {
+ import Show.Map._
+ val mp = scala.collection.immutable.Map("str1" -> "val1", "str2" -> "val2")
+ assertEquals("Map(\"str1\" -> \"val1\", \"str2\" -> \"val2\")", mp.show)
+ }
+
+ @Test def withoutShow = {
+ case class Car(model: String, manufacturer: String, year: Int)
+
+ assertEquals("Car(Mustang,Ford,1967)", Car("Mustang", "Ford", 1967).show)
+ assertEquals(
+ "Map(str1 -> val1, str2 -> val2)",
+ scala.collection.immutable.Map("str1" -> "val1", "str2" -> "val2").show
+ )
+ }
+}