Add untagged and generics derivations#6
Conversation
d722c61 to
8564f0c
Compare
8564f0c to
051ffc1
Compare
| -- This is due to a breaking change introduced in insert-ordered-containers-0.3.0 | ||
| -- More info are available here: | ||
| -- https://github.com/biocad/openapi3/pull/119 | ||
| -- https://github.com/erikd/insert-ordered-containers/pull/8 | ||
| -- | ||
| #if !MIN_VERSION_openapi3(3,2,5) | ||
| import Data.HashMap.Strict.InsOrd qualified as HMSI | ||
| #else | ||
| import Data.HashMap.Strict.InsOrd.Compat qualified as HMSI | ||
| #endif |
There was a problem hiding this comment.
Does this fix our ordering issues in OpenAPI? 🧐 @svobot
There was a problem hiding this comment.
I do not think this is going to fix the ordering. The conditional here is just for building the library with the new version of the openapi3 library.
Here is the background: there was an issue in insert-ordered-containers with the FromJSON and ToJSON instances (see erikd/insert-ordered-containers#7). This problem should have been resolved here: erikd/insert-ordered-containers#8. However, this change made the swagger2 and openapi3 packages incompatible with the latest release of insert-ordered-containers.
One of the contributors to the swagger2 library decided to fix the problem by copying the old version of one of the insert-ordered-containers modules and using it when building the library with insert-ordered-containers > v0.3.0 (see GetShopTV/swagger2#262). The author of openapi3 did the exact same thing (see biocad/openapi3#119).
I think the strategy was to preserve the legacy behavior, leaving no option to use the new version of the insert-ordered-containers library.
This also causes issues in other packages:
servant-swaggernow strictly depends oninsert-ordered-containers> v0.3.0, meaning it will use the internalCompatmodule (servant-swagger.cabal#L78).servant-openapi3currently does not build withinsert-ordered-containers> v0.3.0 (servant-openapi3.cabal#L88).
As a result, if your project depends on both of those packages, you cannot actually bump either of them, and you are stuck with insert-ordered-containers < v0.3.0.
What we really need to do is propose that the authors of swagger2 and openapi3 add a build flag to use either the new version of insert-ordered-containers (>= v0.3.0) or the legacy version of insert-ordered-containers (< v0.3.0) and the Compat modules.
There was a problem hiding this comment.
Does this fix our ordering issues in OpenAPI? 🧐 @svobot
We should try to build openapi3 with the new version of insert-ordered-containers without the Compat module.
Simplify API: replace
GTaggedJSONwithGTagged/GUntagged+ addGeneric1supportMotivation
The previous API exposed a single newtype
GTaggedJSONparameterised by an options type that had to embed aMaybe Symbolto control whether tagging was enabled. This meant users needed two separateHasTaggedOptionsinstances (one for'Just tagKeyand one for'Nothing) and the options type had to carry the tag key at the type level. Internally, this relied on thesingletonlibrary to reflect theMaybe Symbolat runtime, adding an unwanted dependency. An initial implementation by @crtschin first explored moving the tag key to the type level and addingGeneric1support, usingsingletonto bridge the type- and value-level representations; this PR builds on that work while removing thesingletondependency entirely.Changes
New newtypes replacing
GTaggedJSON:GTagged (key :: Symbol) opts a— derive tagged (discriminated union) JSON instances; the tag field name is now a type-levelSymbolon the newtype itself, not baked into the options typeGUntagged opts a— derive untagged (plain product/sum) JSON instancesGTagged1 (key :: Symbol) opts f a/GUntagged1 opts f a—Generic1-based variants for parameterised types (f a), enabling derivation on types with a type parameterAPI simplification:
Maybe Symbolin their options type;HasTaggedOptionsnow only needs a single instance per options typederiving … viaclause:via GTagged "my_tag" MyOpts MyTypetagKeyfield has been removed fromTaggedOptions; tagging vs. non-tagging is now expressed entirely through which newtype you pickunwrapreplaces the old.unGTaggedJSONaccessorNew
Generic1support (genericLift*functions):genericLiftToJSON,genericLiftToEncoding,genericLiftToPairs,genericLiftToSeries,genericLiftParseJSON,genericLiftDeclareNamedSchema— counterparts to the existinggeneric*functions, operating viaGeneric1Other:
singletonlibrary dependencyinsert-ordered-containers0.3.0 breaking change (affectsopenapi3users on newer versions)Generic1round-trip and schema tests