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]
28 | ValidationError ErrorMap
29 deriving (Show, Eq, Functor)
34 -> Sing (tcs :: TextConstraint)
36validateTextConstraint (JSONPath path) t = \case
40 predicate = nlen == (fromIntegral $ T.length t)
41 errMsg = "length of " <> path <> " should be == " <> T.pack (show nlen)
42 warn = vWarning $ mmSingleton path (pure errMsg)
47 predicate = nlen <= (fromIntegral $ T.length t)
48 errMsg = "length of " <> path <> " should be <= " <> T.pack (show nlen)
49 warn = vWarning $ mmSingleton path (pure errMsg)
54 predicate = nlen > (fromIntegral $ T.length t)
55 errMsg = "length of " <> path <> " should be > " <> T.pack (show nlen)
56 warn = vWarning $ mmSingleton path (pure errMsg)
61 predicate = maybe False (const True) $ matchRegex (mkRegex regex) (T.unpack t)
62 errMsg = path <> " must match " <> T.pack (show regex)
63 warn = vWarning $ mmSingleton path (pure errMsg)
67 matching :: Sing (s :: [Symbol]) -> Bool
69 matching (SCons s@SSym fs) = T.pack (symbolVal s) == t || matching fs
70 errMsg = path <> " must be one of " <> T.pack (show (fromSing ss))
71 warn = vWarning $ mmSingleton path (pure errMsg)
72 unless (matching ss) warn
74validateNumberConstraint
77 -> Sing (tcs :: NumberConstraint)
79validateNumberConstraint (JSONPath path) num = \case
83 predicate = fromIntegral nlen == num
84 errMsg = path <> " should be == " <> T.pack (show nlen)
85 warn = vWarning $ mmSingleton path (pure errMsg)
90 predicate = num > fromIntegral nlen
91 errMsg = path <> " should be > " <> T.pack (show nlen)
92 warn = vWarning $ mmSingleton path (pure errMsg)
97 predicate = fromIntegral nlen <= num
98 errMsg = path <> " should be <= " <> T.pack (show nlen)
99 warn = vWarning $ mmSingleton path (pure errMsg)
100 unless predicate warn
102validateArrayConstraint
105 -> Sing (tcs :: ArrayConstraint)
107validateArrayConstraint (JSONPath path) v = \case
111 predicate = nlen == fromIntegral (V.length v)
112 errMsg = "length of " <> path <> " should be == " <> T.pack (show nlen)
113 warn = vWarning $ mmSingleton path (pure errMsg)
114 unless predicate warn
118 -> [DemotedPathSegment]
121validateJsonRepr sschema dpath jr = case jr of
122 ReprText t -> case sschema of
123 SSchemaText scs -> do
125 process :: Sing (cs :: [TextConstraint]) -> Validation ()
126 process SNil = pure ()
127 process (SCons c cs) = do
128 validateTextConstraint (demotedPathToText dpath) t c
131 ReprNumber n -> case sschema of
132 SSchemaNumber scs -> do
134 process :: Sing (cs :: [NumberConstraint]) -> Validation ()
135 process SNil = pure ()
136 process (SCons c cs) = do
137 validateNumberConstraint (demotedPathToText dpath) n c
141 ReprArray v -> case sschema of
142 SSchemaArray acs s -> do
144 process :: Sing (cs :: [ArrayConstraint]) -> Validation ()
145 process SNil = pure ()
146 process (SCons c cs) = do
147 validateArrayConstraint (demotedPathToText dpath) v c
150 for_ (V.indexed v) $ \(ix, jr') -> do
151 let newPath = dpath <> pure (DIx $ fromIntegral ix)
152 validateJsonRepr s newPath jr'
153 ReprOptional d -> case sschema of
154 SSchemaOptional ss -> case d of
155 Just x -> validateJsonRepr ss dpath x
157 ReprObject fs -> case sschema of
158 SSchemaObject _ -> go fs
160 go :: Rec FieldRepr (ts :: [ (Symbol, Schema) ] ) -> Validation ()
162 go (f@(FieldRepr d) :& ftl) = do
163 let newPath = dpath <> [DKey (knownFieldName f)]
164 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