@@ -19,22 +19,33 @@ module Data.Schematic
19 , isDecodingError
19 , isDecodingError
20 , isValidationError
20 , isValidationError
21 , ParseResult(..)
21 , ParseResult(..)
27+import Control.Applicative
24−import Control.Monad.Validation
28+import Control.Monad.Validation
25−import Data.Aeson as J
29+import Data.Aeson as J
26−import Data.Aeson.Types as J
30+import Data.Aeson.Types as J
27−import Data.ByteString.Lazy as BL
31+import Data.ByteString.Lazy as BL
28−import Data.Functor.Identity
32+import Data.Functor.Identity
29−import Data.Schematic.JsonSchema
33+import Data.Kind
30−import Data.Schematic.Helpers
34+import Data.Schematic.Helpers
35+import Data.Schematic.JsonSchema
31−import Data.Schematic.Lens
36+import Data.Schematic.Lens
32−import Data.Schematic.Migration
37+import Data.Schematic.Migration
33−import Data.Schematic.Schema
38+import Data.Schematic.Schema
34−import Data.Schematic.Utils
39+import Data.Schematic.Utils
35−import Data.Schematic.Validation
40+import Data.Schematic.Validation
41+import Data.Scientific
36−import Data.Singletons.Prelude
42+import Data.Singletons.Prelude
43+import Data.Singletons.TypeLits
37−import Data.Text as T
45+import Data.Text as T
47+import qualified Data.Vector as V
40parseAndValidateJson
51parseAndValidateJson
@@ -125,3 +136,65 @@ decodeAndValidateVersionedWithPureMList
125 -> ParseResult (JsonRepr (Head (MapSnd (AllVersions versioned))))
136 -> ParseResult (JsonRepr (Head (MapSnd (AllVersions versioned))))
126decodeAndValidateVersionedWithPureMList a b c =
137decodeAndValidateVersionedWithPureMList a b c =
127 runIdentity $ decodeAndValidateVersionedWithMList a b c
138 runIdentity $ decodeAndValidateVersionedWithMList a b c
140+-- convenience helpers
143+ = forall b. FSubset (FieldsOf a) b (FImage (FieldsOf a) b)
144+ => Tagged (FieldsOf a) (Rec FieldRepr b)
145+ -> JsonRepr ('SchemaObject (FieldsOf a))
147+withRepr :: Constructor a
148+withRepr = ReprObject . unTagged . fmap fcast
152+ => m (FieldRepr fns)
153+ -> m (Rec FieldRepr b)
154+ -> m (Rec FieldRepr (fns ': b))
159+class Representable s where
161+ construct :: Sing fn -> Proxy s -> Repr s -> FieldRepr '(fn, s)
163+instance SingI so => Representable ('SchemaObject so) where
164+ type Repr ('SchemaObject so) = Rec FieldRepr so
165+ construct sfn _ o = withKnownSymbol sfn $ FieldRepr $ ReprObject o
167+instance (SingI cs, SingI sa) => Representable ('SchemaArray cs sa) where
168+ type Repr ('SchemaArray cs sa) = V.Vector (JsonRepr sa)
169+ construct sfn _ a = withKnownSymbol sfn $ FieldRepr $ ReprArray a
171+instance SingI cs => Representable ('SchemaText cs) where
172+ type Repr ('SchemaText cs) = Text
173+ construct sfn _ t = withKnownSymbol sfn $ FieldRepr $ ReprText t
175+instance SingI cs => Representable ('SchemaNumber cs) where
176+ type Repr ('SchemaNumber cs) = Scientific
177+ construct sfn _ n = withKnownSymbol sfn $ FieldRepr $ ReprNumber n
179+instance Representable 'SchemaBoolean where
180+ type Repr 'SchemaBoolean = Bool
181+ construct sfn _ b = withKnownSymbol sfn $ FieldRepr $ ReprBoolean b
183+instance SingI so => Representable ('SchemaOptional so) where
184+ type Repr ('SchemaOptional so) = Maybe (JsonRepr so)
185+ construct sfn _ o = withKnownSymbol sfn $ FieldRepr $ ReprOptional o
187+instance SingI (h ': tl) => Representable ('SchemaUnion (h ': tl)) where
188+ type Repr ('SchemaUnion (h ': tl)) = Union JsonRepr (h ': tl)
189+ construct sfn _ u = withKnownSymbol sfn $ FieldRepr $ ReprUnion u
191+type family FieldsOf (s :: Schema) :: [(Symbol, Schema)] where
192+ FieldsOf ('SchemaObject fs) = fs
194+type FieldConstructor fn =
195+ forall fs. (Representable (ByField fn fs (FIndex fn fs)))
196+ => Repr (ByField fn fs (FIndex fn fs))
197+ -> Tagged fs (FieldRepr '(fn, (ByField fn fs (FIndex fn fs))))
199+field :: forall fn. KnownSymbol fn => FieldConstructor fn
200+field = Tagged . construct (sing :: Sing fn) Proxy