Readme and documentation efforts

This commit is contained in:
Tom Sydney Kerckhove 2021-10-30 12:03:59 +02:00
parent ac755572fb
commit 1f16d4ccb6
2 changed files with 77 additions and 11 deletions

View File

@ -2,9 +2,29 @@
Autodocodec is short for "self(auto)- documenting encoder and decoder".
In short:
You write one (1) instance, of the 'Codec' type-class, for your type, and you get:
* [A 'ToJSON' instance from 'aeson'](https://hackage.haskell.org/package/aeson-2.0.1.0/docs/Data-Aeson-Types.html#t:ToJSON)
* [A 'FromJSON' instance from 'aeson'](https://hackage.haskell.org/package/aeson-2.0.1.0/docs/Data-Aeson-Types.html#t:FromJSON)
* [A json schema](http://json-schema.org/)
* A human-readable yaml schema
* Hopefully soon also: A swagger schema
* Hopefully soon also: An openapi schema
* Potentially also: bson instances for mongodb
## DISCLAIMER: This is a work in progress.
This is not ready for production, it is not in use in any of my own projects yet, I do not recommend using it yet.
* Documentation is not complete.
* Some pieces of the implementation
## Goals:
* Correct-by-construction encoding and decoding, without generating code.
* Generate automatically-correct documentation from code.
* Fun but not important: Be able to provide instances without depending on aeson and/or yaml.
* Would be nice: support for recursive types.

View File

@ -42,16 +42,20 @@ data Codec input output where
BoolCodec ::
-- |
Codec Bool Bool
-- | A String value
-- | Encode 'Text' to a @string@ value, and decode a @string@ value as a 'Text'.
--
-- This is named after the primitive type "String" in json, not after the haskell type string.
StringCodec ::
-- |
Codec Text Text
-- | Encode 'Scientific' to a @number@ value, and decode a @number@ value as a 'Scientific'.
--
-- NOTE: We use 'Scientific' here because that is what aeson uses.
-- TODO: Can we do this without 'Scientific'? It has too many footguns.
NumberCodec ::
-- |
Codec Scientific Scientific -- TODO can we do this without scientific?
-- TODO use a vector here because that's what aeson uses.
Codec Scientific Scientific
-- TODO use a vector here because that's what aeson uses.
ArrayCodec ::
-- |
!(Maybe Text) ->
@ -217,20 +221,62 @@ maybeCodec = bimapCodec f g . EitherCodec nullCodec
instance Functor (Codec input) where
fmap = fmapCodec
-- | An autodocodec for objects.
-- See 'Codec' for more information about the two type parameters.
data ObjectCodec input output where
RequiredKeyCodec :: Text -> Codec input output -> ObjectCodec input output
OptionalKeyCodec :: Text -> Codec input output -> ObjectCodec (Maybe input) (Maybe output)
PureObjectCodec :: output -> ObjectCodec input output
BimapObjectCodec :: (oldOutput -> newOutput) -> (newInput -> oldInput) -> ObjectCodec oldInput oldOutput -> ObjectCodec newInput newOutput
ApObjectCodec :: ObjectCodec input (output -> newOutput) -> ObjectCodec input output -> ObjectCodec input newOutput
RequiredKeyCodec ::
-- |
Text ->
-- |
Codec input output ->
-- |
ObjectCodec input output
OptionalKeyCodec ::
-- |
Text ->
-- |
Codec input output ->
-- |
ObjectCodec (Maybe input) (Maybe output)
PureObjectCodec ::
-- |
output ->
-- |
ObjectCodec input output
BimapObjectCodec ::
-- |
(oldOutput -> newOutput) ->
-- |
(newInput -> oldInput) ->
-- |
ObjectCodec oldInput oldOutput ->
-- |
ObjectCodec newInput newOutput
ApObjectCodec ::
-- |
ObjectCodec input (output -> newOutput) ->
-- |
ObjectCodec input output ->
-- |
ObjectCodec input newOutput
fmapObjectCodec :: (oldOutput -> newOutput) -> ObjectCodec input oldOutput -> ObjectCodec input newOutput
fmapObjectCodec ::
(oldOutput -> newOutput) ->
ObjectCodec input oldOutput ->
ObjectCodec input newOutput
fmapObjectCodec f = BimapObjectCodec f id
comapObjectCodec :: (newInput -> oldInput) -> ObjectCodec oldInput output -> ObjectCodec newInput output
comapObjectCodec ::
(newInput -> oldInput) ->
ObjectCodec oldInput output ->
ObjectCodec newInput output
comapObjectCodec g = BimapObjectCodec id g
bimapObjectCodec :: (oldOutput -> newOutput) -> (newInput -> oldInput) -> ObjectCodec oldInput oldOutput -> ObjectCodec newInput newOutput
bimapObjectCodec ::
(oldOutput -> newOutput) ->
(newInput -> oldInput) ->
ObjectCodec oldInput oldOutput ->
ObjectCodec newInput newOutput
bimapObjectCodec = BimapObjectCodec
instance Functor (ObjectCodec input) where