Skip to content

Commit

Permalink
Merge commit '1dfd69cc7120d79e429d3d508d51dcbb28c9a84c' into topic/jn…
Browse files Browse the repository at this point in the history
…umber-funk

Conflicts:
	.gitignore
	src/main/scala/argonaut/Json.scala
	src/test/scala/argonaut/PrettyParamsSpecification.scala
  • Loading branch information
tixxit committed Dec 6, 2014
2 parents 5531d7f + 1dfd69c commit 613dcf7
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 154 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ target
repl-port
*~
tags
*.sublime-*
23 changes: 23 additions & 0 deletions src/main/scala/argonaut/DecodeJson.scala
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,27 @@ trait DecodeJsons extends GeneratedDecodeJsons with internal.MacrosCompat {

implicit def SetDecodeJson[A](implicit e: DecodeJson[A]): DecodeJson[Set[A]] =
implicitly[DecodeJson[List[A]]] map (_.toSet) setName "[A]Set[A]"

implicit def IMapDecodeJson[A: DecodeJson: Order]: DecodeJson[String ==>> A] =
MapDecodeJson[A].map(a => ==>>.fromList(a.toList)) setName "[A]==>>[String, A]"

implicit def IListDecodeJson[A: DecodeJson]: DecodeJson[IList[A]] =
implicitly[DecodeJson[List[A]]] map (IList.fromList) setName "[A]IList[A]"

implicit def DListDecodeJson[A: DecodeJson]: DecodeJson[DList[A]] =
implicitly[DecodeJson[List[A]]] map (DList.fromList(_)) setName "[A]DList[A]"

implicit def EphemeralStreamDecodeJson[A: DecodeJson]: DecodeJson[EphemeralStream[A]] =
implicitly[DecodeJson[List[A]]] map (list => EphemeralStream.apply(list: _*)) setName "[A]EphemeralStream[A]"

implicit def ISetDecodeJson[A: DecodeJson: Order]: DecodeJson[ISet[A]] =
implicitly[DecodeJson[List[A]]] map (ISet.fromList(_)) setName "[A]ISet[A]"

implicit def NonEmptyListDecodeJson[A: DecodeJson]: DecodeJson[NonEmptyList[A]] =
implicitly[DecodeJson[List[A]]] flatMap (l =>
DecodeJson[NonEmptyList[A]](c => std.list.toNel(l) match {
case None => DecodeResult.fail("[A]NonEmptyList[A]", c.history)
case Some(n) => DecodeResult.ok(n)
})
) setName "[A]NonEmptyList[A]"
}
43 changes: 32 additions & 11 deletions src/main/scala/argonaut/EncodeJson.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,35 +55,34 @@ object EncodeJson extends EncodeJsons {
macro GenericMacros.deriveLabelledInstance[EncodeJson, A]
}

implicit def EncodeJsonTypeClass: LabelledTypeClass[EncodeJson] = new LabelledTypeClass[EncodeJson] {
def emptyCoproduct =
EncodeJson(_ => jEmptyObject)
implicit val EncodeJsonTypeClass: LabelledTypeClass[EncodeJson] = new LabelledTypeClass[EncodeJson] {
def emptyCoproduct = EncodeJson(_ => jEmptyObject)

def coproduct[L, R <: Coproduct](name: String, CL: => EncodeJson[L], CR: => EncodeJson[R]): EncodeJson[L :+: R] =
EncodeJson(a => a match {
case Inl(x) => Json((name -> CL.encode(x)))
case Inr(t) => CR.encode(t)
})

def emptyProduct =
EncodeJson(_ => jEmptyObject)
def emptyProduct = EncodeJson(_ => jEmptyObject)

def product[A, T <: HList](name: String, A: EncodeJson[A], T: EncodeJson[T]) =
def product[A, T <: HList](name: String, A: EncodeJson[A], T: EncodeJson[T]): EncodeJson[A :: T] = {
EncodeJson(a => (name -> A.encode(a.head)) ->: T.encode(a.tail))
}

def project[F, G](instance: => EncodeJson[G], to : F => G, from : G => F) =
instance.contramap(to)
def project[F, G](instance: => EncodeJson[G], to : F => G, from : G => F) = instance.contramap(to)
}

def of[A: EncodeJson] =
implicitly[EncodeJson[A]]

def of[A: EncodeJson] = implicitly[EncodeJson[A]]
}

trait EncodeJsons extends GeneratedEncodeJsons with internal.MacrosCompat {
def contrazip[A, B](e: EncodeJson[A \/ B]): (EncodeJson[A], EncodeJson[B]) =
(EncodeJson(a => e(a.left)), EncodeJson(b => e(b.right)))

def fromFoldable[F[_], A](implicit A: EncodeJson[A], F: Foldable[F]): EncodeJson[F[A]] =
EncodeJson(fa => jArray(F.foldLeft(fa, Nil: List[Json])((list, a) => A.encode(a) :: list).reverse))

implicit val JsonEncodeJson: EncodeJson[Json] =
EncodeJson(q => q)

Expand Down Expand Up @@ -178,6 +177,28 @@ trait EncodeJsons extends GeneratedEncodeJsons with internal.MacrosCompat {
}
))

implicit def IListEncodeJson[A: EncodeJson]: EncodeJson[IList[A]] =
fromFoldable[IList, A]

implicit def DListEncodeJson[A: EncodeJson]: EncodeJson[DList[A]] =
fromFoldable[DList, A]

implicit def EphemeralStreamEncodeJson[A: EncodeJson]: EncodeJson[EphemeralStream[A]] =
fromFoldable[EphemeralStream, A]

implicit def ISetEncodeJson[A: EncodeJson]: EncodeJson[ISet[A]] =
fromFoldable[ISet, A]

implicit def NonEmptyListEncodeJson[A: EncodeJson]: EncodeJson[NonEmptyList[A]] =
fromFoldable[NonEmptyList, A]

implicit def IMapEncodeJson[A](implicit A: EncodeJson[A]): EncodeJson[String ==>> A] =
EncodeJson(x => jObjectAssocList(
x.foldrWithKey(Nil: List[(String, Json)])(
(k, v, list) => (k, A(v)) :: list
)
))

implicit val EncodeJsonContra: Contravariant[EncodeJson] = new Contravariant[EncodeJson] {
def contramap[A, B](r: EncodeJson[A])(f: B => A) = r contramap f
}
Expand Down
10 changes: 2 additions & 8 deletions src/main/scala/argonaut/Json.scala
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ trait Jsons {
type JsonString = String
type JsonField = String
type JsonAssoc = (JsonField, Json)
type JsonObjectMap = scalaz.InsertionMap[JsonField, Json]
type JsonAssocList = List[JsonAssoc]

import PLens._, StoreT._

Expand Down Expand Up @@ -888,16 +888,10 @@ trait Jsons {
def jSingleObject(k: JsonField, v: Json): Json =
JObject(JsonObject.single(k, v))

/**
* Construct a JSON value that is an object from an index.
*/
def jObjectMap(x: JsonObjectMap): Json =
JObject(JsonObject(x))

/**
* Construct a JSON value that is an object from an association list.
*/
def jObjectAssocList(x: List[(JsonField, Json)]): Json =
def jObjectAssocList(x: JsonAssocList): Json =
JObject(JsonObject.from(x))

/**
Expand Down
15 changes: 0 additions & 15 deletions src/main/scala/argonaut/JsonObject.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ sealed trait JsonObject {
*/
def toMap: Map[JsonField, Json]

/**
* Convert to an insertion map.
*/
@deprecated("InsertionMap is deprecated in scalaz 7.1, use toList instead", "6.1")
def toInsertionMap: InsertionMap[JsonField, Json]

/**
* Insert the given association.
*/
Expand Down Expand Up @@ -108,11 +102,6 @@ private[argonaut] case class JsonObjectInstance(

def toMap: Map[JsonField, Json] = fieldsMap

@deprecated("InsertionMap is deprecated in scalaz 7.1, use toList instead", "6.1")
def toInsertionMap: InsertionMap[JsonField, Json] =
orderedFields.foldLeft(InsertionMap.empty[JsonField, Json]){(acc, field) =>
acc ^+^ (field, fieldsMap(field))}

def +(f: JsonField, j: Json): JsonObject =
if (fieldsMap.contains(f)) {
copy(fieldsMap = fieldsMap.updated(f, j))
Expand Down Expand Up @@ -178,10 +167,6 @@ object JsonObject extends JsonObjects {
def from[F[_]: Foldable](f: F[(JsonField, Json)]): JsonObject =
f.foldLeft(empty){ case (acc, (k, v)) => acc + (k, v) }

@deprecated("InsertionMap is deprecated in scalaz 7.1. Use `from[[F[_]: Foldable]] instead", "6.1")
def apply(insertionMap: InsertionMap[JsonField, Json]): JsonObject =
from(insertionMap.toList)

/**
* Construct an empty association.
*/
Expand Down
7 changes: 7 additions & 0 deletions src/test/scala/argonaut/CodecSpecification.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import scala.collection.immutable.SortedSet
import scala.collection.mutable.ArrayBuffer
import scalaz._, Scalaz._
import scalaz.scalacheck.ScalaCheckBinding._
import scalaz.scalacheck.ScalazArbitrary.{UnitArbitrary => _, _}
import org.scalacheck._, Arbitrary._, Prop._
import org.specs2._, org.specs2.specification._

Expand Down Expand Up @@ -67,6 +68,12 @@ object CodecSpecification extends Specification with ScalaCheck {
String \\/ Int encode/decode ${encodedecode[String \/ Int]}
Map[String, Int] encode/decode ${encodedecode[Map[String, Int]]}
Set[String] encode/decode ${encodedecode[Set[String]]}
ISet[Int] encode/decode ${encodedecode[ISet[Int]]}
IList[Int] encode/decode ${encodedecode[IList[Int]]}
NonEmptyList[Int] encode/decode ${encodedecode[NonEmptyList[Int]]}
DList[Int] encode/decode ${encodedecode[DList[Int]]}
EphemeralStream[Int] encode/decode ${encodedecode[EphemeralStream[Int]]}
IMap[String, Int] encode/decode ${encodedecode[IMap[String, Int]]}
Tuple2[String, Int] encode/decode ${encodedecode[Tuple2[String, Int]]}
Tuple3[String, Int, Boolean] encode/decode ${encodedecode[Tuple3[String, Int, Boolean]]}
Tuple4[String, Int, Boolean, Long] encode/decode ${encodedecode[Tuple4[String, Int, Boolean, Long]]}
Expand Down
3 changes: 0 additions & 3 deletions src/test/scala/argonaut/Data.scala
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,6 @@ object Data {
implicit val ArbitrarySometimesBoolString: Arbitrary[SometimesBoolString] =
Arbitrary(frequency((1, value("true")), (1, value("false")), (8, arbitrary[String])) map (SometimesBoolString(_)))

implicit def ArbitraryScalazEither[A: Arbitrary, B: Arbitrary]: Arbitrary[A \/ B] =
Arbitrary(arbitrary[Either[A, B]] map (\/.fromEither(_)))

implicit val ArbitraryPrettyParams: Arbitrary[PrettyParams] = Arbitrary(
for {
lbraceLeft <- arbitrary[Int => String]
Expand Down
16 changes: 7 additions & 9 deletions src/test/scala/argonaut/DecodeJsonSpecification.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import shapeless._
import org.scalacheck._, Arbitrary._, Prop._
import org.specs2._, org.specs2.specification._

// Defining these below (close to ShapeArbitrary say) makes the DecodeJson derivation fail
// Same thing for EncodeJson
sealed trait Shape
case class Circle(radius: Int) extends Shape
case class Square(side: Int) extends Shape

object DecodeJsonSpecification extends Specification with ScalaCheck { def is = s2"""

DecodeJson Witness Compilation
Expand All @@ -19,7 +25,7 @@ DecodeJson Auto Derivation
--------------------------

Product-types correspond ${auto.products}
Sum-types correspond NOT COMPILING-- auto.sums
Sum-types correspond ${auto.sums}

"""

Expand Down Expand Up @@ -61,12 +67,6 @@ DecodeJson Auto Derivation
Json("Person" := Json("name" := p.name, "age" := p.age)).as[Person].toOption must_== Some(p))


/* FIX this should work, but doesn't --
sealed trait Shape
case class Circle(radius: Int) extends Shape
case class Square(side: Int) extends Shape
implicit def ShapeArbitrary: Arbitrary[Shape] = Arbitrary(Gen.oneOf(
arbitrary[Int].map(Circle.apply)
, arbitrary[Int].map(Square.apply)
Expand All @@ -77,8 +77,6 @@ DecodeJson Auto Derivation
case Circle(radius) => Json("Circle" := Json("radius" := radius))
case Square(side) => Json("Square" := Json("side" := side))
}).as[Shape].toOption must_== Some(s))
*/
}

object derived {
Expand Down
12 changes: 3 additions & 9 deletions src/test/scala/argonaut/EncodeJsonSpecification.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ EncodeJson Auto Derivation
--------------------------

Product-types correspond ${auto.products}
Sum-types correspond NOT COMPILING-- auto.sums
Sum-types correspond ${auto.sums}

"""

Expand Down Expand Up @@ -59,12 +59,6 @@ EncodeJson Auto Derivation
def products = prop((p: Person) =>
p.asJson must_== Json("Person" := Json("name" := p.name, "age" := p.age)))

/* FIX this should work, but doesn't --
sealed trait Shape
case class Circle(radius: Int) extends Shape
case class Square(side: Int) extends Shape
implicit def ShapeArbitrary: Arbitrary[Shape] = Arbitrary(Gen.oneOf(
arbitrary[Int].map(Circle.apply)
, arbitrary[Int].map(Square.apply)
Expand All @@ -73,10 +67,10 @@ EncodeJson Auto Derivation
EncodeJson.of[Shape]

def sums = prop((s: Shape) =>
s.asJson(x) must_== (s match {
s.asJson must_== (s match {
case Circle(radius) => Json("Circle" := Json("radius" := radius))
case Square(side) => Json("Square" := Json("side" := side))
})) */
}))
}

object derived {
Expand Down
Loading

0 comments on commit 613dcf7

Please sign in to comment.