{-# LANGUAGE DeriveFunctor              #-}
{-# LANGUAGE FlexibleContexts           #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GADTs                      #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE Rank2Types                 #-}
{-# LANGUAGE TypeFamilies               #-}
{-# LANGUAGE TypeOperators              #-}
-- | Types and functions to convert Json values into your data types.
--
-- This module uses the 'Control.Lens.Traversal' based 'Control.Zipper.Zipper'
-- as the basis for the 'Decoder'. It is provided for compatibility and
-- comparison. It is not as fast as the succinct data structure based
-- 'Waargonaut.Decode.Decoder'.
--
module Waargonaut.Decode.Traversal 
  {-# DEPRECATED "Use 'Waargonaut.Decode'. This module will be removed in a future release." #-} 
  (
    Err (..)
  , CursorHistory (..)
  , DecodeResult (..)

    -- * Type aliases
  , JCursorMove
  , JCursor
  , Decoder

    -- * Decoder creation
  , withCursor

    -- * Decoder execution
  , runDecoder
  , runDecoderResult
  , runPureDecode
  , simpleDecode
  , generaliseDecoder

    -- * Cursor movement
  , into
  , up
  , down
  , moveLeftN
  , moveLeft1
  , moveRightN
  , moveRight1
  , moveToKey
  , try

    -- * Decode at Cursor
  , fromKey
  , atKey
  , atCursor
  , focus

    -- * Provided decoders
  , scientific
  , integral
  , int
  , bool
  , text
  , string
  , boundedChar
  , unboundedChar
  , null
  , json
  , foldCursor
  , leftwardCons
  , rightwardSnoc
  , nonEmptyAt
  , nonempty
  , listAt
  , list
  , maybeOrNull
  , withDefault
  , either
  ) where

import           Prelude                       hiding (either, maybe, null)

import           Natural                       (Natural, successor', zero',
                                                _Natural)

import           Control.Lens                  (Bazaar', Cons, LensLike', Snoc,
                                                re, (^.), (^?))
import qualified Control.Lens                  as L

import           Control.Lens.Internal.Indexed (Indexed, Indexing)
import           Control.Monad                 ((>=>))
import           Control.Monad.Except          (MonadError)
import           Control.Monad.Morph           (MFunctor (..), MMonad (..),
                                                generalize)
import           Control.Monad.State           (MonadState)
import           Control.Monad.Trans.Class     (MonadTrans (..))

import           Control.Error.Util            (note)
import           Control.Monad.Error.Hoist     ((<%?>), (<?>))

import           Control.Zipper                ((:>>))
import qualified Control.Zipper                as Z

import           Data.Functor.Identity         (Identity, runIdentity)
import qualified Data.Maybe                    as Maybe

import           Data.List.NonEmpty            (NonEmpty ((:|)))

import qualified Data.Bool                     as Bool
import           Data.Text                     (Text)

import           Data.Scientific               (Scientific)

import           Waargonaut.Types              (AsJType, Elems, JAssoc, Json)

import qualified Waargonaut.Types              as WT

import           Waargonaut.Decode.Error       (Err (..))
import           Waargonaut.Decode.Internal    (CursorHistory' (..),
                                                DecodeError (..), DecodeResultT,
                                                Decoder' (..), ZipperMove (..),
                                                runDecoderResultT, try)

import qualified Waargonaut.Decode.Internal    as DR

-- | Convenience Error structure for the separate parsing/decoding phases. For
-- when things really aren't that complicated.

-- | Wrapper for our 'CursorHistory'' to define our index as being an 'Int'.
--
newtype CursorHistory = CursorHist
  { CursorHistory -> CursorHistory' Int
unCursorHist :: CursorHistory' Int
  }
  deriving (Int -> CursorHistory -> ShowS
[CursorHistory] -> ShowS
CursorHistory -> String
(Int -> CursorHistory -> ShowS)
-> (CursorHistory -> String)
-> ([CursorHistory] -> ShowS)
-> Show CursorHistory
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CursorHistory] -> ShowS
$cshowList :: [CursorHistory] -> ShowS
show :: CursorHistory -> String
$cshow :: CursorHistory -> String
showsPrec :: Int -> CursorHistory -> ShowS
$cshowsPrec :: Int -> CursorHistory -> ShowS
Show, CursorHistory -> CursorHistory -> Bool
(CursorHistory -> CursorHistory -> Bool)
-> (CursorHistory -> CursorHistory -> Bool) -> Eq CursorHistory
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CursorHistory -> CursorHistory -> Bool
$c/= :: CursorHistory -> CursorHistory -> Bool
== :: CursorHistory -> CursorHistory -> Bool
$c== :: CursorHistory -> CursorHistory -> Bool
Eq)

-- | Provide some of the type parameters that the underlying 'DecodeResultT'
-- requires. This contains the state and error management as we walk around our
-- zipper and decode our JSON input.
--
newtype DecodeResult f a = DecodeResult
  { DecodeResult f a -> DecodeResultT Int DecodeError f a
unDecodeResult :: DecodeResultT Int DecodeError f a
  }
  deriving ( a -> DecodeResult f b -> DecodeResult f a
(a -> b) -> DecodeResult f a -> DecodeResult f b
(forall a b. (a -> b) -> DecodeResult f a -> DecodeResult f b)
-> (forall a b. a -> DecodeResult f b -> DecodeResult f a)
-> Functor (DecodeResult f)
forall a b. a -> DecodeResult f b -> DecodeResult f a
forall a b. (a -> b) -> DecodeResult f a -> DecodeResult f b
forall (f :: * -> *) a b.
Functor f =>
a -> DecodeResult f b -> DecodeResult f a
forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> DecodeResult f a -> DecodeResult f b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> DecodeResult f b -> DecodeResult f a
$c<$ :: forall (f :: * -> *) a b.
Functor f =>
a -> DecodeResult f b -> DecodeResult f a
fmap :: (a -> b) -> DecodeResult f a -> DecodeResult f b
$cfmap :: forall (f :: * -> *) a b.
Functor f =>
(a -> b) -> DecodeResult f a -> DecodeResult f b
Functor
           , Functor (DecodeResult f)
a -> DecodeResult f a
Functor (DecodeResult f)
-> (forall a. a -> DecodeResult f a)
-> (forall a b.
    DecodeResult f (a -> b) -> DecodeResult f a -> DecodeResult f b)
-> (forall a b c.
    (a -> b -> c)
    -> DecodeResult f a -> DecodeResult f b -> DecodeResult f c)
-> (forall a b.
    DecodeResult f a -> DecodeResult f b -> DecodeResult f b)
-> (forall a b.
    DecodeResult f a -> DecodeResult f b -> DecodeResult f a)
-> Applicative (DecodeResult f)
DecodeResult f a -> DecodeResult f b -> DecodeResult f b
DecodeResult f a -> DecodeResult f b -> DecodeResult f a
DecodeResult f (a -> b) -> DecodeResult f a -> DecodeResult f b
(a -> b -> c)
-> DecodeResult f a -> DecodeResult f b -> DecodeResult f c
forall a. a -> DecodeResult f a
forall a b.
DecodeResult f a -> DecodeResult f b -> DecodeResult f a
forall a b.
DecodeResult f a -> DecodeResult f b -> DecodeResult f b
forall a b.
DecodeResult f (a -> b) -> DecodeResult f a -> DecodeResult f b
forall a b c.
(a -> b -> c)
-> DecodeResult f a -> DecodeResult f b -> DecodeResult f c
forall (f :: * -> *). Monad f => Functor (DecodeResult f)
forall (f :: * -> *) a. Monad f => a -> DecodeResult f a
forall (f :: * -> *) a b.
Monad f =>
DecodeResult f a -> DecodeResult f b -> DecodeResult f a
forall (f :: * -> *) a b.
Monad f =>
DecodeResult f a -> DecodeResult f b -> DecodeResult f b
forall (f :: * -> *) a b.
Monad f =>
DecodeResult f (a -> b) -> DecodeResult f a -> DecodeResult f b
forall (f :: * -> *) a b c.
Monad f =>
(a -> b -> c)
-> DecodeResult f a -> DecodeResult f b -> DecodeResult f c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: DecodeResult f a -> DecodeResult f b -> DecodeResult f a
$c<* :: forall (f :: * -> *) a b.
Monad f =>
DecodeResult f a -> DecodeResult f b -> DecodeResult f a
*> :: DecodeResult f a -> DecodeResult f b -> DecodeResult f b
$c*> :: forall (f :: * -> *) a b.
Monad f =>
DecodeResult f a -> DecodeResult f b -> DecodeResult f b
liftA2 :: (a -> b -> c)
-> DecodeResult f a -> DecodeResult f b -> DecodeResult f c
$cliftA2 :: forall (f :: * -> *) a b c.
Monad f =>
(a -> b -> c)
-> DecodeResult f a -> DecodeResult f b -> DecodeResult f c
<*> :: DecodeResult f (a -> b) -> DecodeResult f a -> DecodeResult f b
$c<*> :: forall (f :: * -> *) a b.
Monad f =>
DecodeResult f (a -> b) -> DecodeResult f a -> DecodeResult f b
pure :: a -> DecodeResult f a
$cpure :: forall (f :: * -> *) a. Monad f => a -> DecodeResult f a
$cp1Applicative :: forall (f :: * -> *). Monad f => Functor (DecodeResult f)
Applicative
           , Applicative (DecodeResult f)
a -> DecodeResult f a
Applicative (DecodeResult f)
-> (forall a b.
    DecodeResult f a -> (a -> DecodeResult f b) -> DecodeResult f b)
-> (forall a b.
    DecodeResult f a -> DecodeResult f b -> DecodeResult f b)
-> (forall a. a -> DecodeResult f a)
-> Monad (DecodeResult f)
DecodeResult f a -> (a -> DecodeResult f b) -> DecodeResult f b
DecodeResult f a -> DecodeResult f b -> DecodeResult f b
forall a. a -> DecodeResult f a
forall a b.
DecodeResult f a -> DecodeResult f b -> DecodeResult f b
forall a b.
DecodeResult f a -> (a -> DecodeResult f b) -> DecodeResult f b
forall (f :: * -> *). Monad f => Applicative (DecodeResult f)
forall (f :: * -> *) a. Monad f => a -> DecodeResult f a
forall (f :: * -> *) a b.
Monad f =>
DecodeResult f a -> DecodeResult f b -> DecodeResult f b
forall (f :: * -> *) a b.
Monad f =>
DecodeResult f a -> (a -> DecodeResult f b) -> DecodeResult f b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: a -> DecodeResult f a
$creturn :: forall (f :: * -> *) a. Monad f => a -> DecodeResult f a
>> :: DecodeResult f a -> DecodeResult f b -> DecodeResult f b
$c>> :: forall (f :: * -> *) a b.
Monad f =>
DecodeResult f a -> DecodeResult f b -> DecodeResult f b
>>= :: DecodeResult f a -> (a -> DecodeResult f b) -> DecodeResult f b
$c>>= :: forall (f :: * -> *) a b.
Monad f =>
DecodeResult f a -> (a -> DecodeResult f b) -> DecodeResult f b
$cp1Monad :: forall (f :: * -> *). Monad f => Applicative (DecodeResult f)
Monad
           , MonadState (CursorHistory' Int)
           , MonadError DecodeError
           )

instance MonadTrans DecodeResult where
  lift :: m a -> DecodeResult m a
lift = DecodeResultT Int DecodeError m a -> DecodeResult m a
forall (f :: * -> *) a.
DecodeResultT Int DecodeError f a -> DecodeResult f a
DecodeResult (DecodeResultT Int DecodeError m a -> DecodeResult m a)
-> (m a -> DecodeResultT Int DecodeError m a)
-> m a
-> DecodeResult m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> DecodeResultT Int DecodeError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift

instance MFunctor DecodeResult where
  hoist :: (forall a. m a -> n a) -> DecodeResult m b -> DecodeResult n b
hoist forall a. m a -> n a
nat (DecodeResult DecodeResultT Int DecodeError m b
dr) = DecodeResultT Int DecodeError n b -> DecodeResult n b
forall (f :: * -> *) a.
DecodeResultT Int DecodeError f a -> DecodeResult f a
DecodeResult ((forall a. m a -> n a)
-> DecodeResultT Int DecodeError m b
-> DecodeResultT Int DecodeError n b
forall k (t :: (* -> *) -> k -> *) (m :: * -> *) (n :: * -> *)
       (b :: k).
(MFunctor t, Monad m) =>
(forall a. m a -> n a) -> t m b -> t n b
hoist forall a. m a -> n a
nat DecodeResultT Int DecodeError m b
dr)

instance MMonad DecodeResult where
  embed :: (forall a. m a -> DecodeResult n a)
-> DecodeResult m b -> DecodeResult n b
embed forall a. m a -> DecodeResult n a
f (DecodeResult DecodeResultT Int DecodeError m b
dr) = DecodeResultT Int DecodeError n b -> DecodeResult n b
forall (f :: * -> *) a.
DecodeResultT Int DecodeError f a -> DecodeResult f a
DecodeResult ((forall a. m a -> DecodeResultT Int DecodeError n a)
-> DecodeResultT Int DecodeError m b
-> DecodeResultT Int DecodeError n b
forall (t :: (* -> *) -> * -> *) (n :: * -> *) (m :: * -> *) b.
(MMonad t, Monad n) =>
(forall a. m a -> t n a) -> t m b -> t n b
embed (DecodeResult n a -> DecodeResultT Int DecodeError n a
forall (f :: * -> *) a.
DecodeResult f a -> DecodeResultT Int DecodeError f a
unDecodeResult (DecodeResult n a -> DecodeResultT Int DecodeError n a)
-> (m a -> DecodeResult n a)
-> m a
-> DecodeResultT Int DecodeError n a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> DecodeResult n a
forall a. m a -> DecodeResult n a
f) DecodeResultT Int DecodeError m b
dr)

-- | Type alias to describe the lens that may be given to a zipper movement
-- function to more directly target something within the 'Json' data structure.
--
type JCursorMove s a =
  LensLike' (Indexing (Bazaar' (Indexed Int) a)) s a

-- | This is an alias to help explain a type from the zipper that is used to move
-- around the 'Json' data structure. 'JCursor h a' represents a "cursor" that is
-- currently located on a thing of type @a@, having previously been on a thing
-- of type @h@.
--
-- This type will grow as a form of "breadcrumb" trail as the cursor moves
-- through the data structure. It may be used interchangably with 'h :>> a' from
-- the 'Control.Zipper' module.
--
type JCursor h a =
  h :>> a

-- | A shorthand description of our 'Decoder' type that is used directly to
-- convert 'Json' structures to other data types.
--
type Decoder f a =
  forall h. Decoder' (JCursor h Json) Int DecodeError f a

-- | Generalise a 'Decoder' that has been specialised to 'Identity' back to some 'Monad f'.
generaliseDecoder :: Monad f => Decoder Identity a -> Decoder f a
generaliseDecoder :: Decoder Identity a -> Decoder f a
generaliseDecoder Decoder Identity a
dr = (JCursor h Json -> DecodeResultT Int DecodeError f a)
-> Decoder' (JCursor h Json) Int DecodeError f a
forall c i e (f :: * -> *) a.
(c -> DecodeResultT i e f a) -> Decoder' c i e f a
Decoder' ((forall a. Identity a -> DecodeResultT Int DecodeError f a)
-> DecodeResultT Int DecodeError Identity a
-> DecodeResultT Int DecodeError f a
forall (t :: (* -> *) -> * -> *) (n :: * -> *) (m :: * -> *) b.
(MMonad t, Monad n) =>
(forall a. m a -> t n a) -> t m b -> t n b
embed forall a. Identity a -> DecodeResultT Int DecodeError f a
forall (m :: * -> *) a. Monad m => Identity a -> m a
generalize (DecodeResultT Int DecodeError Identity a
 -> DecodeResultT Int DecodeError f a)
-> (JCursor h Json -> DecodeResultT Int DecodeError Identity a)
-> JCursor h Json
-> DecodeResultT Int DecodeError f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Decoder' (JCursor h Json) Int DecodeError Identity a
-> JCursor h Json -> DecodeResultT Int DecodeError Identity a
forall c i e (f :: * -> *) a.
Decoder' c i e f a -> c -> DecodeResultT i e f a
runDecoder' Decoder' (JCursor h Json) Int DecodeError Identity a
Decoder Identity a
dr)
{-# INLINE generaliseDecoder #-}

-- | Function to define a 'Decoder' for a specific data type.
--
-- For example, given the following data type:
--
-- @
-- data Image = Image
--   { _imageW        :: Int
--   , _imageH        :: Int
--   , _imageTitle    :: Text
--   , _imageAnimated :: Bool
--   , _imageIDs      :: [Int]
--   }
-- @
--
-- We can use 'withCursor' to write a decoder that will be given a cursor that
-- we can use to build the data types that we need.
--
-- @
-- imageDecoder :: Monad f => Decoder f Image
-- imageDecoder = withCursor $ \\curs -> Image
--   \<$> D.fromKey \"Width\" D.int curs
--   \<*> D.fromKey \"Height\" D.int curs
--   \<*> D.fromKey \"Title\" D.text curs
--   \<*> D.fromKey \"Animated\" D.bool curs
--   \<*> D.fromKey \"IDs\" intArray curs
-- @
--
-- It's up to you to provide a cursor that is at the correct position for a
-- 'Decoder' to operate, but building decoders in this way simplifies creating
-- decoders for larger structures, as the smaller pieces contain fewer
-- assumptions. This encourages greater reuse of decoders and simplifies the
-- debugging process.
--
withCursor
  :: (forall h. JCursor h Json -> DecodeResult f a)
  -> Decoder f a
withCursor :: (forall h. JCursor h Json -> DecodeResult f a) -> Decoder f a
withCursor forall h. JCursor h Json -> DecodeResult f a
f =
  (JCursor h Json -> DecodeResultT Int DecodeError f a)
-> Decoder' (JCursor h Json) Int DecodeError f a
forall c i e (f :: * -> *) a.
(c -> DecodeResultT i e f a) -> Decoder' c i e f a
Decoder' (DecodeResult f a -> DecodeResultT Int DecodeError f a
forall (f :: * -> *) a.
DecodeResult f a -> DecodeResultT Int DecodeError f a
unDecodeResult (DecodeResult f a -> DecodeResultT Int DecodeError f a)
-> (JCursor h Json -> DecodeResult f a)
-> JCursor h Json
-> DecodeResultT Int DecodeError f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JCursor h Json -> DecodeResult f a
forall h. JCursor h Json -> DecodeResult f a
f)

-- | Run a 'Decoder f a' using a 'JCursor' to try to convert it into the data
-- type described by the 'Decoder'.
--
runDecoder
  :: Decoder f a
  -> JCursor h Json
  -> DecodeResult f a
runDecoder :: Decoder f a -> JCursor h Json -> DecodeResult f a
runDecoder Decoder f a
f =
  DecodeResultT Int DecodeError f a -> DecodeResult f a
forall (f :: * -> *) a.
DecodeResultT Int DecodeError f a -> DecodeResult f a
DecodeResult (DecodeResultT Int DecodeError f a -> DecodeResult f a)
-> (JCursor h Json -> DecodeResultT Int DecodeError f a)
-> JCursor h Json
-> DecodeResult f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Decoder' (JCursor h Json) Int DecodeError f a
-> JCursor h Json -> DecodeResultT Int DecodeError f a
forall c i e (f :: * -> *) a.
Decoder' c i e f a -> c -> DecodeResultT i e f a
DR.runDecoder' Decoder' (JCursor h Json) Int DecodeError f a
Decoder f a
f

-- | Execute a 'DecodeResult' to determine if the process has been successful,
-- providing a descriptive error and the path history of the cursor movements to
-- assist in debugging any failures.
--
runDecoderResult
  :: Monad f
  => DecodeResult f a
  -> f (Either (DecodeError, CursorHistory) a)
runDecoderResult :: DecodeResult f a -> f (Either (DecodeError, CursorHistory) a)
runDecoderResult =
  ASetter
  (f (Either (DecodeError, CursorHistory' Int) a))
  (f (Either (DecodeError, CursorHistory) a))
  (CursorHistory' Int)
  CursorHistory
-> (CursorHistory' Int -> CursorHistory)
-> f (Either (DecodeError, CursorHistory' Int) a)
-> f (Either (DecodeError, CursorHistory) a)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
L.over ((Either (DecodeError, CursorHistory' Int) a
 -> Identity (Either (DecodeError, CursorHistory) a))
-> f (Either (DecodeError, CursorHistory' Int) a)
-> Identity (f (Either (DecodeError, CursorHistory) a))
forall (f :: * -> *) a b. Functor f => Setter (f a) (f b) a b
L.mapped ((Either (DecodeError, CursorHistory' Int) a
  -> Identity (Either (DecodeError, CursorHistory) a))
 -> f (Either (DecodeError, CursorHistory' Int) a)
 -> Identity (f (Either (DecodeError, CursorHistory) a)))
-> ((CursorHistory' Int -> Identity CursorHistory)
    -> Either (DecodeError, CursorHistory' Int) a
    -> Identity (Either (DecodeError, CursorHistory) a))
-> ASetter
     (f (Either (DecodeError, CursorHistory' Int) a))
     (f (Either (DecodeError, CursorHistory) a))
     (CursorHistory' Int)
     CursorHistory
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((DecodeError, CursorHistory' Int)
 -> Identity (DecodeError, CursorHistory))
-> Either (DecodeError, CursorHistory' Int) a
-> Identity (Either (DecodeError, CursorHistory) a)
forall a c b. Prism (Either a c) (Either b c) a b
L._Left (((DecodeError, CursorHistory' Int)
  -> Identity (DecodeError, CursorHistory))
 -> Either (DecodeError, CursorHistory' Int) a
 -> Identity (Either (DecodeError, CursorHistory) a))
-> ((CursorHistory' Int -> Identity CursorHistory)
    -> (DecodeError, CursorHistory' Int)
    -> Identity (DecodeError, CursorHistory))
-> (CursorHistory' Int -> Identity CursorHistory)
-> Either (DecodeError, CursorHistory' Int) a
-> Identity (Either (DecodeError, CursorHistory) a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CursorHistory' Int -> Identity CursorHistory)
-> (DecodeError, CursorHistory' Int)
-> Identity (DecodeError, CursorHistory)
forall s t a b. Field2 s t a b => Lens s t a b
L._2) CursorHistory' Int -> CursorHistory
CursorHist
  (f (Either (DecodeError, CursorHistory' Int) a)
 -> f (Either (DecodeError, CursorHistory) a))
-> (DecodeResult f a
    -> f (Either (DecodeError, CursorHistory' Int) a))
-> DecodeResult f a
-> f (Either (DecodeError, CursorHistory) a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DecodeResultT Int DecodeError f a
-> f (Either (DecodeError, CursorHistory' Int) a)
forall (f :: * -> *) i a.
Monad f =>
DecodeResultT i DecodeError f a
-> f (Either (DecodeError, CursorHistory' i) a)
runDecoderResultT
  (DecodeResultT Int DecodeError f a
 -> f (Either (DecodeError, CursorHistory' Int) a))
-> (DecodeResult f a -> DecodeResultT Int DecodeError f a)
-> DecodeResult f a
-> f (Either (DecodeError, CursorHistory' Int) a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DecodeResult f a -> DecodeResultT Int DecodeError f a
forall (f :: * -> *) a.
DecodeResult f a -> DecodeResultT Int DecodeError f a
unDecodeResult

-- |
-- Run a pure decoder with 'Identity'.
--
runPureDecode
  :: Decoder Identity a
  -> JCursor h Json
  -> Either (DecodeError, CursorHistory) a
runPureDecode :: Decoder Identity a
-> JCursor h Json -> Either (DecodeError, CursorHistory) a
runPureDecode Decoder Identity a
dec = Identity (Either (DecodeError, CursorHistory) a)
-> Either (DecodeError, CursorHistory) a
forall a. Identity a -> a
runIdentity
  (Identity (Either (DecodeError, CursorHistory) a)
 -> Either (DecodeError, CursorHistory) a)
-> (JCursor h Json
    -> Identity (Either (DecodeError, CursorHistory) a))
-> JCursor h Json
-> Either (DecodeError, CursorHistory) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DecodeResult Identity a
-> Identity (Either (DecodeError, CursorHistory) a)
forall (f :: * -> *) a.
Monad f =>
DecodeResult f a -> f (Either (DecodeError, CursorHistory) a)
runDecoderResult
  (DecodeResult Identity a
 -> Identity (Either (DecodeError, CursorHistory) a))
-> (JCursor h Json -> DecodeResult Identity a)
-> JCursor h Json
-> Identity (Either (DecodeError, CursorHistory) a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Decoder Identity a -> JCursor h Json -> DecodeResult Identity a
forall (f :: * -> *) a h.
Decoder f a -> JCursor h Json -> DecodeResult f a
runDecoder Decoder Identity a
dec

-- |
-- Using the given parsing function, take some input and try to convert it to
-- the 'Json' structure. Then pass it to the given 'Decoder'.
simpleDecode
  :: (s -> Either e Json)
  -> Decoder Identity a
  -> s
  -> Either (Err CursorHistory e) a
simpleDecode :: (s -> Either e Json)
-> Decoder Identity a -> s -> Either (Err CursorHistory e) a
simpleDecode s -> Either e Json
p Decoder Identity a
dec =
  (e -> Err CursorHistory e)
-> (Json -> Top :>> Json)
-> Either e Json
-> Either (Err CursorHistory e) (Top :>> Json)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
L.bimap e -> Err CursorHistory e
forall c e. e -> Err c e
Parse Json -> Top :>> Json
forall a. a -> Top :>> a
Z.zipper (Either e Json -> Either (Err CursorHistory e) (Top :>> Json))
-> (s -> Either e Json)
-> s
-> Either (Err CursorHistory e) (Top :>> Json)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> Either e Json
p (s -> Either (Err CursorHistory e) (Top :>> Json))
-> ((Top :>> Json) -> Either (Err CursorHistory e) a)
-> s
-> Either (Err CursorHistory e) a
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=>
  ASetter
  (Either (DecodeError, CursorHistory) a)
  (Either (Err CursorHistory e) a)
  (DecodeError, CursorHistory)
  (Err CursorHistory e)
-> ((DecodeError, CursorHistory) -> Err CursorHistory e)
-> Either (DecodeError, CursorHistory) a
-> Either (Err CursorHistory e) a
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
L.over ASetter
  (Either (DecodeError, CursorHistory) a)
  (Either (Err CursorHistory e) a)
  (DecodeError, CursorHistory)
  (Err CursorHistory e)
forall a c b. Prism (Either a c) (Either b c) a b
L._Left (DecodeError, CursorHistory) -> Err CursorHistory e
forall c e. (DecodeError, c) -> Err c e
Decode (Either (DecodeError, CursorHistory) a
 -> Either (Err CursorHistory e) a)
-> ((Top :>> Json) -> Either (DecodeError, CursorHistory) a)
-> (Top :>> Json)
-> Either (Err CursorHistory e) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Decoder Identity a
-> (Top :>> Json) -> Either (DecodeError, CursorHistory) a
forall a h.
Decoder Identity a
-> JCursor h Json -> Either (DecodeError, CursorHistory) a
runPureDecode Decoder Identity a
dec

-- Helper function that takes a given attempt to move the cursor to a new
-- location, throwing the 'FailedToMove' error if it fails, or recording the new
-- position and returning the new position.
moveAndKeepHistory
  :: Monad f
  => ZipperMove
  -> Maybe (JCursor h s)
  -> DecodeResult f (JCursor h s)
moveAndKeepHistory :: ZipperMove -> Maybe (JCursor h s) -> DecodeResult f (JCursor h s)
moveAndKeepHistory ZipperMove
dir Maybe (JCursor h s)
mCurs = do
  JCursor h s
a <- Maybe (JCursor h s)
mCurs Maybe (JCursor h s) -> DecodeError -> DecodeResult f (JCursor h s)
forall (m :: * -> *) (t :: * -> *) e e' a.
HoistError m t e e' =>
t a -> e' -> m a
<?> ZipperMove -> DecodeError
FailedToMove ZipperMove
dir
  JCursor h s
a JCursor h s -> DecodeResult f () -> DecodeResult f (JCursor h s)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ZipperMove -> Int -> DecodeResult f ()
forall i (m :: * -> *).
MonadState (CursorHistory' i) m =>
ZipperMove -> i -> m ()
DR.recordZipperMove ZipperMove
dir (JCursor h s -> Int
forall h i a. Zipper h i a -> Int
Z.tooth JCursor h s
a)

-- | Using a given 'Control.Lens.LensLike', try to step down into the 'Json' data structure
-- to the location targeted by the lens.
--
-- This can be used to move large steps over the data structure, or more
-- precisely to specific keys at deeper levels. On a successful step, the
-- history will be recorded as a single step into the thing described by the
-- 'Text' input.
--
into
  :: Monad f
  => Text
  -> JCursorMove s a
  -> JCursor h s
  -> DecodeResult f (JCursor (JCursor h s) a)
into :: Text
-> JCursorMove s a
-> JCursor h s
-> DecodeResult f (JCursor (JCursor h s) a)
into Text
tgt JCursorMove s a
l =
  ZipperMove
-> Maybe (JCursor (JCursor h s) a)
-> DecodeResult f (JCursor (JCursor h s) a)
forall (f :: * -> *) h s.
Monad f =>
ZipperMove -> Maybe (JCursor h s) -> DecodeResult f (JCursor h s)
moveAndKeepHistory (Text -> ZipperMove
DAt Text
tgt) (Maybe (JCursor (JCursor h s) a)
 -> DecodeResult f (JCursor (JCursor h s) a))
-> (JCursor h s -> Maybe (JCursor (JCursor h s) a))
-> JCursor h s
-> DecodeResult f (JCursor (JCursor h s) a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JCursorMove s a
-> (h :> (s :@ Int)) -> Maybe ((h :> (s :@ Int)) :>> a)
forall (m :: * -> *) a s h j.
MonadPlus m =>
LensLike' (Indexing (Bazaar' (Indexed Int) a)) s a
-> (h :> (s :@ j)) -> m ((h :> (s :@ j)) :>> a)
Z.within JCursorMove s a
l

-- | A constrained version of 'into' that will only move a single step down into
-- a 'Json' value. The 'Text' input is so you're able to provide an expectation
-- of what you are stepping down into, this provides a more descriptive error
-- message than simply "down".
--
-- For example:
--
-- @
-- firstElemCursor <- down "array" cursor
-- @
--
down
  :: Monad f
  => Text
  -> JCursor h Json
  -> DecodeResult f (JCursor (JCursor h Json) Json)
down :: Text
-> JCursor h Json -> DecodeResult f (JCursor (JCursor h Json) Json)
down Text
tgt =
  Text
-> JCursorMove Json Json
-> JCursor h Json
-> DecodeResult f (JCursor (JCursor h Json) Json)
forall (f :: * -> *) s a h.
Monad f =>
Text
-> JCursorMove s a
-> JCursor h s
-> DecodeResult f (JCursor (JCursor h s) a)
into Text
tgt JCursorMove Json Json
Traversal' Json Json
WT.jsonTraversal

-- | Attempt to step one level "up" from the current cursor location.
up
  :: Monad f
  => JCursor (JCursor h s) a
  -> DecodeResult f (JCursor h s)
up :: JCursor (JCursor h s) a -> DecodeResult f (JCursor h s)
up =
  ZipperMove -> Maybe (JCursor h s) -> DecodeResult f (JCursor h s)
forall (f :: * -> *) h s.
Monad f =>
ZipperMove -> Maybe (JCursor h s) -> DecodeResult f (JCursor h s)
moveAndKeepHistory ZipperMove
U (Maybe (JCursor h s) -> DecodeResult f (JCursor h s))
-> (JCursor (JCursor h s) a -> Maybe (JCursor h s))
-> JCursor (JCursor h s) a
-> DecodeResult f (JCursor h s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JCursor h s -> Maybe (JCursor h s)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (JCursor h s -> Maybe (JCursor h s))
-> (JCursor (JCursor h s) a -> JCursor h s)
-> JCursor (JCursor h s) a
-> Maybe (JCursor h s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JCursor (JCursor h s) a -> JCursor h s
forall j h s a i.
Ord j =>
((h :> (s :@ j)) :> (a :@ i)) -> h :> (s :@ j)
Z.upward

-- | From the current cursor location, try to move @n@ steps to the left.
moveLeftN
  :: Monad f
  => Natural
  -> JCursor h a
  -> DecodeResult f (JCursor h a)
moveLeftN :: Natural -> JCursor h a -> DecodeResult f (JCursor h a)
moveLeftN Natural
n JCursor h a
cur =
  ZipperMove -> Maybe (JCursor h a) -> DecodeResult f (JCursor h a)
forall (f :: * -> *) h s.
Monad f =>
ZipperMove -> Maybe (JCursor h s) -> DecodeResult f (JCursor h s)
moveAndKeepHistory (Natural -> ZipperMove
L Natural
n) ((JCursor h a -> Maybe (JCursor h a))
-> Int -> JCursor h a -> Maybe (JCursor h a)
forall (m :: * -> *) a.
MonadFail m =>
(a -> m a) -> Int -> a -> m a
Z.jerks JCursor h a -> Maybe (JCursor h a)
forall (m :: * -> *) h a i.
MonadPlus m =>
(h :> (a :@ i)) -> m (h :> (a :@ i))
Z.leftward (Natural
n Natural -> Getting Int Natural Int -> Int
forall s a. s -> Getting a s a -> a
^. AReview Int Natural -> Getter Natural Int
forall t b. AReview t b -> Getter b t
re AReview Int Natural
forall a. AsNatural a => Prism' a Natural
_Natural) JCursor h a
cur)

-- | From the current cursor location, try to move @n@ steps to the right.
moveRightN
  :: Monad f
  => Natural
  -> JCursor h a
  -> DecodeResult f (JCursor h a)
moveRightN :: Natural -> JCursor h a -> DecodeResult f (JCursor h a)
moveRightN Natural
n JCursor h a
cur =
  ZipperMove -> Maybe (JCursor h a) -> DecodeResult f (JCursor h a)
forall (f :: * -> *) h s.
Monad f =>
ZipperMove -> Maybe (JCursor h s) -> DecodeResult f (JCursor h s)
moveAndKeepHistory (Natural -> ZipperMove
R Natural
n) ((JCursor h a -> Maybe (JCursor h a))
-> Int -> JCursor h a -> Maybe (JCursor h a)
forall (m :: * -> *) a.
MonadFail m =>
(a -> m a) -> Int -> a -> m a
Z.jerks JCursor h a -> Maybe (JCursor h a)
forall (m :: * -> *) h a i.
MonadPlus m =>
(h :> (a :@ i)) -> m (h :> (a :@ i))
Z.rightward (Natural
n Natural -> Getting Int Natural Int -> Int
forall s a. s -> Getting a s a -> a
^. AReview Int Natural -> Getter Natural Int
forall t b. AReview t b -> Getter b t
re AReview Int Natural
forall a. AsNatural a => Prism' a Natural
_Natural) JCursor h a
cur)

-- | From the current cursor location, try to move 1 step to the left.
moveLeft1
  :: Monad f
  => JCursor h a
  -> DecodeResult f (JCursor h a)
moveLeft1 :: JCursor h a -> DecodeResult f (JCursor h a)
moveLeft1 =
  Natural -> JCursor h a -> DecodeResult f (JCursor h a)
forall (f :: * -> *) h a.
Monad f =>
Natural -> JCursor h a -> DecodeResult f (JCursor h a)
moveLeftN (Natural -> Natural
successor' Natural
zero')

-- | From the current cursor location, try to move 1 step to the right.
moveRight1
  :: Monad f
  => JCursor h a
  -> DecodeResult f (JCursor h a)
moveRight1 :: JCursor h a -> DecodeResult f (JCursor h a)
moveRight1 =
  Natural -> JCursor h a -> DecodeResult f (JCursor h a)
forall (f :: * -> *) h a.
Monad f =>
Natural -> JCursor h a -> DecodeResult f (JCursor h a)
moveRightN (Natural -> Natural
successor' Natural
zero')

-- | Provide a @conversion@ function and create a 'Decoder' that uses the
-- current cursor and runs the given function. Fails with 'ConversionFailure' and
-- the given 'Text' description.
atCursor
  :: Monad f
  => Text
  -> (Json -> Maybe b)
  -> Decoder f b
atCursor :: Text -> (Json -> Maybe b) -> Decoder f b
atCursor Text
t Json -> Maybe b
f = (forall h. JCursor h Json -> DecodeResult f b) -> Decoder f b
forall (f :: * -> *) a.
(forall h. JCursor h Json -> DecodeResult f a) -> Decoder f a
withCursor ((forall h. JCursor h Json -> DecodeResult f b) -> Decoder f b)
-> (forall h. JCursor h Json -> DecodeResult f b) -> Decoder f b
forall a b. (a -> b) -> a -> b
$ \JCursor h Json
c -> do
  b
b <- JCursor h Json
c JCursor h Json
-> Getting (Either Text b) (JCursor h Json) (Either Text b)
-> Either Text b
forall s a. s -> Getting a s a -> a
^. (Json -> Const (Either Text b) Json)
-> JCursor h Json -> Const (Either Text b) (JCursor h Json)
forall i h a. IndexedLens' i (Zipper h i a) a
Z.focus ((Json -> Const (Either Text b) Json)
 -> JCursor h Json -> Const (Either Text b) (JCursor h Json))
-> ((Either Text b -> Const (Either Text b) (Either Text b))
    -> Json -> Const (Either Text b) Json)
-> Getting (Either Text b) (JCursor h Json) (Either Text b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Json -> Either Text b)
-> (Either Text b -> Const (Either Text b) (Either Text b))
-> Json
-> Const (Either Text b) Json
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
L.to (Text -> Maybe b -> Either Text b
forall a b. a -> Maybe b -> Either a b
note Text
t (Maybe b -> Either Text b)
-> (Json -> Maybe b) -> Json -> Either Text b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Json -> Maybe b
f) Either Text b -> (Text -> DecodeError) -> DecodeResult f b
forall (m :: * -> *) (t :: * -> *) e e' a.
HoistError m t e e' =>
t a -> (e -> e') -> m a
<%?> Text -> DecodeError
ConversionFailure
  b
b b -> DecodeResult f () -> DecodeResult f b
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ZipperMove -> Int -> DecodeResult f ()
forall i (m :: * -> *).
MonadState (CursorHistory' i) m =>
ZipperMove -> i -> m ()
DR.recordZipperMove (Text -> ZipperMove
Item Text
t) (JCursor h Json -> Int
forall h i a. Zipper h i a -> Int
Z.tooth JCursor h Json
c)

-- | From the current cursor position, try to move to the value for the first
-- occurence of that key. This move expects that you've positioned the cursor on an
-- object.
moveToKey
  :: ( AsJType s ws s
     , Monad f
     )
  => Text
  -> JCursor h s
  -> DecodeResult f (h :>> s :>> Elems ws (JAssoc ws s) :>> JAssoc ws s :>> s)
moveToKey :: Text
-> JCursor h s
-> DecodeResult
     f
     (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s)
moveToKey Text
k =
  ZipperMove
-> Maybe
     (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s)
-> DecodeResult
     f
     (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s)
forall (f :: * -> *) h s.
Monad f =>
ZipperMove -> Maybe (JCursor h s) -> DecodeResult f (JCursor h s)
moveAndKeepHistory (Text -> ZipperMove
DAt Text
k)
  (Maybe
   (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s)
 -> DecodeResult
      f
      (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s))
-> (JCursor h s
    -> Maybe
         (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s))
-> JCursor h s
-> DecodeResult
     f
     (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ( LensLike'
  (Indexing (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))))
  s
  (Elems ws (JAssoc ws s))
-> (h :> (s :@ Int))
-> Maybe ((h :> (s :@ Int)) :>> Elems ws (JAssoc ws s))
forall (m :: * -> *) a s h j.
MonadPlus m =>
LensLike' (Indexing (Bazaar' (Indexed Int) a)) s a
-> (h :> (s :@ j)) -> m ((h :> (s :@ j)) :>> a)
Z.within LensLike'
  (Indexing (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))))
  s
  (Elems ws (JAssoc ws s))
intoElems
      (JCursor h s -> Maybe (JCursor h s :>> Elems ws (JAssoc ws s)))
-> ((JCursor h s :>> Elems ws (JAssoc ws s))
    -> Maybe
         (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s))
-> JCursor h s
-> Maybe
     (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LensLike'
  (Indexing (Bazaar' (Indexed Int) (JAssoc ws s)))
  (Elems ws (JAssoc ws s))
  (JAssoc ws s)
-> (JCursor h s :> (Elems ws (JAssoc ws s) :@ Int))
-> Maybe
     ((JCursor h s :> (Elems ws (JAssoc ws s) :@ Int)) :>> JAssoc ws s)
forall (m :: * -> *) a s h j.
MonadPlus m =>
LensLike' (Indexing (Bazaar' (Indexed Int) a)) s a
-> (h :> (s :@ j)) -> m ((h :> (s :@ j)) :>> a)
Z.within LensLike'
  (Indexing (Bazaar' (Indexed Int) (JAssoc ws s)))
  (Elems ws (JAssoc ws s))
  (JAssoc ws s)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
      ((JCursor h s :>> Elems ws (JAssoc ws s))
 -> Maybe
      ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s))
-> (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
    -> Maybe
         (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s))
-> (JCursor h s :>> Elems ws (JAssoc ws s))
-> Maybe
     (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
-> Maybe ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
shuffleToKey
      (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
 -> Maybe
      ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s))
-> (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
    -> Maybe
         (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s))
-> ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
-> Maybe
     (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LensLike' (Indexing (Bazaar' (Indexed Int) s)) (JAssoc ws s) s
-> ((JCursor h s :>> Elems ws (JAssoc ws s))
    :> (JAssoc ws s :@ Int))
-> Maybe
     (((JCursor h s :>> Elems ws (JAssoc ws s)) :> (JAssoc ws s :@ Int))
      :>> s)
forall (m :: * -> *) a s h j.
MonadPlus m =>
LensLike' (Indexing (Bazaar' (Indexed Int) a)) s a
-> (h :> (s :@ j)) -> m ((h :> (s :@ j)) :>> a)
Z.within LensLike' (Indexing (Bazaar' (Indexed Int) s)) (JAssoc ws s) s
forall c ws a. HasJAssoc c ws a => Lens' c a
WT.jsonAssocVal
    )
  where
    shuffleToKey :: ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
-> Maybe ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
shuffleToKey (JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s
cu = LensLike'
  (Indexing (Bazaar' (Indexed Int) (JString' HeXDigit)))
  (JAssoc ws s)
  (JString' HeXDigit)
-> ((JCursor h s :>> Elems ws (JAssoc ws s))
    :> (JAssoc ws s :@ Int))
-> Maybe
     (((JCursor h s :>> Elems ws (JAssoc ws s)) :> (JAssoc ws s :@ Int))
      :>> JString' HeXDigit)
forall (m :: * -> *) a s h j.
MonadPlus m =>
LensLike' (Indexing (Bazaar' (Indexed Int) a)) s a
-> (h :> (s :@ j)) -> m ((h :> (s :@ j)) :>> a)
Z.within LensLike'
  (Indexing (Bazaar' (Indexed Int) (JString' HeXDigit)))
  (JAssoc ws s)
  (JString' HeXDigit)
forall c ws a. HasJAssoc c ws a => Lens' c (JString' HeXDigit)
WT.jsonAssocKey (JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s
(JCursor h s :>> Elems ws (JAssoc ws s)) :> (JAssoc ws s :@ Int)
cu Maybe
  (Zipper
     ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
     Int
     (JString' HeXDigit))
-> Getting
     (First Text)
     (Maybe
        (Zipper
           ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
           Int
           (JString' HeXDigit)))
     Text
-> Maybe Text
forall s a. s -> Getting (First a) s a -> Maybe a
^? (Zipper
   ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
   Int
   (JString' HeXDigit)
 -> Const
      (First Text)
      (Zipper
         ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
         Int
         (JString' HeXDigit)))
-> Maybe
     (Zipper
        ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
        Int
        (JString' HeXDigit))
-> Const
     (First Text)
     (Maybe
        (Zipper
           ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
           Int
           (JString' HeXDigit)))
forall a b. Prism (Maybe a) (Maybe b) a b
L._Just ((Zipper
    ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
    Int
    (JString' HeXDigit)
  -> Const
       (First Text)
       (Zipper
          ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
          Int
          (JString' HeXDigit)))
 -> Maybe
      (Zipper
         ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
         Int
         (JString' HeXDigit))
 -> Const
      (First Text)
      (Maybe
         (Zipper
            ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
            Int
            (JString' HeXDigit))))
-> ((Text -> Const (First Text) Text)
    -> Zipper
         ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
         Int
         (JString' HeXDigit)
    -> Const
         (First Text)
         (Zipper
            ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
            Int
            (JString' HeXDigit)))
-> Getting
     (First Text)
     (Maybe
        (Zipper
           ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
           Int
           (JString' HeXDigit)))
     Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JString' HeXDigit -> Const (First Text) (JString' HeXDigit))
-> Zipper
     ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
     Int
     (JString' HeXDigit)
-> Const
     (First Text)
     (Zipper
        ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
        Int
        (JString' HeXDigit))
forall i h a. IndexedLens' i (Zipper h i a) a
Z.focus ((JString' HeXDigit -> Const (First Text) (JString' HeXDigit))
 -> Zipper
      ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
      Int
      (JString' HeXDigit)
 -> Const
      (First Text)
      (Zipper
         ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
         Int
         (JString' HeXDigit)))
-> ((Text -> Const (First Text) Text)
    -> JString' HeXDigit -> Const (First Text) (JString' HeXDigit))
-> (Text -> Const (First Text) Text)
-> Zipper
     ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
     Int
     (JString' HeXDigit)
-> Const
     (First Text)
     (Zipper
        ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
        Int
        (JString' HeXDigit))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Const (First Text) Text)
-> JString' HeXDigit -> Const (First Text) (JString' HeXDigit)
forall (p :: * -> * -> *) (f :: * -> *).
(Profunctor p, Applicative f) =>
p Text (f Text) -> p (JString' HeXDigit) (f (JString' HeXDigit))
WT._JStringText
      Maybe Text
-> (Text
    -> Maybe
         ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s))
-> Maybe ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
-> Maybe ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
-> Bool
-> Maybe ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
forall a. a -> a -> Bool -> a
Bool.bool (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
-> Maybe ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
forall a. a -> Maybe a
Just (JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s
cu) (((JCursor h s :>> Elems ws (JAssoc ws s)) :> (JAssoc ws s :@ Int))
-> Maybe
     ((JCursor h s :>> Elems ws (JAssoc ws s)) :> (JAssoc ws s :@ Int))
forall (m :: * -> *) h a i.
MonadPlus m =>
(h :> (a :@ i)) -> m (h :> (a :@ i))
Z.rightward (JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s
(JCursor h s :>> Elems ws (JAssoc ws s)) :> (JAssoc ws s :@ Int)
cu Maybe ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
-> (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
    -> Maybe
         ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s))
-> Maybe ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
-> Maybe ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
shuffleToKey) (Bool
 -> Maybe
      ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s))
-> (Text -> Bool)
-> Text
-> Maybe ((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
/=Text
k)

    intoElems :: LensLike'
  (Indexing (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))))
  s
  (Elems ws (JAssoc ws s))
intoElems = ((JObject ws s, ws)
 -> Indexing
      (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
      (JObject ws s, ws))
-> s -> Indexing (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))) s
forall r ws a. AsJType r ws a => Prism' r (JObject ws a, ws)
WT._JObj (((JObject ws s, ws)
  -> Indexing
       (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
       (JObject ws s, ws))
 -> s
 -> Indexing (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))) s)
-> ((Elems ws (JAssoc ws s)
     -> Indexing
          (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
          (Elems ws (JAssoc ws s)))
    -> (JObject ws s, ws)
    -> Indexing
         (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
         (JObject ws s, ws))
-> LensLike'
     (Indexing (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))))
     s
     (Elems ws (JAssoc ws s))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (JObject ws s
 -> Indexing
      (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))) (JObject ws s))
-> (JObject ws s, ws)
-> Indexing
     (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))) (JObject ws s, ws)
forall s t a b. Field1 s t a b => Lens s t a b
L._1 ((JObject ws s
  -> Indexing
       (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))) (JObject ws s))
 -> (JObject ws s, ws)
 -> Indexing
      (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
      (JObject ws s, ws))
-> ((Elems ws (JAssoc ws s)
     -> Indexing
          (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
          (Elems ws (JAssoc ws s)))
    -> JObject ws s
    -> Indexing
         (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))) (JObject ws s))
-> (Elems ws (JAssoc ws s)
    -> Indexing
         (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
         (Elems ws (JAssoc ws s)))
-> (JObject ws s, ws)
-> Indexing
     (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))) (JObject ws s, ws)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CommaSeparated ws (JAssoc ws s)
 -> Indexing
      (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
      (CommaSeparated ws (JAssoc ws s)))
-> JObject ws s
-> Indexing
     (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))) (JObject ws s)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
L._Wrapped ((CommaSeparated ws (JAssoc ws s)
  -> Indexing
       (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
       (CommaSeparated ws (JAssoc ws s)))
 -> JObject ws s
 -> Indexing
      (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))) (JObject ws s))
-> ((Elems ws (JAssoc ws s)
     -> Indexing
          (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
          (Elems ws (JAssoc ws s)))
    -> CommaSeparated ws (JAssoc ws s)
    -> Indexing
         (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
         (CommaSeparated ws (JAssoc ws s)))
-> (Elems ws (JAssoc ws s)
    -> Indexing
         (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
         (Elems ws (JAssoc ws s)))
-> JObject ws s
-> Indexing
     (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s))) (JObject ws s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((ws, Maybe (Elems ws (JAssoc ws s)))
 -> Indexing
      (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
      (ws, Maybe (Elems ws (JAssoc ws s))))
-> CommaSeparated ws (JAssoc ws s)
-> Indexing
     (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
     (CommaSeparated ws (JAssoc ws s))
forall ws a ws' b.
Iso
  (CommaSeparated ws a)
  (CommaSeparated ws' b)
  (ws, Maybe (Elems ws a))
  (ws', Maybe (Elems ws' b))
WT._CommaSeparated (((ws, Maybe (Elems ws (JAssoc ws s)))
  -> Indexing
       (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
       (ws, Maybe (Elems ws (JAssoc ws s))))
 -> CommaSeparated ws (JAssoc ws s)
 -> Indexing
      (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
      (CommaSeparated ws (JAssoc ws s)))
-> ((Elems ws (JAssoc ws s)
     -> Indexing
          (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
          (Elems ws (JAssoc ws s)))
    -> (ws, Maybe (Elems ws (JAssoc ws s)))
    -> Indexing
         (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
         (ws, Maybe (Elems ws (JAssoc ws s))))
-> (Elems ws (JAssoc ws s)
    -> Indexing
         (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
         (Elems ws (JAssoc ws s)))
-> CommaSeparated ws (JAssoc ws s)
-> Indexing
     (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
     (CommaSeparated ws (JAssoc ws s))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe (Elems ws (JAssoc ws s))
 -> Indexing
      (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
      (Maybe (Elems ws (JAssoc ws s))))
-> (ws, Maybe (Elems ws (JAssoc ws s)))
-> Indexing
     (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
     (ws, Maybe (Elems ws (JAssoc ws s)))
forall s t a b. Field2 s t a b => Lens s t a b
L._2 ((Maybe (Elems ws (JAssoc ws s))
  -> Indexing
       (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
       (Maybe (Elems ws (JAssoc ws s))))
 -> (ws, Maybe (Elems ws (JAssoc ws s)))
 -> Indexing
      (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
      (ws, Maybe (Elems ws (JAssoc ws s))))
-> ((Elems ws (JAssoc ws s)
     -> Indexing
          (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
          (Elems ws (JAssoc ws s)))
    -> Maybe (Elems ws (JAssoc ws s))
    -> Indexing
         (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
         (Maybe (Elems ws (JAssoc ws s))))
-> (Elems ws (JAssoc ws s)
    -> Indexing
         (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
         (Elems ws (JAssoc ws s)))
-> (ws, Maybe (Elems ws (JAssoc ws s)))
-> Indexing
     (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
     (ws, Maybe (Elems ws (JAssoc ws s)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Elems ws (JAssoc ws s)
 -> Indexing
      (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
      (Elems ws (JAssoc ws s)))
-> Maybe (Elems ws (JAssoc ws s))
-> Indexing
     (Bazaar' (Indexed Int) (Elems ws (JAssoc ws s)))
     (Maybe (Elems ws (JAssoc ws s)))
forall a b. Prism (Maybe a) (Maybe b) a b
L._Just

-- | Move to the first occurence of this key, as per 'moveToKey' and then
-- attempt to run the given 'Decoder' on that value, returning the result.
--
-- @
-- ...
-- txtVal <- fromKey "foo" text c
-- ...
-- @
--
fromKey
  :: ( Monad f
     )
  => Text
  -> Decoder f b
  -> JCursor h Json
  -> DecodeResult f b
fromKey :: Text -> Decoder f b -> JCursor h Json -> DecodeResult f b
fromKey Text
k Decoder f b
d =
  Text
-> JCursor h Json
-> DecodeResult
     f
     (((JCursor h Json :>> Elems WS (JAssoc WS Json))
       :>> JAssoc WS Json)
      :>> Json)
forall s ws (f :: * -> *) h.
(AsJType s ws s, Monad f) =>
Text
-> JCursor h s
-> DecodeResult
     f
     (((JCursor h s :>> Elems ws (JAssoc ws s)) :>> JAssoc ws s) :>> s)
moveToKey Text
k (JCursor h Json
 -> DecodeResult
      f
      (((JCursor h Json :>> Elems WS (JAssoc WS Json))
        :>> JAssoc WS Json)
       :>> Json))
-> ((((JCursor h Json :>> Elems WS (JAssoc WS Json))
      :>> JAssoc WS Json)
     :>> Json)
    -> DecodeResult f b)
-> JCursor h Json
-> DecodeResult f b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> Decoder f b
-> (((JCursor h Json :>> Elems WS (JAssoc WS Json))
     :>> JAssoc WS Json)
    :>> Json)
-> DecodeResult f b
forall (f :: * -> *) a h.
Decoder f a -> JCursor h Json -> DecodeResult f a
runDecoder Decoder f b
d

-- | A simplified version of 'fromKey' that takes a 'Text' value indicating a
-- key to be moved to and decoded using the given 'Decoder f a'. If you don't
-- need any special cursor movements to reach the list of keys you require, you
-- could use this function to build a trivial 'Decoder' for a record type:
--
-- @
-- data MyRec = MyRec { fieldA :: Text, fieldB :: Int }
--
-- myRecDecoder :: Decoder f MyRec
-- myRecDecoder = MyRec
--   <$> atKey \"field_a\" text
--   <*> atKey \"field_b\" int
-- @
--
atKey
  :: Monad f
  => Text
  -> Decoder f a
  -> Decoder f a
atKey :: Text -> Decoder f a -> Decoder f a
atKey Text
k Decoder f a
d =
  (forall h. JCursor h Json -> DecodeResult f a) -> Decoder f a
forall (f :: * -> *) a.
(forall h. JCursor h Json -> DecodeResult f a) -> Decoder f a
withCursor (Text -> Decoder f a -> JCursor h Json -> DecodeResult f a
forall (f :: * -> *) b h.
Monad f =>
Text -> Decoder f b -> JCursor h Json -> DecodeResult f b
fromKey Text
k Decoder f a
d)

-- | Decoder for 'Scientific'
scientific :: Monad f => Decoder f Scientific
scientific :: Decoder f Scientific
scientific = Text -> (Json -> Maybe Scientific) -> Decoder f Scientific
forall (f :: * -> *) b.
Monad f =>
Text -> (Json -> Maybe b) -> Decoder f b
atCursor Text
"Scientific" Json -> Maybe Scientific
forall a ws. AsJType a ws a => a -> Maybe Scientific
DR.scientific'

-- | Decoder for a bounded integral value.
integral :: (Bounded i, Integral i, Monad f) => Decoder f i
integral :: Decoder f i
integral = Text -> (Json -> Maybe i) -> Decoder f i
forall (f :: * -> *) b.
Monad f =>
Text -> (Json -> Maybe b) -> Decoder f b
atCursor Text
"Integral" Json -> Maybe i
forall i a ws.
(Bounded i, Integral i, AsJType a ws a) =>
a -> Maybe i
DR.integral'

-- | Decoder for 'Int'
int :: Monad f => Decoder f Int
int :: Decoder f Int
int = Text -> (Json -> Maybe Int) -> Decoder f Int
forall (f :: * -> *) b.
Monad f =>
Text -> (Json -> Maybe b) -> Decoder f b
atCursor Text
"Int" Json -> Maybe Int
forall a ws. AsJType a ws a => a -> Maybe Int
DR.int'

-- | Decoder for 'Bool'
bool :: Monad f => Decoder f Bool
bool :: Decoder f Bool
bool = Text -> (Json -> Maybe Bool) -> Decoder f Bool
forall (f :: * -> *) b.
Monad f =>
Text -> (Json -> Maybe b) -> Decoder f b
atCursor Text
"Bool" Json -> Maybe Bool
forall a ws. AsJType a ws a => a -> Maybe Bool
DR.bool'

-- | Decoder for 'Text', as per the 'Text' documentation any unacceptable utf8 characters will be replaced.
text :: Monad f => Decoder f Text
text :: Decoder f Text
text = Text -> (Json -> Maybe Text) -> Decoder f Text
forall (f :: * -> *) b.
Monad f =>
Text -> (Json -> Maybe b) -> Decoder f b
atCursor Text
"Text" Json -> Maybe Text
forall a ws. AsJType a ws a => a -> Maybe Text
DR.text'

-- | Decoder for 'String'
string :: Monad f => Decoder f String
string :: Decoder f String
string = Text -> (Json -> Maybe String) -> Decoder f String
forall (f :: * -> *) b.
Monad f =>
Text -> (Json -> Maybe b) -> Decoder f b
atCursor Text
"String" Json -> Maybe String
forall a ws. AsJType a ws a => a -> Maybe String
DR.string'

-- | Decoder for 'null'
null :: Monad f => Decoder f ()
null :: Decoder f ()
null = Text -> (Json -> Maybe ()) -> Decoder f ()
forall (f :: * -> *) b.
Monad f =>
Text -> (Json -> Maybe b) -> Decoder f b
atCursor Text
"null" Json -> Maybe ()
forall a ws. AsJType a ws a => a -> Maybe ()
DR.null'

-- | Decoder for a 'Char' value that cannot contain values in the range U+D800
-- to U+DFFF. This decoder will fail if the 'Char' is outside of this range.
boundedChar :: Monad f => Decoder f Char
boundedChar :: Decoder f Char
boundedChar = Text -> (Json -> Maybe Char) -> Decoder f Char
forall (f :: * -> *) b.
Monad f =>
Text -> (Json -> Maybe b) -> Decoder f b
atCursor Text
"Bounded Char" Json -> Maybe Char
forall a ws. AsJType a ws a => a -> Maybe Char
DR.boundedChar'

-- | Decoder for a Haskell 'Char' value whose values represent Unicode
-- (or equivalently ISO/IEC 10646) characters.
unboundedChar :: Monad f => Decoder f Char
unboundedChar :: Decoder f Char
unboundedChar = Text -> (Json -> Maybe Char) -> Decoder f Char
forall (f :: * -> *) b.
Monad f =>
Text -> (Json -> Maybe b) -> Decoder f b
atCursor Text
"Unbounded Char" Json -> Maybe Char
forall a ws. AsJType a ws a => a -> Maybe Char
DR.unboundedChar'

-- | Decoder for pulling out the 'Json' Haskell data structure at the current cursor.
json :: Monad f => Decoder f Json
json :: Decoder f Json
json = Text -> (Json -> Maybe Json) -> Decoder f Json
forall (f :: * -> *) b.
Monad f =>
Text -> (Json -> Maybe b) -> Decoder f b
atCursor Text
"JSON" Json -> Maybe Json
forall (f :: * -> *) a. Applicative f => a -> f a
pure

-- | Try to decode the value at the current focus using the given 'Decoder'.
focus
  :: Decoder f a
  -> JCursor h Json
  -> DecodeResult f a
focus :: Decoder f a -> JCursor h Json -> DecodeResult f a
focus =
  Decoder f a -> JCursor h Json -> DecodeResult f a
forall (f :: * -> *) a h.
Decoder f a -> JCursor h Json -> DecodeResult f a
runDecoder

-- | Allows for folding over the results of repeated cursor movements.
--
-- @
-- intList :: Decoder f [String]
-- intList = withCursor $ \curs ->
--   foldCursor [] (\acc a -> acc <> [a]) moveRight1 string curs
-- @
--
foldCursor
  :: Monad f
  => s
  -> (s -> a -> s)
  -> (JCursor h Json -> DecodeResult f (JCursor h Json))
  -> Decoder f a
  -> JCursor h Json
  -> DecodeResult f s
foldCursor :: s
-> (s -> a -> s)
-> (JCursor h Json -> DecodeResult f (JCursor h Json))
-> Decoder f a
-> JCursor h Json
-> DecodeResult f s
foldCursor s
s s -> a -> s
sas JCursor h Json -> DecodeResult f (JCursor h Json)
mvCurs Decoder f a
elemD = DecodeResultT Int DecodeError f s -> DecodeResult f s
forall (f :: * -> *) a.
DecodeResultT Int DecodeError f a -> DecodeResult f a
DecodeResult
  (DecodeResultT Int DecodeError f s -> DecodeResult f s)
-> (JCursor h Json -> DecodeResultT Int DecodeError f s)
-> JCursor h Json
-> DecodeResult f s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s
-> (s -> a -> s)
-> (JCursor h Json
    -> DecodeResultT Int DecodeError f (JCursor h Json))
-> Decoder' (JCursor h Json) Int DecodeError f a
-> JCursor h Json
-> DecodeResultT Int DecodeError f s
forall (f :: * -> *) b a c i e.
Monad f =>
b
-> (b -> a -> b)
-> (c -> DecodeResultT i e f c)
-> Decoder' c i e f a
-> c
-> DecodeResultT i e f b
DR.foldCursor'
    s
s
    s -> a -> s
sas
    (DecodeResult f (JCursor h Json)
-> DecodeResultT Int DecodeError f (JCursor h Json)
forall (f :: * -> *) a.
DecodeResult f a -> DecodeResultT Int DecodeError f a
unDecodeResult (DecodeResult f (JCursor h Json)
 -> DecodeResultT Int DecodeError f (JCursor h Json))
-> (JCursor h Json -> DecodeResult f (JCursor h Json))
-> JCursor h Json
-> DecodeResultT Int DecodeError f (JCursor h Json)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JCursor h Json -> DecodeResult f (JCursor h Json)
mvCurs)
    Decoder' (JCursor h Json) Int DecodeError f a
Decoder f a
elemD

-- | Use the 'Cons' typeclass and move leftwards from the current cursor
-- position, "consing" the values to the @s@ as it moves.
leftwardCons
  :: ( Monad f
     , Cons s s a a
     )
  => s
  -> Decoder f a
  -> JCursor h Json
  -> DecodeResult f s
leftwardCons :: s -> Decoder f a -> JCursor h Json -> DecodeResult f s
leftwardCons s
s Decoder f a
elemD = DecodeResultT Int DecodeError f s -> DecodeResult f s
forall (f :: * -> *) a.
DecodeResultT Int DecodeError f a -> DecodeResult f a
DecodeResult
  (DecodeResultT Int DecodeError f s -> DecodeResult f s)
-> (JCursor h Json -> DecodeResultT Int DecodeError f s)
-> JCursor h Json
-> DecodeResult f s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s
-> (s -> a -> s)
-> (JCursor h Json
    -> DecodeResultT Int DecodeError f (JCursor h Json))
-> Decoder' (JCursor h Json) Int DecodeError f a
-> JCursor h Json
-> DecodeResultT Int DecodeError f s
forall (f :: * -> *) b a c i e.
Monad f =>
b
-> (b -> a -> b)
-> (c -> DecodeResultT i e f c)
-> Decoder' c i e f a
-> c
-> DecodeResultT i e f b
DR.foldCursor' s
s
    ((a -> s -> s) -> s -> a -> s
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> s -> s
forall s a. Cons s s a a => a -> s -> s
L.cons)
    (DecodeResult f (JCursor h Json)
-> DecodeResultT Int DecodeError f (JCursor h Json)
forall (f :: * -> *) a.
DecodeResult f a -> DecodeResultT Int DecodeError f a
unDecodeResult (DecodeResult f (JCursor h Json)
 -> DecodeResultT Int DecodeError f (JCursor h Json))
-> (JCursor h Json -> DecodeResult f (JCursor h Json))
-> JCursor h Json
-> DecodeResultT Int DecodeError f (JCursor h Json)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JCursor h Json -> DecodeResult f (JCursor h Json)
forall (f :: * -> *) h a.
Monad f =>
JCursor h a -> DecodeResult f (JCursor h a)
moveLeft1)
    Decoder' (JCursor h Json) Int DecodeError f a
Decoder f a
elemD

-- | Use the 'Snoc' typeclass and move rightwards from the current cursor
-- position, "snocing" the values to the @s@ as it moves.
rightwardSnoc
  :: ( Monad f
     , Snoc s s a a
     )
  => s
  -> Decoder f a
  -> JCursor h Json
  -> DecodeResult f s
rightwardSnoc :: s -> Decoder f a -> JCursor h Json -> DecodeResult f s
rightwardSnoc s
s Decoder f a
elemD = DecodeResultT Int DecodeError f s -> DecodeResult f s
forall (f :: * -> *) a.
DecodeResultT Int DecodeError f a -> DecodeResult f a
DecodeResult
  (DecodeResultT Int DecodeError f s -> DecodeResult f s)
-> (JCursor h Json -> DecodeResultT Int DecodeError f s)
-> JCursor h Json
-> DecodeResult f s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s
-> (s -> a -> s)
-> (JCursor h Json
    -> DecodeResultT Int DecodeError f (JCursor h Json))
-> Decoder' (JCursor h Json) Int DecodeError f a
-> JCursor h Json
-> DecodeResultT Int DecodeError f s
forall (f :: * -> *) b a c i e.
Monad f =>
b
-> (b -> a -> b)
-> (c -> DecodeResultT i e f c)
-> Decoder' c i e f a
-> c
-> DecodeResultT i e f b
DR.foldCursor' s
s
    s -> a -> s
forall s a. Snoc s s a a => s -> a -> s
L.snoc
    (DecodeResult f (JCursor h Json)
-> DecodeResultT Int DecodeError f (JCursor h Json)
forall (f :: * -> *) a.
DecodeResult f a -> DecodeResultT Int DecodeError f a
unDecodeResult (DecodeResult f (JCursor h Json)
 -> DecodeResultT Int DecodeError f (JCursor h Json))
-> (JCursor h Json -> DecodeResult f (JCursor h Json))
-> JCursor h Json
-> DecodeResultT Int DecodeError f (JCursor h Json)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JCursor h Json -> DecodeResult f (JCursor h Json)
forall (f :: * -> *) h a.
Monad f =>
JCursor h a -> DecodeResult f (JCursor h a)
moveRight1)
    Decoder' (JCursor h Json) Int DecodeError f a
Decoder f a
elemD

-- | Decode a 'NonEmpty' list of @a@ at the given cursor position.
nonEmptyAt
  :: Monad f
  => Decoder f a
  -> JCursor h Json
  -> DecodeResult f (NonEmpty a)
nonEmptyAt :: Decoder f a -> JCursor h Json -> DecodeResult f (NonEmpty a)
nonEmptyAt Decoder f a
elemD JCursor h Json
c =
  ZipperMove
-> Maybe (JCursor (JCursor h Json) Json)
-> DecodeResult f (JCursor (JCursor h Json) Json)
forall (f :: * -> *) h s.
Monad f =>
ZipperMove -> Maybe (JCursor h s) -> DecodeResult f (JCursor h s)
moveAndKeepHistory ZipperMove
D (JCursorMove Json Json
-> (h :> (Json :@ Int)) -> Maybe ((h :> (Json :@ Int)) :>> Json)
forall (m :: * -> *) a s h j.
MonadPlus m =>
LensLike' (Indexing (Bazaar' (Indexed Int) a)) s a
-> (h :> (s :@ j)) -> m ((h :> (s :@ j)) :>> a)
Z.within JCursorMove Json Json
Traversal' Json Json
WT.jsonTraversal JCursor h Json
h :> (Json :@ Int)
c)
  DecodeResult f (JCursor (JCursor h Json) Json)
-> (JCursor (JCursor h Json) Json -> DecodeResult f (NonEmpty a))
-> DecodeResult f (NonEmpty a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \JCursor (JCursor h Json) Json
curs -> do
    a
h <- Decoder f a -> JCursor (JCursor h Json) Json -> DecodeResult f a
forall (f :: * -> *) a h.
Decoder f a -> JCursor h Json -> DecodeResult f a
focus Decoder f a
elemD JCursor (JCursor h Json) Json
curs
    JCursor (JCursor h Json) Json
-> DecodeResult f (JCursor (JCursor h Json) Json)
forall (f :: * -> *) h a.
Monad f =>
JCursor h a -> DecodeResult f (JCursor h a)
moveRight1 JCursor (JCursor h Json) Json
curs DecodeResult f (JCursor (JCursor h Json) Json)
-> (JCursor (JCursor h Json) Json -> DecodeResult f (NonEmpty a))
-> DecodeResult f (NonEmpty a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ([a] -> NonEmpty a)
-> DecodeResult f [a] -> DecodeResult f (NonEmpty a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a
ha -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:|) (DecodeResult f [a] -> DecodeResult f (NonEmpty a))
-> (JCursor (JCursor h Json) Json -> DecodeResult f [a])
-> JCursor (JCursor h Json) Json
-> DecodeResult f (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a]
-> Decoder f a
-> JCursor (JCursor h Json) Json
-> DecodeResult f [a]
forall (f :: * -> *) s a h.
(Monad f, Snoc s s a a) =>
s -> Decoder f a -> JCursor h Json -> DecodeResult f s
rightwardSnoc [] Decoder f a
elemD

-- | Create a 'Decoder' for a 'NonEmpty' list.
nonempty :: Monad f => Decoder f b -> Decoder f (NonEmpty b)
nonempty :: Decoder f b -> Decoder f (NonEmpty b)
nonempty Decoder f b
d = (forall h. JCursor h Json -> DecodeResult f (NonEmpty b))
-> Decoder f (NonEmpty b)
forall (f :: * -> *) a.
(forall h. JCursor h Json -> DecodeResult f a) -> Decoder f a
withCursor (Decoder f b -> JCursor h Json -> DecodeResult f (NonEmpty b)
forall (f :: * -> *) a h.
Monad f =>
Decoder f a -> JCursor h Json -> DecodeResult f (NonEmpty a)
nonEmptyAt Decoder f b
d)

-- | Decode a '[a]' at the current cursor position.
listAt
  :: Monad f
  => Decoder f a
  -> JCursor h Json
  -> DecodeResult f [a]
listAt :: Decoder f a -> JCursor h Json -> DecodeResult f [a]
listAt Decoder f a
elemD JCursor h Json
c =
  DecodeResult f (JCursor (JCursor h Json) Json)
-> DecodeResult f (Maybe (JCursor (JCursor h Json) Json))
forall e (m :: * -> *) a. MonadError e m => m a -> m (Maybe a)
try (ZipperMove
-> Maybe (JCursor (JCursor h Json) Json)
-> DecodeResult f (JCursor (JCursor h Json) Json)
forall (f :: * -> *) h s.
Monad f =>
ZipperMove -> Maybe (JCursor h s) -> DecodeResult f (JCursor h s)
moveAndKeepHistory ZipperMove
D (JCursorMove Json Json
-> (h :> (Json :@ Int)) -> Maybe ((h :> (Json :@ Int)) :>> Json)
forall (m :: * -> *) a s h j.
MonadPlus m =>
LensLike' (Indexing (Bazaar' (Indexed Int) a)) s a
-> (h :> (s :@ j)) -> m ((h :> (s :@ j)) :>> a)
Z.within JCursorMove Json Json
Traversal' Json Json
WT.jsonTraversal JCursor h Json
h :> (Json :@ Int)
c))
  DecodeResult f (Maybe (JCursor (JCursor h Json) Json))
-> (Maybe (JCursor (JCursor h Json) Json) -> DecodeResult f [a])
-> DecodeResult f [a]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= DecodeResult f [a]
-> (JCursor (JCursor h Json) Json -> DecodeResult f [a])
-> Maybe (JCursor (JCursor h Json) Json)
-> DecodeResult f [a]
forall b a. b -> (a -> b) -> Maybe a -> b
Maybe.maybe ([a] -> DecodeResult f [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [a]
forall a. Monoid a => a
mempty) ([a]
-> Decoder f a
-> JCursor (JCursor h Json) Json
-> DecodeResult f [a]
forall (f :: * -> *) s a h.
(Monad f, Snoc s s a a) =>
s -> Decoder f a -> JCursor h Json -> DecodeResult f s
rightwardSnoc [a]
forall a. Monoid a => a
mempty Decoder f a
elemD)

-- | Create a 'Decoder' for a list of @a@
list
  :: Monad f
  => Decoder f b
  -> Decoder f [b]
list :: Decoder f b -> Decoder f [b]
list Decoder f b
d =
  (forall h. JCursor h Json -> DecodeResult f [b]) -> Decoder f [b]
forall (f :: * -> *) a.
(forall h. JCursor h Json -> DecodeResult f a) -> Decoder f a
withCursor (Decoder f b -> JCursor h Json -> DecodeResult f [b]
forall (f :: * -> *) a h.
Monad f =>
Decoder f a -> JCursor h Json -> DecodeResult f [a]
listAt Decoder f b
d)

-- | Try to decode an optional value, returning the given default value if
-- 'Nothing' is returned.
withDefault
  :: Monad f
  => a
  -> Decoder f (Maybe a)
  -> Decoder f a
withDefault :: a -> Decoder f (Maybe a) -> Decoder f a
withDefault a
def Decoder f (Maybe a)
hasD =
  (forall h. JCursor h Json -> DecodeResult f a) -> Decoder f a
forall (f :: * -> *) a.
(forall h. JCursor h Json -> DecodeResult f a) -> Decoder f a
withCursor ((Maybe a -> a) -> DecodeResult f (Maybe a) -> DecodeResult f a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> Maybe a -> a
forall a. a -> Maybe a -> a
Maybe.fromMaybe a
def) (DecodeResult f (Maybe a) -> DecodeResult f a)
-> (JCursor h Json -> DecodeResult f (Maybe a))
-> JCursor h Json
-> DecodeResult f a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Decoder f (Maybe a) -> JCursor h Json -> DecodeResult f (Maybe a)
forall (f :: * -> *) a h.
Decoder f a -> JCursor h Json -> DecodeResult f a
focus Decoder f (Maybe a)
hasD)

-- | Named to match it's 'Waargonaut.Encode.Encoder' counterpart, this
-- function will decode an optional value.
maybeOrNull
  :: Monad f
  => Decoder f a
  -> Decoder f (Maybe a)
maybeOrNull :: Decoder f a -> Decoder f (Maybe a)
maybeOrNull Decoder f a
hasD =
  (forall h. JCursor h Json -> DecodeResult f (Maybe a))
-> Decoder f (Maybe a)
forall (f :: * -> *) a.
(forall h. JCursor h Json -> DecodeResult f a) -> Decoder f a
withCursor (DecodeResult f a -> DecodeResult f (Maybe a)
forall e (m :: * -> *) a. MonadError e m => m a -> m (Maybe a)
try (DecodeResult f a -> DecodeResult f (Maybe a))
-> (JCursor h Json -> DecodeResult f a)
-> JCursor h Json
-> DecodeResult f (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Decoder f a -> JCursor h Json -> DecodeResult f a
forall (f :: * -> *) a h.
Decoder f a -> JCursor h Json -> DecodeResult f a
focus Decoder f a
hasD)

-- | Decode either an @a@ or a @b@, failing if neither 'Decoder' succeeds. The
-- 'Right' decoder is attempted first.
either
  :: Monad f
  => Decoder f a
  -> Decoder f b
  -> Decoder f (Either a b)
either :: Decoder f a -> Decoder f b -> Decoder f (Either a b)
either Decoder f a
leftD Decoder f b
rightD =
  (forall h. JCursor h Json -> DecodeResult f (Either a b))
-> Decoder f (Either a b)
forall (f :: * -> *) a.
(forall h. JCursor h Json -> DecodeResult f a) -> Decoder f a
withCursor ((forall h. JCursor h Json -> DecodeResult f (Either a b))
 -> Decoder f (Either a b))
-> (forall h. JCursor h Json -> DecodeResult f (Either a b))
-> Decoder f (Either a b)
forall a b. (a -> b) -> a -> b
$ \JCursor h Json
c ->
    DecodeResult f (Either a b) -> DecodeResult f (Maybe (Either a b))
forall e (m :: * -> *) a. MonadError e m => m a -> m (Maybe a)
try (Decoder f (Either a b)
-> JCursor h Json -> DecodeResult f (Either a b)
forall (f :: * -> *) a h.
Decoder f a -> JCursor h Json -> DecodeResult f a
focus (b -> Either a b
forall a b. b -> Either a b
Right (b -> Either a b)
-> Decoder' (JCursor h Json) Int DecodeError f b
-> Decoder' (JCursor h Json) Int DecodeError f (Either a b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder' (JCursor h Json) Int DecodeError f b
Decoder f b
rightD) JCursor h Json
c) DecodeResult f (Maybe (Either a b))
-> (Maybe (Either a b) -> DecodeResult f (Either a b))
-> DecodeResult f (Either a b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
    DecodeResult f (Either a b)
-> (Either a b -> DecodeResult f (Either a b))
-> Maybe (Either a b)
-> DecodeResult f (Either a b)
forall b a. b -> (a -> b) -> Maybe a -> b
Maybe.maybe (Decoder f (Either a b)
-> JCursor h Json -> DecodeResult f (Either a b)
forall (f :: * -> *) a h.
Decoder f a -> JCursor h Json -> DecodeResult f a
focus (a -> Either a b
forall a b. a -> Either a b
Left (a -> Either a b)
-> Decoder' (JCursor h Json) Int DecodeError f a
-> Decoder' (JCursor h Json) Int DecodeError f (Either a b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder' (JCursor h Json) Int DecodeError f a
Decoder f a
leftD) JCursor h Json
c) Either a b -> DecodeResult f (Either a b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure