1module Data.Schematic.Validation where
4import Control.Monad.Validation
6import Data.Functor.Identity
8import Data.Schematic.Path
9import Data.Schematic.Schema
10import Data.Schematic.Utils ()
12import Data.Singletons.Prelude
13import Data.Singletons.TypeLits
15import Data.Vector as V
21type Validation a = ValidationT ErrorMap Identity a
23type ErrorMap = MonoidMap Text [Text]
27 | DecodingError Text -- static
28 | ValidationError ErrorMap -- runtime
29 deriving (Show, Eq, Functor)
31isValid :: ParseResult a -> Bool
32isValid (Valid _) = True
35isDecodingError :: ParseResult a -> Bool
36isDecodingError (DecodingError _) = True
37isDecodingError _ = False
39isValidationError :: ParseResult a -> Bool
40isValidationError (ValidationError _) = True
41isValidationError _ = False
46 -> Sing (tcs :: TextConstraint)
48validateTextConstraint (JSONPath path) t = \case
52 predicate = nlen == (fromIntegral $ T.length t)
53 errMsg = "length of " <> path <> " should be == " <> T.pack (show nlen)
54 warn = vWarning $ mmSingleton path (pure errMsg)
59 predicate = nlen <= (fromIntegral $ T.length t)
60 errMsg = "length of " <> path <> " should be <= " <> T.pack (show nlen)
61 warn = vWarning $ mmSingleton path (pure errMsg)
66 predicate = nlen > (fromIntegral $ T.length t)
67 errMsg = "length of " <> path <> " should be > " <> T.pack (show nlen)
68 warn = vWarning $ mmSingleton path (pure errMsg)
73 predicate = maybe False (const True) $ matchRegex (mkRegex regex) (T.unpack t)
74 errMsg = path <> " must match " <> T.pack (show regex)
75 warn = vWarning $ mmSingleton path (pure errMsg)
79 matching :: Sing (s :: [Symbol]) -> Bool
81 matching (SCons s@SSym fs) = T.pack (symbolVal s) == t || matching fs
82 errMsg = path <> " must be one of " <> T.pack (show (fromSing ss))
83 warn = vWarning $ mmSingleton path (pure errMsg)
84 unless (matching ss) warn
86validateNumberConstraint
89 -> Sing (tcs :: NumberConstraint)
91validateNumberConstraint (JSONPath path) num = \case
95 predicate = fromIntegral nlen == num
96 errMsg = path <> " should be == " <> T.pack (show nlen)
97 warn = vWarning $ mmSingleton path (pure errMsg)
102 predicate = num > fromIntegral nlen
103 errMsg = path <> " should be > " <> T.pack (show nlen)
104 warn = vWarning $ mmSingleton path (pure errMsg)
105 unless predicate warn
109 predicate = fromIntegral nlen <= num
110 errMsg = path <> " should be <= " <> T.pack (show nlen)
111 warn = vWarning $ mmSingleton path (pure errMsg)
112 unless predicate warn
114validateArrayConstraint
117 -> Sing (tcs :: ArrayConstraint)
119validateArrayConstraint (JSONPath path) v = \case
123 predicate = nlen == fromIntegral (V.length v)
124 errMsg = "length of " <> path <> " should be == " <> T.pack (show nlen)
125 warn = vWarning $ mmSingleton path (pure errMsg)
126 unless predicate warn
130 -> [DemotedPathSegment]
133validateJsonRepr sschema dpath jr = case jr of
134 ReprText t -> case sschema of
135 SSchemaText scs -> do
137 process :: Sing (cs :: [TextConstraint]) -> Validation ()
138 process SNil = pure ()
139 process (SCons c cs) = do
140 validateTextConstraint (demotedPathToText dpath) t c
143 ReprNumber n -> case sschema of
144 SSchemaNumber scs -> do
146 process :: Sing (cs :: [NumberConstraint]) -> Validation ()
147 process SNil = pure ()
148 process (SCons c cs) = do
149 validateNumberConstraint (demotedPathToText dpath) n c
153 ReprArray v -> case sschema of
154 SSchemaArray acs s -> do
156 process :: Sing (cs :: [ArrayConstraint]) -> Validation ()
157 process SNil = pure ()
158 process (SCons c cs) = do
159 validateArrayConstraint (demotedPathToText dpath) v c
162 for_ (V.indexed v) $ \(ix, jr') -> do
163 let newPath = dpath <> pure (DIx $ fromIntegral ix)
164 validateJsonRepr s newPath jr'
165 ReprOptional d -> case sschema of
166 SSchemaOptional ss -> case d of
167 Just x -> validateJsonRepr ss dpath x
169 ReprObject fs -> case sschema of
170 SSchemaObject _ -> go fs
172 go :: Rec FieldRepr (ts :: [ (Symbol, Schema) ] ) -> Validation ()
174 go (f@(FieldRepr d) :& ftl) = do
175 let newPath = dpath <> [DKey (knownFieldName f)]
176 validateJsonRepr (knownFieldSchema f) newPath d
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list