purescript-son-of-a-j

Zero cost json serialization / deserialization for a subset of PureScript types.


License
BSD-3-Clause
Install
bower install purescript-son-of-a-j

Documentation

purescript-son-of-a-j

Zero cost json serialization and zero copy deserialization for a subset of PureScript types.

Goals and design

  • No extensibilty. No additional instances required. Works out of the box.

  • Provide efficient serialization for types which are internally represented as valid JSON.

  • Provide efficient transformations between any other generic PureScript type (think Sum) and its json serializable version.

Supported types

This library exploits internal JavaScript representations of some PureScript types to allow serialization and deserialization of their values. It provides SonJ class which proofs serializiblity of a given type.

Currently supported types are: Number, String, Int, Boolean, Record, Variant, Array, Null (defined internally) and newtype (with Newtype instance) around any serializable type.

To use this lib user dosen't have to provide any instances at all (please check X type processing in the example below).

Limitations

This libary is not extensible by design as we want to support any newtype serialization out of the box. In other words our instance chain is closed by fully polymorphic instance for Newtype case.

Usage

API

-- | Nearly zero cost - just `unsafeCoerce` with type class check :-P

dump   a. SonJ a  a  Json

unsafeLoad   a. SonJ a  Json  a

-- | Zero copy but with validation (json traversing) cost

load   a. SonJ a  Json  Maybe a

Example usage

This is excerpt of test/Main.purs:

unsafeRoundTrip   a. SonJ a  a  Maybe a
unsafeRoundTrip = SonJ.dump >>> stringify >>> jsonParser >>> hush >>> map SonJ.unsafeLoad

roundTrip   a. SonJ a  a  Maybe a
roundTrip = SonJ.dump >>> stringify >>> jsonParser >>> hush >=> SonJ.load

type MaybeV a = Variant (justa, nothingNull)

just   a. a  MaybeV a
just = inj (SProxy  SProxy "just")

nothing   a. MaybeV a
nothing = inj (SProxy  SProxy "nothing") null

newtype X a b = X { a  a, b  b }
derive instance eqX ∷ (Eq a, Eq b)  Eq (X a b)
derive instance newtypeXNewtype (X a b) _

main  Effect Unit
main = do
  logShow (unsafeRoundTrip (just 8) == Just (just 8))
  logShow (unsafeRoundTrip (just 9) /= Just (just 8))
  logShow (unsafeRoundTrip (X {a: 8, b: just "test"}) == Just (X {a: 8, b: just "test"}))
  logShow (unsafeRoundTrip (X {a: 8, b: just "test"}) /= Just (X {a: 8, b: nothing }))
  logShow (unsafeRoundTrip (X {a: 8, b: nothing  MaybeV Int}) == Just (X {a: 8, b: nothing }))


  logShow (roundTrip (just 8) == Just (just 8))
  logShow (roundTrip (just 9) /= Just (just 8))
  logShow (roundTrip (X {a: 8, b: just "test"}) == Just (X {a: 8, b: just "test"}))
  logShow (roundTrip (X {a: 8, b: just "test"}) /= Just (X {a: 8, b: nothing }))
  logShow (roundTrip (X {a: 8, b: nothing  MaybeV Int}) == Just (X {a: 8, b: nothing }))