Data.Codec.Argonaut
- Package
- purescript-codec-argonaut
- Repository
- garyb/purescript-codec-argonaut
#JsonCodec Source
type JsonCodec a = Codec' (Either JsonDecodeError) Json aCodec type for Json values.
#JsonDecodeError Source
data JsonDecodeErrorError type for failures while decoding.
Constructors
TypeMismatch StringUnexpectedValue JsonAtIndex Int JsonDecodeErrorAtKey String JsonDecodeErrorNamed String JsonDecodeErrorMissingValue
Instances
#printJsonDecodeError Source
printJsonDecodeError :: JsonDecodeError -> StringPrints a JsonDecodeError as a somewhat readable error message.
#JIndexedCodec Source
type JIndexedCodec a = Codec (Either JsonDecodeError) (Array Json) (List Json) a aCodec type for specifically indexed JArray elements.
#indexedArray Source
indexedArray :: forall a. String -> JIndexedCodec a -> JsonCodec aA codec for types that are encoded as an array with a specific layout.
For example, if we'd like to encode a Person as a 2-element array, like
["Rashida", 37], we could write the following codec:
import Data.Codec ((~))
import Data.Codec.Argonaut as CA
type Person = { name ∷ String, age ∷ Int }
codecPerson ∷ CA.JsonCodec Person
codecPerson = CA.indexedArray "Test Object" $
{ name: _, age: _ }
<$> _.name ~ CA.index 0 CA.string
<*> _.age ~ CA.index 1 CA.int
#index Source
index :: forall a. Int -> JsonCodec a -> JIndexedCodec aA codec for an item in an indexedArray.
#JPropCodec Source
type JPropCodec a = Codec (Either JsonDecodeError) (Object Json) (List (Tuple String Json)) a aCodec type for JObject prop/value pairs.
#object Source
object :: forall a. String -> JPropCodec a -> JsonCodec aA codec for objects that are encoded with specific properties.
See also Data.Codec.Argonaut.Record.object for a more commonly useful
version of this function.
#prop Source
prop :: forall a. String -> JsonCodec a -> JPropCodec aA codec for a property of an object.
#record Source
record :: JPropCodec (Record ())The starting value for a object-record codec. Used with recordProp it
provides a convenient method for defining codecs for record types that
encode into JSON objects of the same shape.
For example, to encode a record as the JSON object
{ "name": "Karl", "age": 25 } we would define a codec like this:
import Data.Codec.Argonaut as CA
import Type.Proxy (Proxy(..))
type Person = { name ∷ String, age ∷ Int }
codecPerson ∷ CA.JsonCodec Person
codecPerson =
CA.object "Person" $ CA.record
# CA.recordProp (Proxy :: _ "name") CA.string
# CA.recordProp (Proxy :: _ "age") CA.int
See also Data.Codec.Argonaut.Record.object for a more commonly useful
version of this function.
#recordProp Source
recordProp :: forall p a r r'. IsSymbol p => Cons p a r r' => Proxy p -> JsonCodec a -> JPropCodec (Record r) -> JPropCodec (Record r')Used with record to define codecs for record types that encode into JSON
objects of the same shape. See the comment on record for an example.
#recordPropOptional Source
recordPropOptional :: forall p a r r'. IsSymbol p => Cons p (Maybe a) r r' => Proxy p -> JsonCodec a -> JPropCodec (Record r) -> JPropCodec (Record r')Used with record to define an optional field.
This will only decode the property as Nothing if the field does not exist
in the object - having a values such as null assigned will need handling
separately.
The property will be omitted when encoding and the value is Nothing.
#fix Source
fix :: forall a. (JsonCodec a -> JsonCodec a) -> JsonCodec aHelper function for defining recursive codecs in situations where the codec definition causes a "The value of <codec> is undefined here" error.
import Data.Codec.Argonaut as CA
import Data.Codec.Argonaut.Common as CAC
import Data.Codec.Argonaut.Record as CAR
import Data.Maybe (Maybe)
import Data.Newtype (class Newtype)
import Data.Profunctor (wrapIso)
newtype IntList = IntList { cell ∷ Int, rest ∷ Maybe IntList }
derive instance newtypeLoopyList ∷ Newtype IntList _
codecIntList ∷ CA.JsonCodec IntList
codecIntList =
CA.fix \codec →
wrapIso IntList $
CAR.object "IntList" { cell: CA.int, rest: CAC.maybe codec }
#prismaticCodec Source
prismaticCodec :: forall a b. String -> (a -> Maybe b) -> (b -> a) -> JsonCodec a -> JsonCodec bAdapts an existing codec with a pair of functions to allow a value to be
further refined. If the inner decoder fails an UnexpectedValue error will
be raised for JSON input.
This function is named as such as the pair of functions it accepts
correspond with the preview and review functions of a Prism-style lens.
An example of this would be a codec for Data.String.NonEmpty.NonEmptyString:
nonEmptyString ∷ CA.JsonCodec NES.NonEmptyString
nonEmptyString = CA.prismaticCodec "NonEmptyString" NES.fromString NES.toString CA.string
Another example might be to handle a mapping from a small sum type to strings:
data Direction = North | South | West | East
directionCodec :: JsonCodec Direction
directionCodec = CA.prismaticCodec "Direction" dec enc string
where
dec = case _ of
"N" -> Just North
"S" -> Just South
"W" -> Just West
"E" -> Just East
_ -> Nothing
enc = case _ of
North -> "N"
South -> "S"
West -> "W"
East -> "E"
Although for this latter case there are some other options too, in the form
of Data.Codec.Argonaut.Generic.nullarySum and Data.Codec.Argonaut.Sum.enumSum.
Re-exports from Data.Codec
#Codec Source
#identity Source
identity :: forall m a. Applicative m => Codec m a a a a#(~) Source
Operator alias for Data.Profunctor.lcmap (left-associative / precedence 5)
Codec is defined as a Profunctor so that lcmap can be used to target
specific fields when defining a codec for a product type. This operator
is a convenience for that:
tupleCodec =
Tuple
<$> fst ~ fstCodec
<*> snd ~ sndCodec