module Data.Hermes.Decoder.Path
  ( dot
  , removePath
  , withPath
  , withPathIndex
  ) where

import           Control.Monad.Reader (local)
import           Data.Maybe (fromMaybe)
import           Data.Text (Text)
import qualified Data.Text as T

import           Data.Hermes.Decoder.Types (Decoder, HermesEnv(hPath))

withPath :: Text -> Decoder a -> Decoder a
withPath :: Text -> Decoder a -> Decoder a
withPath Text
key =
  (HermesEnv -> HermesEnv) -> Decoder a -> Decoder a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local ((HermesEnv -> HermesEnv) -> Decoder a -> Decoder a)
-> (HermesEnv -> HermesEnv) -> Decoder a -> Decoder a
forall a b. (a -> b) -> a -> b
$ \HermesEnv
st -> HermesEnv
st { hPath :: Text
hPath = HermesEnv -> Text
hPath HermesEnv
st Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
key }
{-# INLINE withPath #-}

removePath :: Text -> Decoder a -> Decoder a
removePath :: Text -> Decoder a -> Decoder a
removePath Text
key =
  (HermesEnv -> HermesEnv) -> Decoder a -> Decoder a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local ((HermesEnv -> HermesEnv) -> Decoder a -> Decoder a)
-> (HermesEnv -> HermesEnv) -> Decoder a -> Decoder a
forall a b. (a -> b) -> a -> b
$ \HermesEnv
st -> HermesEnv
st { hPath :: Text
hPath = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe (HermesEnv -> Text
hPath HermesEnv
st) (Text -> Text -> Maybe Text
T.stripSuffix Text
key (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ HermesEnv -> Text
hPath HermesEnv
st) }
{-# INLINE removePath #-}

withPathIndex :: Int -> Decoder a -> Decoder a
withPathIndex :: Int -> Decoder a -> Decoder a
withPathIndex Int
idx =
  (HermesEnv -> HermesEnv) -> Decoder a -> Decoder a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local ((HermesEnv -> HermesEnv) -> Decoder a -> Decoder a)
-> (HermesEnv -> HermesEnv) -> Decoder a -> Decoder a
forall a b. (a -> b) -> a -> b
$ \HermesEnv
st -> HermesEnv
st
    { hPath :: Text
hPath = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe (HermesEnv -> Text
hPath HermesEnv
st) (Text -> Text -> Maybe Text
T.stripSuffix (Int -> Text
forall a. Show a => a -> Text
showInt (Int -> Text) -> Int -> Text
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int
idx Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ HermesEnv -> Text
hPath HermesEnv
st)
           Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showInt Int
idx
    }
  where showInt :: a -> Text
showInt a
i = Text -> Text
dot (Text -> Text) -> (String -> Text) -> String -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> String -> Text
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Show a => a -> String
show a
i
{-# INLINE withPathIndex #-}

dot :: Text -> Text
dot :: Text -> Text
dot = Char -> Text -> Text
T.cons Char
'/'
{-# INLINE dot #-}