0 | module Lana.JSON.Encoder
2 | import Data.List.Elem
3 | import Data.List.Elem.Extra as ElemExtra
4 | import Data.List.Quantifiers
8 | import Data.SortedMap as Map
9 | import Data.Finite as Finite
11 | import Lana.Class as LC
12 | import Lana.Name as LC
13 | import JSON.Encoder as JE
15 | import JSON.Simple.ToJSON
16 | import JSON.Parser as JP
19 | EncodedJSON : Type -> Type
20 | EncodedJSON a = JSON
23 | forgetEncodedJSON : EncodedJSON a -> JSON
24 | forgetEncodedJSON = id
27 | data JEncoder a = MkJEncoder LC.Name (a -> EncodedJSON a)
34 | Functor JEncoder where
35 | map f jenc = assert_total $
idris_crash "todo"
38 | Series = List (Pair String JSON)
41 | encode : JEncoder a -> a -> EncodedJSON a
42 | encode (MkJEncoder name toEncoding) = toEncoding
45 | MyObject: Type -> Type -> Type
46 | MyObject object constructor = (object -> Series)
48 | MyField: Type -> Type -> Type
49 | MyField object constructor = (object -> Series)
51 | mkAdditional: (obj -> Map.SortedMap String a) -> (a -> EncodedJSON a) -> obj -> Series
52 | mkAdditional accessor toEncoding anObj =
54 | l : List (Pair String a)
55 | l = Map.toList (accessor anObj)
56 | fun : List (Pair String a) -> Series
59 | (\(MkPair key value) => the Series [MkPair key (toEncoding value)])
62 | mkUnionNamedFunctor : {fun: Type -> Type} -> Functor fun => {types: List Type} ->
63 | Any Prelude.Basics.id types ->
68 | fun (Any Prelude.Basics.id types)
69 | mkUnionNamedFunctor {types=[]} anyInEmpty g = absurd anyInEmpty
70 | mkUnionNamedFunctor {types=(x :: xs)} anyInXOrXs g =
73 | map (Any.Here . id) $
g {el=x} Elem.Here (the x her)
75 | let xsPrf : fun (Any Prelude.Basics.id xs)
76 | xsPrf = mkUnionNamedFunctor {types=xs} thr $
\iElem, iEl => g (Elem.There iElem) iEl
77 | in map Any.There xsPrf
79 | mkUnionNamed : {types: List Type} ->
80 | Any Prelude.Basics.id types ->
85 | EncodedJSON (Any Prelude.Basics.id types)
86 | mkUnionNamed {types=[]} anyInEmpty g = absurd anyInEmpty
87 | mkUnionNamed {types=(x :: xs)} anyInXOrXs g =
90 | g {el=x} Elem.Here (the x her)
92 | let xsPrf : EncodedJSON (Any Prelude.Basics.id xs)
93 | xsPrf = mkUnionNamed {types=xs} thr $
\iElem, iEl => g (Elem.There iElem) iEl
96 | mkUnionMemberWithIndex : Elem a types ->
97 | (a -> EncodedJSON a) ->
98 | ({elem: Type} -> Elem elem [a] -> elem -> EncodedJSON elem)
99 | mkUnionMemberWithIndex unusedAInTypes aEncoder Data.List.Elem.Here anElem = aEncoder anElem
102 | {left, right: List Type} ->
103 | ({elem: Type} -> Elem elem left -> elem -> EncodedJSON elem) ->
104 | ({elem: Type} -> Elem elem right -> elem -> EncodedJSON elem) ->
105 | ({elem: Type} -> Elem elem (left ++ right) -> elem -> EncodedJSON elem)
106 | mkUnionCombine encodeLeft encodeRight elemLeftRight elem =
107 | case ElemExtra.elemAppLorR left right elemLeftRight of
108 | Left inLeft => encodeLeft inLeft elem
109 | Right inRight => encodeRight inRight elem
112 | implementation LC.Lana JEncoder where
117 | AdditionalFields object constructor = (object -> Series)
119 | UnionMembers allTypes handledTypes
120 | = {elem: Type} -> Elem elem handledTypes -> elem -> EncodedJSON elem
122 | schemaName (MkJEncoder name toEncoding) =
126 | MkJEncoder (LC.unqualifiedName "double") toJSON
129 | MkJEncoder (LC.unqualifiedName "text") toJSON
132 | MkJEncoder (LC.unqualifiedName "boolean") toJSON
136 | (LC.unqualifiedName "null")
137 | (\LC.MkNull => JNull)
139 | array (MkJEncoder name itemToEncoding) =
141 | (LC.annotateName name "array")
142 | (JArray . map itemToEncoding)
144 | nullable (MkJEncoder name toEncoding) =
145 | MkJEncoder (LC.annotateName name "nullable") $
\mbValue =>
147 | Left LC.MkNull => JNull
148 | Right value => toEncoding value
150 | required key accessor (MkJEncoder unusedName toEncoding) =
152 | [MkPair key (toEncoding (accessor object))]
154 | optional key accessor (MkJEncoder unusedName toEncoding) =
156 | case accessor object of
158 | [MkPair key (toEncoding value)]
162 | additionalFields accessor (MkJEncoder unusedName toEncoding) =
163 | mkAdditional accessor toEncoding
165 | mapField unusedF encoder =
168 | constructor unusedF =
171 | field mkStart mkNext =
173 | mkStart object <+> mkNext object
175 | additional mkStart mkRest =
177 | mkStart object <+> mkRest object
179 | objectNamed name toSeries =
180 | MkJEncoder name (JE.object . toSeries)
182 | finiteNamed name toText =
183 | MkJEncoder name (JE.string . toText)
185 | validateNamed name uncheck check (MkJEncoder unvalidatedName toEncoding) =
186 | MkJEncoder name (toEncoding . uncheck)
188 | unionNamed {types} name builder =
190 | f : Union types -> EncodedJSON (Union types)
191 | f = flip (mkUnionNamed {types}) builder
198 | g : Union types -> JEncoder (Union types)
199 | g a = mkUnionNamedFunctor {fun=JEncoder} {types} a $
200 | \elPrf, el => MkJEncoder name $
201 | \_ => builder elPrf el
203 | in MkJEncoder name f
206 | unionMemberWithIndex index encoder =
211 | MkJEncoder name toEncoding = encoder
213 | mkUnionMemberWithIndex index toEncoding
215 | unionCombine = mkUnionCombine
217 | jsonString (MkJEncoder name toEncoding) =