Skip to content

Latest commit

 

History

History
81 lines (50 loc) · 2.9 KB

README.md

File metadata and controls

81 lines (50 loc) · 2.9 KB

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

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 }))