NorfairKing / autodocodec

self(auto)- documenting encoders and decoders

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Documentation on how to use type fields

NorfairKing opened this issue · comments

Using a non-monadic parser means you cannot case-match on a field to determine what to parse next.
BUT we can still use type fields like this:

data NSCheck = NSCheck
  { nsCheckDomain :: !Domain,
    nsCheckAddresses :: ![Domain]
  }
  deriving stock (Show, Eq, Generic)
  deriving (FromJSON, ToJSON) via (Autodocodec NSCheck)

instance Validity NSCheck

instance HasCodec NSCheck where
  codec =
    object "NSCheck" $
      typeField "ns" NSCheck
        <*> domainField .= nsCheckDomain
        <*> singleOrListFieldWith "value" "values" domainCodec "domains" .= nsCheckAddresses

typeField :: Text -> a -> ObjectCodec b a
typeField typeName a =
  a <$ requiredFieldWith' "type" (literalTextCodec typeName) .= const typeName

This could be documented better.

PR welcome

I do not understand this yet. So, typeField parses to NSCheck as long as type: "ns". But how can I make this parse to a different type when type contains a different value? If this is not possible, I do not get the purpose of typeField. Or is it just about ignoring the type field?

Is there any other workaround, e.g. defining separate objects for each type and manually handle the case if multiple types are specified at the same time?

type: 
  type1: value1
  type2: value2

where only type1 or type2 may be specified but not both at the same time.