@@ -16,6 +16,7 @@ import Data.Functor.Classes
16import Data.HashMap.Strict as H
16import Data.HashMap.Strict as H
17import Data.Kind
17import Data.Kind
18import Data.Maybe
18import Data.Maybe
19+import Data.Schematic.Instances
19import Data.Schematic.Utils
20import Data.Schematic.Utils
20import Data.Scientific
21import Data.Scientific
21import Data.Singletons.Decide
22import Data.Singletons.Decide
@@ -26,7 +27,9 @@ import Data.Text as T
26import Data.Vector as V
27import Data.Vector as V
27import Data.Vinyl hiding (Dict)
28import Data.Vinyl hiding (Dict)
28import Data.Vinyl.Functor
29import Data.Vinyl.Functor
30+import Data.Vinyl.TypeLevel hiding (Nat)
29import GHC.Generics (Generic)
31import GHC.Generics (Generic)
30import Test.SmallCheck.Series
33import Test.SmallCheck.Series
31import Text.Show.Deriving (deriveShow1)
34import Text.Show.Deriving (deriveShow1)
@@ -98,10 +101,10 @@ data Schema
98 deriving (Generic)
101 deriving (Generic)
100data instance Sing (schema :: Schema) where
103data instance Sing (schema :: Schema) where
101− SSchemaText :: Sing tcs -> Sing (SchemaText tcs)
104+ SSchemaText :: Known (Sing tcs) => Sing tcs -> Sing (SchemaText tcs)
102− SSchemaNumber :: Sing ncs -> Sing (SchemaNumber ncs)
105+ SSchemaNumber :: Known (Sing ncs) => Sing ncs -> Sing (SchemaNumber ncs)
103− SSchemaArray :: Sing acs -> Sing schema -> Sing (SchemaArray acs schema)
106+ SSchemaArray :: (Known (Sing acs), Known (Sing schema)) => Sing acs -> Sing schema -> Sing (SchemaArray acs schema)
104− SSchemaObject :: Sing fields -> Sing (SchemaObject fields)
107+ SSchemaObject :: Known (Sing fields) => Sing fields -> Sing (SchemaObject fields)
105 SSchemaNull :: Sing SchemaNull
108 SSchemaNull :: Sing SchemaNull
107instance Known (Sing sl) => Known (Sing (SchemaText sl)) where
110instance Known (Sing sl) => Known (Sing (SchemaText sl)) where
@@ -124,6 +127,12 @@ instance Eq (Sing (SchemaObject cs)) where a == b = True
124data FieldRepr :: (Symbol, Schema) -> Type where
127data FieldRepr :: (Symbol, Schema) -> Type where
125 FieldRepr :: KnownSymbol name => JsonRepr schema -> FieldRepr '(name, schema)
128 FieldRepr :: KnownSymbol name => JsonRepr schema -> FieldRepr '(name, schema)
130+type family MapSnd (cs :: [(Symbol, Schema)]) :: [Schema] where
132+ MapSnd ( '(fn, schema) ': as) = schema ': MapSnd as
134+deriving instance Show (JsonRepr schema) => Show (FieldRepr '(name, schema))
127instance Eq (JsonRepr schema) => Eq (FieldRepr '(name, schema)) where
136instance Eq (JsonRepr schema) => Eq (FieldRepr '(name, schema)) where
128 FieldRepr a == FieldRepr b = a == b
137 FieldRepr a == FieldRepr b = a == b
@@ -140,6 +149,39 @@ data JsonRepr :: Schema -> Type where
140 ReprArray :: V.Vector (JsonRepr s) -> JsonRepr (SchemaArray cs s)
149 ReprArray :: V.Vector (JsonRepr s) -> JsonRepr (SchemaArray cs s)
141 ReprObject :: Rec FieldRepr fs -> JsonRepr (SchemaObject fs)
150 ReprObject :: Rec FieldRepr fs -> JsonRepr (SchemaObject fs)
152+instance Show (JsonRepr (SchemaText cs)) where
153+ show (ReprText t) = "ReprText " P.++ show t
155+instance Show (JsonRepr (SchemaNumber cs)) where
156+ show (ReprNumber n) = "ReprNumber " P.++ show n
158+instance Show (JsonRepr SchemaNull) where show _ = "ReprNull"
160+instance Show (JsonRepr s) => Show (JsonRepr (SchemaArray acs s)) where
161+ show (ReprArray v) = "ReprArray " P.++ show v
163+instance RecAll FieldRepr fs Show => Show (JsonRepr (SchemaObject fs)) where
164+ show (ReprObject fs) = "ReprObject " P.++ show fs
166+instance (Monad m, Serial m Text)
167+ => Serial m (JsonRepr (SchemaText cs)) where
168+ series = cons1 ReprText
170+instance (Monad m, Serial m Scientific)
171+ => Serial m (JsonRepr (SchemaNumber cs)) where
172+ series = cons1 ReprNumber
174+instance Monad m => Serial m (JsonRepr SchemaNull) where
175+ series = cons0 ReprNull
177+instance (Serial m (V.Vector (JsonRepr s)))
178+ => Serial m (JsonRepr (SchemaArray cs s)) where
179+ series = cons1 ReprArray
181+instance (Monad m, Serial m (Rec FieldRepr fs))
182+ => Serial m (JsonRepr (SchemaObject fs)) where
183+ series = cons1 ReprObject
143instance Eq (Rec FieldRepr fs) => Eq (JsonRepr (SchemaObject fs)) where
185instance Eq (Rec FieldRepr fs) => Eq (JsonRepr (SchemaObject fs)) where
144 ReprObject a == ReprObject b = a == b
186 ReprObject a == ReprObject b = a == b
@@ -159,27 +201,34 @@ instance Known (Sing schema) => J.FromJSON (JsonRepr schema) where
159 parseJSON value = case known :: Sing schema of
201 parseJSON value = case known :: Sing schema of
160 SSchemaText _ -> withText "String" (pure . ReprText) value
202 SSchemaText _ -> withText "String" (pure . ReprText) value
161 SSchemaNumber _ -> withScientific "Number" (pure . ReprNumber) value
203 SSchemaNumber _ -> withScientific "Number" (pure . ReprNumber) value
204+ SSchemaNull -> case value of
162− SSchemaNull -> pure ReprNull
205+ J.Null -> pure ReprNull
163− SSchemaArray c s -> do
206+ _ -> typeMismatch "Null" value
207+ SSchemaArray c s -> withArray "Array" (fmap ReprArray . traverse parseJSON) value
208+ SSchemaObject fs -> do
165− f :: Sing cs -> Sing s -> V.Vector J.Value -> Parser (JsonRepr (SchemaArray cs s))
166− f _ _ = fmap ReprArray . traverse parseJSON
167− withArray "Array" (f c s) value
168− SSchemaObject fs -> ReprObject <$> withObject "Object" (demoteFields fs) value
172− -> H.HashMap Text J.Value
173− -> Parser (Rec FieldRepr s)
210+ demoteFields :: SList s -> H.HashMap Text J.Value -> Parser (Rec FieldRepr s)
174−demoteFields SNil h
211+ demoteFields SNil h = pure RNil
175− | H.null h = pure RNil
177−demoteFields (SCons (STuple2 (n :: Sing fn) s) tl) h = withKnownSymbol n $ do
212+ demoteFields (SCons (STuple2 (n :: Sing fn) s) tl) h = withKnownSymbol n $ do
178− let fieldName = T.pack $ symbolVal (Proxy @fn)
213+ let fieldName = T.pack $ symbolVal (Proxy @fn)
214+ fieldRepr <- case s of
179− fieldRepr <- case H.lookup fieldName h of
215+ SSchemaText _ -> case H.lookup fieldName h of
180− Just v -> FieldRepr <$> (withSingI s $ parseJSON v)
216+ Just v -> FieldRepr <$> parseJSON v
217+ Nothing -> fail "schematext"
218+ SSchemaNumber _ -> case H.lookup fieldName h of
219+ Just v -> FieldRepr <$> parseJSON v
181− Nothing -> mzero
220+ Nothing -> fail "schemanumber"
221+ SSchemaNull -> case H.lookup fieldName h of
222+ Just v -> FieldRepr <$> parseJSON v
223+ Nothing -> fail "schemanull"
224+ SSchemaArray _ _ -> case H.lookup fieldName h of
225+ Just v -> FieldRepr <$> parseJSON v
226+ Nothing -> fail "schemaarray"
227+ SSchemaObject _ -> case H.lookup fieldName h of
228+ Just v -> FieldRepr <$> parseJSON v
229+ Nothing -> fail "schemaobject"
182− (fieldRepr :&) <$> demoteFields tl h
230+ (fieldRepr :&) <$> demoteFields tl h
231+ ReprObject <$> withObject "Object" (demoteFields fs) value
184instance J.ToJSON (JsonRepr a) where
233instance J.ToJSON (JsonRepr a) where
185 toJSON ReprNull = J.Null
234 toJSON ReprNull = J.Null