Created
November 30, 2010 05:50
-
-
Save jeffreyolchovy/721229 to your computer and use it in GitHub Desktop.
Simple type class for formatting objects as JSON or XML
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
package com.olchovy.format | |
import scala.xml._ | |
import net.liftweb.json.JsonAST._ | |
trait Formatter[-A, B] { | |
def format(a: A): B | |
} | |
object Formatters { | |
abstract class JsonFormatter[-A] extends Formatter[A, JValue] | |
implicit def a2fooJson[A](implicit ev: JsonFormatter[A]) = new FooJsonFormatter[A] | |
implicit def a2seqJson[A](implicit ev: JsonFormatter[A]) = new SeqJsonFormatter[A] | |
implicit object StringJsonFormatter extends JsonFormatter[String] { | |
def format(a: String) = JString(a) | |
} | |
implicit object IntJsonFormatter extends JsonFormatter[Int] { | |
def format(a: Int) = JInt(a) | |
} | |
implicit object DoubleJsonFormatter extends JsonFormatter[Double] { | |
def format(a: Double) = JDouble(a) | |
} | |
class SeqJsonFormatter[A](implicit ev: JsonFormatter[A]) extends JsonFormatter[Seq[A]] { | |
def format(a: Seq[A]) = JArray(a.map(ev.format(_)).toList) | |
} | |
class FooJsonFormatter[A](implicit ev: JsonFormatter[A]) extends JsonFormatter[Foo[A]] { | |
def format(a: Foo[A]) = JField(a.descriptor, ev.format(a.underlying)) | |
} | |
abstract class XmlFormatter[-A] extends Format[A, NodeSeq] | |
implicit def a2fooXml[A](implicit ev: XmlFormatter[A]) = new FooXmlFormatter[A] | |
implicit def a2seqXml[A](implicit ev: XmlFormatter[A]) = new SeqXmlFormatter[A] | |
implicit object StringXmlFormatter extends XmlFormatter[String] { | |
def format(a: String) = Text(a) | |
} | |
implicit object IntXmlFormatter extends XmlFormatter[Int] { | |
def format(a: Int) = Text(a.toString) | |
} | |
implicit object DoubleXmlFormatter extends XmlFormatter[Double] { | |
def format(a: Double) = Text(a.toString) | |
} | |
class SeqXmlFormatter[A](implicit ev: XmlFormatter[A]) extends XmlFormatter[Seq[A]] { | |
def format(a: Seq[A]) = new NodeSeq { | |
def theSeq = a.map { | |
a => Elem(null, "item", Null, TopScope, ev.format(a).theSeq: _*) | |
}.flatMap(a => a) | |
} | |
} | |
class FooXmlFormatter[A](implicit ev: XmlFormatter[A]) extends XmlFormatter[Foo[A]] { | |
def format(a: Foo[A]) = { | |
val label = a.descriptor | |
val child = ev.format(a.underlying).theSeq | |
Elem(null, label, Null, TopScope, child: _*) | |
} | |
} | |
} | |
abstract class Foo[+A] { | |
val descriptor: String | |
val underlying: A | |
def format[B](implicit ev: Formatter[Foo[A], B]) = ev.format(this) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment