2b0eb969

By: Tom Sydney Kerckhove <syd@cs-syd.eu>

Add autodocodec-http-api-data for form-urlencoded data

A type with a HasObjectCodec instance could not be posted as
application/x-www-form-urlencoded without a second, hand-written
description of its fields. http-api-data's own generic derivation is no
substitute: it derives names from Haskell record fields via a label
modifier, so it would be a third independent spelling of the same field
names rather than a shared one.

This is autodocodec-servant-multipart's interpreter retargeted at
Web.FormUrlEncoded.Form, which is likewise a flat map from text keys to
text values. A Form's HashMap Text [Text] models repeated keys natively,
so ArrayOfCodec fits it better than it fits multipart's flat list of
inputs, and unlike the multipart spec every corpus type round-trips,
Example included.

Three places where copying multipart verbatim would have been wrong:

* Form derives Semigroup from HashMap, whose union is left-biased and so
  would silently drop the second form's values under a shared key, where
  multipart's mappend concatenates. Hence unionForm.

* Booleans encode lower case, to match toUrlPiece @Bool and the HTML form
  convention, so that a value survives http-api-data's own parser. The
  decoder still accepts either spelling.

* A field is absent exactly when its key is absent, which is lossless.
  dropEmptyFormValues is exported separately, for callers who need a
  shell's unset variable to read as absence rather than as the empty
  string.

Suite timing

Time to Start Worker time Duration Time to finish Idle
Config 13s 0s 0s 14s 13s
Eval 14s 1m14s 1m14s 1m29s 0s
Build 1m25s 1m43s 32m30s 33m56s 30m43s
Suite 13s 2m58s 33m42s 33m56s 30m57s

Timeline

0s20s40s1m1m20s32m20s32m40s33m33m20s33m40s