Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Add (<.:>), which is like (.:) but traverses through the JSON according to the given path #60

Closed
wants to merge 2 commits into
from
Jump to file or symbol
Failed to load files and symbols.
+16 −0
Split
View
@@ -37,6 +37,7 @@ module Data.Aeson.Types
, (.:)
, (.:?)
, (.!=)
+ , (<.:>)
, object
) where
View
@@ -36,6 +36,7 @@ module Data.Aeson.Types.Class
, (.:?)
, (.!=)
, (.=)
+ , (<.:>)
, typeMismatch
) where
@@ -765,6 +766,20 @@ obj .:? key = case H.lookup key obj of
pmval .!= val = fromMaybe val <$> pmval
{-# INLINE (.!=) #-}
+-- | Produce the value for the last key by traversing through the JSON.
+--
+-- Example usage:
+--
+-- > o <.:> ["_links", "comments", "href"]
+(<.:>) :: (FromJSON a) => Object -> [Text] -> Parser a
+_ <.:> [] = fail $ "attempted to traverse an Object without a path"
+obj <.:> [key] = obj .: key
+obj <.:> (key:keys) =
+ case next of
+ (Object nextObj) -> nextObj <.:> keys
+ other -> typeMismatch "Object" other
+ where next = fromMaybe (Object H.empty) $ H.lookup key obj
+
-- | Fail parsing due to a type mismatch, with a descriptive message.
typeMismatch :: String -- ^ The name of the type you are trying to parse.
-> Value -- ^ The actual value encountered.