{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ViewPatterns #-}
module Descriptive.Formlet
(
indexed
,FormletState(..)
,Formlet(..))
where
import Descriptive
import Control.Monad.State.Strict
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as M
import Data.Text (Text)
data Formlet
= Index !Integer
| Constrained !Text
deriving (Int -> Formlet -> ShowS
[Formlet] -> ShowS
Formlet -> String
(Int -> Formlet -> ShowS)
-> (Formlet -> String) -> ([Formlet] -> ShowS) -> Show Formlet
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Formlet] -> ShowS
$cshowList :: [Formlet] -> ShowS
show :: Formlet -> String
$cshow :: Formlet -> String
showsPrec :: Int -> Formlet -> ShowS
$cshowsPrec :: Int -> Formlet -> ShowS
Show,Formlet -> Formlet -> Bool
(Formlet -> Formlet -> Bool)
-> (Formlet -> Formlet -> Bool) -> Eq Formlet
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Formlet -> Formlet -> Bool
$c/= :: Formlet -> Formlet -> Bool
== :: Formlet -> Formlet -> Bool
$c== :: Formlet -> Formlet -> Bool
Eq)
data FormletState =
FormletState {FormletState -> Map Integer Text
formletMap :: (Map Integer Text)
,FormletState -> Integer
formletIndex :: !Integer}
deriving (Int -> FormletState -> ShowS
[FormletState] -> ShowS
FormletState -> String
(Int -> FormletState -> ShowS)
-> (FormletState -> String)
-> ([FormletState] -> ShowS)
-> Show FormletState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FormletState] -> ShowS
$cshowList :: [FormletState] -> ShowS
show :: FormletState -> String
$cshow :: FormletState -> String
showsPrec :: Int -> FormletState -> ShowS
$cshowsPrec :: Int -> FormletState -> ShowS
Show,FormletState -> FormletState -> Bool
(FormletState -> FormletState -> Bool)
-> (FormletState -> FormletState -> Bool) -> Eq FormletState
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FormletState -> FormletState -> Bool
$c/= :: FormletState -> FormletState -> Bool
== :: FormletState -> FormletState -> Bool
$c== :: FormletState -> FormletState -> Bool
Eq)
indexed :: Monad m => Consumer FormletState Formlet m Text
indexed :: Consumer FormletState Formlet m Text
indexed =
StateT FormletState m (Description Formlet)
-> StateT FormletState m (Result (Description Formlet) Text)
-> Consumer FormletState Formlet m Text
forall s (m :: * -> *) d a.
StateT s m (Description d)
-> StateT s m (Result (Description d) a) -> Consumer s d m a
consumer (do Integer
i <- StateT FormletState m Integer
forall (m :: * -> *). MonadState FormletState m => m Integer
nextIndex
Description Formlet -> StateT FormletState m (Description Formlet)
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Description Formlet
d Integer
i))
(do Integer
i <- StateT FormletState m Integer
forall (m :: * -> *). MonadState FormletState m => m Integer
nextIndex
FormletState
s <- StateT FormletState m FormletState
forall s (m :: * -> *). MonadState s m => m s
get
Result (Description Formlet) Text
-> StateT FormletState m (Result (Description Formlet) Text)
forall (m :: * -> *) a. Monad m => a -> m a
return (case Integer -> Map Integer Text -> Maybe Text
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Integer
i (FormletState -> Map Integer Text
formletMap FormletState
s) of
Nothing -> Description Formlet -> Result (Description Formlet) Text
forall e a. e -> Result e a
Failed (Integer -> Description Formlet
d Integer
i)
Just a :: Text
a -> Text -> Result (Description Formlet) Text
forall e a. a -> Result e a
Succeeded Text
a))
where d :: Integer -> Description Formlet
d = Formlet -> Description Formlet
forall a. a -> Description a
Unit (Formlet -> Description Formlet)
-> (Integer -> Formlet) -> Integer -> Description Formlet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Formlet
Index
nextIndex :: MonadState FormletState m => m Integer
nextIndex :: m Integer
nextIndex =
do Integer
i <- (FormletState -> Integer) -> m Integer
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets FormletState -> Integer
formletIndex
(FormletState -> FormletState) -> m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\s :: FormletState
s ->
FormletState
s {formletIndex :: Integer
formletIndex = FormletState -> Integer
formletIndex FormletState
s Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ 1})
Integer -> m Integer
forall (m :: * -> *) a. Monad m => a -> m a
return Integer
i