@@ -4,6 +4,7 @@ import Import hiding ((<>))
5import Data.Aeson.TH (constructorTagModifier)
5import Data.Aeson.TH (constructorTagModifier)
6import Data.Char (toLower)
6import Data.Char (toLower)
7+import qualified Data.HashMap.Strict as HM
7import Data.List.NonEmpty (NonEmpty((:|)))
8import Data.List.NonEmpty (NonEmpty((:|)))
8import qualified Data.List.NonEmpty as NE
9import qualified Data.List.NonEmpty as NE
9import qualified Data.Scientific as SCI
10import qualified Data.Scientific as SCI
@@ -133,7 +134,7 @@ data JSONPointerError
133 deriving (Eq, Show)
134 deriving (Eq, Show)
135resolveFragment
136resolveFragment
136− :: forall schema. (FromJSON schema, ToJSON schema)
137+ :: (FromJSON schema, ToJSON schema)
137 => (BaseURI -> schema -> BaseURI)
138 => (BaseURI -> schema -> BaseURI)
138 -> Scope schema
139 -> Scope schema
@@ -158,17 +159,40 @@ resolveFragment updateScope scope fragment = do
158 -- as property keys that aren't meant to change scope?
159 -- as property keys that aren't meant to change scope?
159 -- Perhaps this should be added to the language agnostic
160 -- Perhaps this should be added to the language agnostic
160 -- test suite as well.
161 -- test suite as well.
163+ -- In the meantime 'newBaseURIFromFragment' drops all keys
164+ -- from JSON objects except "id", which at least prevents
165+ -- SubschemaDecodingError in a situation where one of the
166+ -- values we step through isn't a valid schema.
161 go :: (Value, BaseURI)
167 go :: (Value, BaseURI)
162 -> JP.Token
168 -> JP.Token
163 -> Either JSONPointerError (Value, BaseURI)
169 -> Either JSONPointerError (Value, BaseURI)
164− go (lastVal, uri) tok = do
170+ go (lastVal, baseURI) tok = do
165 v <- first ResolutionError (JP.resolveToken tok lastVal)
171 v <- first ResolutionError (JP.resolveToken tok lastVal)
166− case v of
172+ newBase <- newBaseURIFromFragment updateScope baseURI v
167− Array _ -> pure (v, uri)
173+ Right (v, newBase)
169− -- PERFORMANCE: Avoid deserializing subschemas.
175+-- | Update the 'BaseURI' (the store of the current "id" value)
176+-- after resolving one token of a JSON Pointer and stepping into
178+newBaseURIFromFragment
180+ => (BaseURI -> schema -> BaseURI)
183+ -> Either JSONPointerError BaseURI
184+newBaseURIFromFragment updateScope baseURI v =
187+ let hmWithOnlyId = case HM.lookup idKey hm of
189+ Just idVal -> HM.singleton idKey idVal
170− schema <- first SubschemaDecodingError (fromJSONEither v)
190+ schema <- first SubschemaDecodingError (fromJSONEither (Object hmWithOnlyId))
171− pure (v, updateScope uri schema)
191+ Right (updateScope baseURI schema)
173--------------------------------------------------
197--------------------------------------------------