Last active
August 29, 2015 14:13
-
-
Save jeffmay/868116e2689fa3a359ce to your computer and use it in GitHub Desktop.
SecurePrinter typeclass
This file contains 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
import scala.annotation.implicitNotFound | |
import scala.language.{higherKinds, implicitConversions} | |
/** | |
* A typeclass of securely printable values. | |
* | |
* Only primitive values and values that are marked as securely printable by default. | |
* | |
* You can extend new types as securely printable by adding an implicit printable to the | |
* companion object of the class. | |
* | |
* {{{ | |
* class NewType | |
* object NewType { | |
* implicit lazy val printable = SecurelyPrintable.usingToString[NewType] | |
* } | |
* }}} | |
*/ | |
@implicitNotFound("No implicit SecurePrinter found for type ${T}. " + | |
"Implement or import an implicit SecurePrinter[${T}]." | |
) | |
trait SecurePrinter[-T] { | |
def write(value: T): String | |
} | |
object SecurePrinter { | |
def of[T: SecurePrinter]: SecurePrinter[T] = implicitly | |
def using[T](asString: T => String): SecurePrinter[T] = new SecurePrinter[T] { | |
override def write(value: T): String = asString(value) | |
} | |
def usingToString[T <: AnyRef]: SecurePrinter[T] = new SecurePrinter[T] { | |
override def write(value: T): String = value.toString | |
} | |
implicit object SecurePrinterString extends SecurePrinter[String] { | |
override def write(value: String): String = value | |
} | |
implicit object SecurePrinterAnyVal extends SecurePrinter[AnyVal] { | |
override def write(value: AnyVal): String = value.toString | |
} | |
/** | |
* Creates a printer that prints the class name with all the items separated by commas. | |
* | |
* This mimics the way case classes, tuples, and Scala collections are printed. | |
*/ | |
implicit def TraversableSecurePrinter[T](implicit printer: SecurePrinter[T]): SecurePrinter[Traversable[T]] = { | |
new SecurePrinter[Traversable[T]] { | |
override def write(ts: Traversable[T]): String = { | |
val className = ts.getClass.getSimpleName | |
val builder = new StringBuilder(className) | |
builder.append('(') | |
if (ts.nonEmpty) { | |
val iter = ts.toIterator | |
builder.append(printer.write(iter.next())) | |
while (iter.hasNext) { | |
builder.append(',') | |
builder.append(' ') | |
builder.append(printer.write(iter.next())) | |
} | |
} | |
builder.append(')') | |
builder.result() | |
} | |
} | |
} | |
} |
Turns out I don't need C at all. I fixed it.
Thanks!!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
And when I run it: