@@ -3,7 +3,6 @@ module Data.Schematic.Validation where
3import Control.Monad
3import Control.Monad
4import Control.Monad.Validation
4import Control.Monad.Validation
5import Data.Aeson
5import Data.Aeson
6−import Data.Aeson.Internal
7import Data.Aeson.Types
6import Data.Aeson.Types
8import Data.Foldable
7import Data.Foldable
9import Data.Functor.Identity
8import Data.Functor.Identity
@@ -50,51 +49,51 @@ isValidationError (ValidationError _) = True
50isValidationError _ = False
49isValidationError _ = False
52validateTextConstraint
51validateTextConstraint
53− :: JSONPathText
52+ :: JSONPath
55 -> Sing (tcs :: TextConstraint)
54 -> Sing (tcs :: TextConstraint)
56 -> Validation ()
55 -> Validation ()
57−validateTextConstraint (JSONPathText path) t = \case
56+validateTextConstraint (JSONPath path) t = \case
58 STEq n -> do
57 STEq n -> do
60 nlen = withKnownNat n $ natVal n
59 nlen = withKnownNat n $ natVal n
61 predicate = nlen == (fromIntegral $ T.length t)
60 predicate = nlen == (fromIntegral $ T.length t)
62− errMsg = "length should be == " <> T.pack (show nlen)
61+ errMsg = "length of " <> path <> " should be == " <> T.pack (show nlen)
63 warn = vWarning $ mmSingleton path (pure errMsg)
62 warn = vWarning $ mmSingleton path (pure errMsg)
64 unless predicate warn
63 unless predicate warn
65 STLt n -> do
64 STLt n -> do
67 nlen = withKnownNat n $ natVal n
66 nlen = withKnownNat n $ natVal n
68 predicate = nlen > (fromIntegral $ T.length t)
67 predicate = nlen > (fromIntegral $ T.length t)
69− errMsg = "length should be < " <> T.pack (show nlen)
68+ errMsg = "length of " <> path <> " should be < " <> T.pack (show nlen)
70 warn = vWarning $ mmSingleton path (pure errMsg)
69 warn = vWarning $ mmSingleton path (pure errMsg)
71 unless predicate warn
70 unless predicate warn
72 STLe n -> do
71 STLe n -> do
74 nlen = withKnownNat n $ natVal n
73 nlen = withKnownNat n $ natVal n
75 predicate = nlen >= (fromIntegral $ T.length t)
74 predicate = nlen >= (fromIntegral $ T.length t)
76− errMsg = "length should be <= " <> T.pack (show nlen)
75+ errMsg = "length of " <> path <> " should be <= " <> T.pack (show nlen)
77 warn = vWarning $ mmSingleton path (pure errMsg)
76 warn = vWarning $ mmSingleton path (pure errMsg)
78 unless predicate warn
77 unless predicate warn
79 STGt n -> do
78 STGt n -> do
81 nlen = withKnownNat n $ natVal n
80 nlen = withKnownNat n $ natVal n
82 predicate = nlen < (fromIntegral $ T.length t)
81 predicate = nlen < (fromIntegral $ T.length t)
83− errMsg = "length should be > " <> T.pack (show nlen)
82+ errMsg = "length of " <> path <> " should be > " <> T.pack (show nlen)
84 warn = vWarning $ mmSingleton path (pure errMsg)
83 warn = vWarning $ mmSingleton path (pure errMsg)
85 unless predicate warn
84 unless predicate warn
86 STGe n -> do
85 STGe n -> do
88 nlen = withKnownNat n $ natVal n
87 nlen = withKnownNat n $ natVal n
89 predicate = nlen <= (fromIntegral $ T.length t)
88 predicate = nlen <= (fromIntegral $ T.length t)
90− errMsg = "length should be >= " <> T.pack (show nlen)
89+ errMsg = "length of " <> path <> " should be >= " <> T.pack (show nlen)
91 warn = vWarning $ mmSingleton path (pure errMsg)
90 warn = vWarning $ mmSingleton path (pure errMsg)
92 unless predicate warn
91 unless predicate warn
93 STRegex r -> do
92 STRegex r -> do
95 regex = withKnownSymbol r $ fromSing r
94 regex = withKnownSymbol r $ fromSing r
96 predicate = matchTest (makeRegex (T.unpack regex) :: Regex) (T.unpack t)
95 predicate = matchTest (makeRegex (T.unpack regex) :: Regex) (T.unpack t)
97− errMsg = "must match " <> regex
96+ errMsg = path <> " must match " <> regex
98 warn = vWarning $ mmSingleton path (pure errMsg)
97 warn = vWarning $ mmSingleton path (pure errMsg)
99 unless predicate warn
98 unless predicate warn
100 STEnum ss -> do
99 STEnum ss -> do
@@ -102,97 +101,69 @@ validateTextConstraint (JSONPathText path) t = \case
102 matching :: Sing (s :: [Symbol]) -> Bool
101 matching :: Sing (s :: [Symbol]) -> Bool
103 matching SNil = False
102 matching SNil = False
104 matching (SCons s@SSym fs) = T.pack (symbolVal s) == t || matching fs
103 matching (SCons s@SSym fs) = T.pack (symbolVal s) == t || matching fs
105− errMsg = "must be one of " <> T.pack (show (fromSing ss))
104+ errMsg = path <> " must be one of " <> T.pack (show (fromSing ss))
106 warn = vWarning $ mmSingleton path (pure errMsg)
105 warn = vWarning $ mmSingleton path (pure errMsg)
107 unless (matching ss) warn
106 unless (matching ss) warn
109validateNumberConstraint
108validateNumberConstraint
110− :: JSONPathText
109+ :: JSONPath
111 -> Scientific
110 -> Scientific
112 -> Sing (tcs :: NumberConstraint)
111 -> Sing (tcs :: NumberConstraint)
113 -> Validation ()
112 -> Validation ()
114−validateNumberConstraint (JSONPathText path) num = \case
113+validateNumberConstraint (JSONPath path) num = \case
115 SNEq n -> do
114 SNEq n -> do
117 nlen = withKnownNat n $ natVal n
116 nlen = withKnownNat n $ natVal n
118 predicate = fromIntegral nlen == num
117 predicate = fromIntegral nlen == num
119− errMsg = "should be == " <> T.pack (show nlen)
118+ errMsg = path <> " should be == " <> T.pack (show nlen)
120 warn = vWarning $ mmSingleton path (pure errMsg)
119 warn = vWarning $ mmSingleton path (pure errMsg)
121 unless predicate warn
120 unless predicate warn
122 SNGt n -> do
121 SNGt n -> do
124 nlen = withKnownNat n $ natVal n
123 nlen = withKnownNat n $ natVal n
125 predicate = num > fromIntegral nlen
124 predicate = num > fromIntegral nlen
126− errMsg = "should be > " <> T.pack (show nlen)
125+ errMsg = path <> " should be > " <> T.pack (show nlen)
127 warn = vWarning $ mmSingleton path (pure errMsg)
126 warn = vWarning $ mmSingleton path (pure errMsg)
128 unless predicate warn
127 unless predicate warn
129 SNGe n -> do
128 SNGe n -> do
131 nlen = withKnownNat n $ natVal n
130 nlen = withKnownNat n $ natVal n
132 predicate = num >= fromIntegral nlen
131 predicate = num >= fromIntegral nlen
133− errMsg = "should be >= " <> T.pack (show nlen)
132+ errMsg = path <> " should be >= " <> T.pack (show nlen)
134 warn = vWarning $ mmSingleton path (pure errMsg)
133 warn = vWarning $ mmSingleton path (pure errMsg)
135 unless predicate warn
134 unless predicate warn
136 SNLt n -> do
135 SNLt n -> do
138 nlen = withKnownNat n $ natVal n
137 nlen = withKnownNat n $ natVal n
139 predicate = num < fromIntegral nlen
138 predicate = num < fromIntegral nlen
140− errMsg = "should be < " <> T.pack (show nlen)
139+ errMsg = path <> " should be < " <> T.pack (show nlen)
141 warn = vWarning $ mmSingleton path (pure errMsg)
140 warn = vWarning $ mmSingleton path (pure errMsg)
142 unless predicate warn
141 unless predicate warn
143 SNLe n -> do
142 SNLe n -> do
145 nlen = withKnownNat n $ natVal n
144 nlen = withKnownNat n $ natVal n
146 predicate = num <= fromIntegral nlen
145 predicate = num <= fromIntegral nlen
147− errMsg = "should be <= " <> T.pack (show nlen)
146+ errMsg = path <> " should be <= " <> T.pack (show nlen)
148 warn = vWarning $ mmSingleton path (pure errMsg)
147 warn = vWarning $ mmSingleton path (pure errMsg)
149 unless predicate warn
148 unless predicate warn
151validateArrayConstraint
150validateArrayConstraint
152− :: JSONPathText
151+ :: JSONPath
153 -> V.Vector a
152 -> V.Vector a
154 -> Sing (tcs :: ArrayConstraint)
153 -> Sing (tcs :: ArrayConstraint)
155 -> Validation ()
154 -> Validation ()
156−validateArrayConstraint (JSONPathText path) v = \case
155+validateArrayConstraint (JSONPath path) v = \case
157 SAEq n -> do
156 SAEq n -> do
159 nlen = withKnownNat n $ natVal n
158 nlen = withKnownNat n $ natVal n
160 predicate = nlen == fromIntegral (V.length v)
159 predicate = nlen == fromIntegral (V.length v)
161− errMsg = "length should be == " <> T.pack (show nlen)
160+ errMsg = "length of " <> path <> " should be == " <> T.pack (show nlen)
162− warn = vWarning $ mmSingleton path (pure errMsg)
163− unless predicate warn
166− nlen = withKnownNat n $ natVal n
167− predicate = fromIntegral (V.length v) > nlen
168− errMsg = "length should be > " <> T.pack (show nlen)
169− warn = vWarning $ mmSingleton path (pure errMsg)
170− unless predicate warn
173− nlen = withKnownNat n $ natVal n
174− predicate = fromIntegral (V.length v) >= nlen
175− errMsg = "length should be >= " <> T.pack (show nlen)
176− warn = vWarning $ mmSingleton path (pure errMsg)
177− unless predicate warn
180− nlen = withKnownNat n $ natVal n
181− predicate = fromIntegral (V.length v) < nlen
182− errMsg = "length should be < " <> T.pack (show nlen)
183− warn = vWarning $ mmSingleton path (pure errMsg)
184− unless predicate warn
187− nlen = withKnownNat n $ natVal n
188− predicate = fromIntegral (V.length v) <= nlen
189− errMsg = "length should be <= " <> T.pack (show nlen)
190 warn = vWarning $ mmSingleton path (pure errMsg)
161 warn = vWarning $ mmSingleton path (pure errMsg)
191 unless predicate warn
162 unless predicate warn
193validateJsonRepr
164validateJsonRepr
194 :: Sing schema
165 :: Sing schema
195− -> JSONPath
166+ -> [DemotedPathSegment]
196 -> JsonRepr schema
167 -> JsonRepr schema
197 -> Validation ()
168 -> Validation ()
198validateJsonRepr sschema dpath jr = case jr of
169validateJsonRepr sschema dpath jr = case jr of
@@ -226,7 +197,7 @@ validateJsonRepr sschema dpath jr = case jr of
226 process cs
197 process cs
227 process acs
198 process acs
228 for_ (V.indexed v) $ \(ix, jr') -> do
199 for_ (V.indexed v) $ \(ix, jr') -> do
229− let newPath = dpath <> pure (Index $ fromIntegral ix)
200+ let newPath = dpath <> pure (DIx $ fromIntegral ix)
230 validateJsonRepr s newPath jr'
201 validateJsonRepr s newPath jr'
231 ReprOptional d -> case sschema of
202 ReprOptional d -> case sschema of
232 SSchemaOptional ss -> case d of
203 SSchemaOptional ss -> case d of
@@ -238,7 +209,7 @@ validateJsonRepr sschema dpath jr = case jr of
238 go :: Rec FieldRepr (ts :: [(Symbol, Schema)] ) -> Validation ()
209 go :: Rec FieldRepr (ts :: [(Symbol, Schema)] ) -> Validation ()
239 go RNil = pure ()
210 go RNil = pure ()
240 go (f@(FieldRepr d) :& ftl) = do
211 go (f@(FieldRepr d) :& ftl) = do
241− let newPath = dpath <> [Key (knownFieldName f)]
212+ let newPath = dpath <> [DKey (knownFieldName f)]
242 validateJsonRepr (knownFieldSchema f) newPath d
213 validateJsonRepr (knownFieldSchema f) newPath d
244 ReprUnion _ -> pure () -- FIXME
215 ReprUnion _ -> pure () -- FIXME
@@ -250,7 +221,7 @@ validateJsonRepr sschema dpath jr = case jr of
250 -- fail "impossible to produce subUnion, please report this as a bug"
221 -- fail "impossible to produce subUnion, please report this as a bug"
251 -- Just x -> do
222 -- Just x -> do
253− -- JSONPathText path = demotedPathToText dpath
224+ -- JSONPath path = demotedPathToText dpath
254 -- case stl of
225 -- case stl of
255 -- SNil -> void $ vWarning $ mmSingleton path
226 -- SNil -> void $ vWarning $ mmSingleton path
256 -- $ pure "union handling error, please report this as bug"
227 -- $ pure "union handling error, please report this as bug"