Skip to content

Instantly share code, notes, and snippets.

@eed3si9n
Created August 3, 2011 03:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eed3si9n/1121835 to your computer and use it in GitHub Desktop.
Save eed3si9n/1121835 to your computer and use it in GitHub Desktop.
trait CanReadXML[A] {
def reads(seq: scala.xml.NodeSeq): Either[String, A]
}
trait Foo { def foo: Int }
trait Bar { def bar: Int }
object Def {
def fromXML[A: CanReadXML](seq: scala.xml.NodeSeq) =
implicitly[CanReadXML[A]].reads(seq)
}
implicit val fooCanReadXML = new CanReadXML[Foo] {
def reads(seq: scala.xml.NodeSeq) = (seq \ "foo").headOption map { x =>
Right(new Foo {
def foo = x.text.toInt
})
} getOrElse { Left("no foo") }
}
implicit val barCanReadXML = new CanReadXML[Bar] {
def reads(seq: scala.xml.NodeSeq) = (seq \ "bar").headOption map { x =>
Right(new Bar {
def bar = x.text.toInt
})
} getOrElse { Left("no bar") }
}
implicit val fooBarCanReadXML = new CanReadXML[Foo with Bar] {
def reads(seq: scala.xml.NodeSeq) =
(Def.fromXML[Foo](seq), Def.fromXML[Bar](seq)) match {
case (Right(x), Right(y)) => Right(new Foo with Bar {
def foo = x.foo
def bar = y.bar
override def toString = "FooWithBar(%d, %d)" format(foo, bar)
})
case _ => Left("no foo with bar")
}
}
Def.fromXML[Foo with Bar](<obj><foo>1</foo><bar>2</bar></obj>)
@eed3si9n
Copy link
Author

eed3si9n commented Aug 3, 2011

scala> Def.fromXML[Foo with Bar](<obj><foo>1</foo><bar>2</bar></obj>)
res0: Either[String,Foo with Bar] = Right(FooWithBar(1, 2))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment