{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -Wno-orphans #-}
-- | Module for easy creating template params
--
-- Example usage:
--
-- @
-- \-- applicable to renderTemplate, renderTemplateI functions
-- fields :: Fields Identity ()
-- fields = do
--   value \"foo\" \"bar\"
--   valueM \"foo2\" $ return \"bar2\"
--   object \"foo3\" $ do
--            value \"foo31\" \"bar31\"
--            value \"foo32\" \"bar32\"
--   objects \"foo4\" [ do
--                    value \"foo411\" \"bar411\"
--                    value \"foo412\" \"bar412\"
--                  , do
--                    value \"foo421\" \"bar421\"
--                    value \"foo422\" \"bar422\"
--                  ]
--
-- \-- applicable to renderTemplateMain functions
-- params :: [(String, SElem String)]
-- params = runIdentity $ runFields fields
-- @
module Text.StringTemplates.Fields ( Fields(..)
                                   , runFields
                                   , value
                                   , valueM
                                   , object
                                   , objects
                                   ) where

import Control.Monad.Base (MonadBase)
import Control.Monad.Catch
import Control.Monad.Reader
import Control.Monad.State.Strict
import Control.Monad.Trans.Control (MonadBaseControl(..), MonadTransControl(..), ComposeSt, defaultLiftBaseWith, defaultRestoreM, defaultLiftWith, defaultRestoreT)
import Data.Int
import Data.Word
import Text.StringTemplate.Base hiding (render)
import Text.StringTemplate.Classes
import qualified Data.Map as M

type InnerFields = StateT [(String, SElem String)]

-- | Simple monad transformer that collects info about template params
newtype Fields m a = Fields { forall (m :: * -> *) a. Fields m a -> InnerFields m a
unFields :: InnerFields m a }
  deriving (Functor (Fields m)
Functor (Fields m) =>
(forall a. a -> Fields m a)
-> (forall a b. Fields m (a -> b) -> Fields m a -> Fields m b)
-> (forall a b c.
    (a -> b -> c) -> Fields m a -> Fields m b -> Fields m c)
-> (forall a b. Fields m a -> Fields m b -> Fields m b)
-> (forall a b. Fields m a -> Fields m b -> Fields m a)
-> Applicative (Fields m)
forall a. a -> Fields m a
forall a b. Fields m a -> Fields m b -> Fields m a
forall a b. Fields m a -> Fields m b -> Fields m b
forall a b. Fields m (a -> b) -> Fields m a -> Fields m b
forall a b c.
(a -> b -> c) -> Fields m a -> Fields m b -> Fields m c
forall (m :: * -> *). Monad m => Functor (Fields m)
forall (m :: * -> *) a. Monad m => a -> Fields m a
forall (m :: * -> *) a b.
Monad m =>
Fields m a -> Fields m b -> Fields m a
forall (m :: * -> *) a b.
Monad m =>
Fields m a -> Fields m b -> Fields m b
forall (m :: * -> *) a b.
Monad m =>
Fields m (a -> b) -> Fields m a -> Fields m b
forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> Fields m a -> Fields m b -> Fields m 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
$cpure :: forall (m :: * -> *) a. Monad m => a -> Fields m a
pure :: forall a. a -> Fields m a
$c<*> :: forall (m :: * -> *) a b.
Monad m =>
Fields m (a -> b) -> Fields m a -> Fields m b
<*> :: forall a b. Fields m (a -> b) -> Fields m a -> Fields m b
$cliftA2 :: forall (m :: * -> *) a b c.
Monad m =>
(a -> b -> c) -> Fields m a -> Fields m b -> Fields m c
liftA2 :: forall a b c.
(a -> b -> c) -> Fields m a -> Fields m b -> Fields m c
$c*> :: forall (m :: * -> *) a b.
Monad m =>
Fields m a -> Fields m b -> Fields m b
*> :: forall a b. Fields m a -> Fields m b -> Fields m b
$c<* :: forall (m :: * -> *) a b.
Monad m =>
Fields m a -> Fields m b -> Fields m a
<* :: forall a b. Fields m a -> Fields m b -> Fields m a
Applicative, (forall a b. (a -> b) -> Fields m a -> Fields m b)
-> (forall a b. a -> Fields m b -> Fields m a)
-> Functor (Fields m)
forall a b. a -> Fields m b -> Fields m a
forall a b. (a -> b) -> Fields m a -> Fields m b
forall (m :: * -> *) a b.
Functor m =>
a -> Fields m b -> Fields m a
forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> Fields m a -> Fields m b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall (m :: * -> *) a b.
Functor m =>
(a -> b) -> Fields m a -> Fields m b
fmap :: forall a b. (a -> b) -> Fields m a -> Fields m b
$c<$ :: forall (m :: * -> *) a b.
Functor m =>
a -> Fields m b -> Fields m a
<$ :: forall a b. a -> Fields m b -> Fields m a
Functor, Applicative (Fields m)
Applicative (Fields m) =>
(forall a b. Fields m a -> (a -> Fields m b) -> Fields m b)
-> (forall a b. Fields m a -> Fields m b -> Fields m b)
-> (forall a. a -> Fields m a)
-> Monad (Fields m)
forall a. a -> Fields m a
forall a b. Fields m a -> Fields m b -> Fields m b
forall a b. Fields m a -> (a -> Fields m b) -> Fields m b
forall (m :: * -> *). Monad m => Applicative (Fields m)
forall (m :: * -> *) a. Monad m => a -> Fields m a
forall (m :: * -> *) a b.
Monad m =>
Fields m a -> Fields m b -> Fields m b
forall (m :: * -> *) a b.
Monad m =>
Fields m a -> (a -> Fields m b) -> Fields m 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
$c>>= :: forall (m :: * -> *) a b.
Monad m =>
Fields m a -> (a -> Fields m b) -> Fields m b
>>= :: forall a b. Fields m a -> (a -> Fields m b) -> Fields m b
$c>> :: forall (m :: * -> *) a b.
Monad m =>
Fields m a -> Fields m b -> Fields m b
>> :: forall a b. Fields m a -> Fields m b -> Fields m b
$creturn :: forall (m :: * -> *) a. Monad m => a -> Fields m a
return :: forall a. a -> Fields m a
Monad, MonadBase b, (forall (m :: * -> *). Monad m => Monad (Fields m)) =>
(forall (m :: * -> *) a. Monad m => m a -> Fields m a)
-> MonadTrans Fields
forall (m :: * -> *). Monad m => Monad (Fields m)
forall (m :: * -> *) a. Monad m => m a -> Fields m a
forall (t :: (* -> *) -> * -> *).
(forall (m :: * -> *). Monad m => Monad (t m)) =>
(forall (m :: * -> *) a. Monad m => m a -> t m a) -> MonadTrans t
$clift :: forall (m :: * -> *) a. Monad m => m a -> Fields m a
lift :: forall (m :: * -> *) a. Monad m => m a -> Fields m a
MonadTrans, Monad (Fields m)
Monad (Fields m) =>
(forall e a. (HasCallStack, Exception e) => e -> Fields m a)
-> MonadThrow (Fields m)
forall e a. (HasCallStack, Exception e) => e -> Fields m a
forall (m :: * -> *).
Monad m =>
(forall e a. (HasCallStack, Exception e) => e -> m a)
-> MonadThrow m
forall (m :: * -> *). MonadThrow m => Monad (Fields m)
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> Fields m a
$cthrowM :: forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> Fields m a
throwM :: forall e a. (HasCallStack, Exception e) => e -> Fields m a
MonadThrow, MonadThrow (Fields m)
MonadThrow (Fields m) =>
(forall e a.
 (HasCallStack, Exception e) =>
 Fields m a -> (e -> Fields m a) -> Fields m a)
-> MonadCatch (Fields m)
forall e a.
(HasCallStack, Exception e) =>
Fields m a -> (e -> Fields m a) -> Fields m a
forall (m :: * -> *). MonadCatch m => MonadThrow (Fields m)
forall (m :: * -> *) e a.
(MonadCatch m, HasCallStack, Exception e) =>
Fields m a -> (e -> Fields m a) -> Fields m a
forall (m :: * -> *).
MonadThrow m =>
(forall e a.
 (HasCallStack, Exception e) =>
 m a -> (e -> m a) -> m a)
-> MonadCatch m
$ccatch :: forall (m :: * -> *) e a.
(MonadCatch m, HasCallStack, Exception e) =>
Fields m a -> (e -> Fields m a) -> Fields m a
catch :: forall e a.
(HasCallStack, Exception e) =>
Fields m a -> (e -> Fields m a) -> Fields m a
MonadCatch, MonadCatch (Fields m)
MonadCatch (Fields m) =>
(forall b.
 HasCallStack =>
 ((forall a. Fields m a -> Fields m a) -> Fields m b) -> Fields m b)
-> (forall b.
    HasCallStack =>
    ((forall a. Fields m a -> Fields m a) -> Fields m b) -> Fields m b)
-> (forall a b c.
    HasCallStack =>
    Fields m a
    -> (a -> ExitCase b -> Fields m c)
    -> (a -> Fields m b)
    -> Fields m (b, c))
-> MonadMask (Fields m)
forall b.
HasCallStack =>
((forall a. Fields m a -> Fields m a) -> Fields m b) -> Fields m b
forall a b c.
HasCallStack =>
Fields m a
-> (a -> ExitCase b -> Fields m c)
-> (a -> Fields m b)
-> Fields m (b, c)
forall (m :: * -> *). MonadMask m => MonadCatch (Fields m)
forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. Fields m a -> Fields m a) -> Fields m b) -> Fields m b
forall (m :: * -> *) a b c.
(MonadMask m, HasCallStack) =>
Fields m a
-> (a -> ExitCase b -> Fields m c)
-> (a -> Fields m b)
-> Fields m (b, c)
forall (m :: * -> *).
MonadCatch m =>
(forall b. HasCallStack => ((forall a. m a -> m a) -> m b) -> m b)
-> (forall b.
    HasCallStack =>
    ((forall a. m a -> m a) -> m b) -> m b)
-> (forall a b c.
    HasCallStack =>
    m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c))
-> MonadMask m
$cmask :: forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. Fields m a -> Fields m a) -> Fields m b) -> Fields m b
mask :: forall b.
HasCallStack =>
((forall a. Fields m a -> Fields m a) -> Fields m b) -> Fields m b
$cuninterruptibleMask :: forall (m :: * -> *) b.
(MonadMask m, HasCallStack) =>
((forall a. Fields m a -> Fields m a) -> Fields m b) -> Fields m b
uninterruptibleMask :: forall b.
HasCallStack =>
((forall a. Fields m a -> Fields m a) -> Fields m b) -> Fields m b
$cgeneralBracket :: forall (m :: * -> *) a b c.
(MonadMask m, HasCallStack) =>
Fields m a
-> (a -> ExitCase b -> Fields m c)
-> (a -> Fields m b)
-> Fields m (b, c)
generalBracket :: forall a b c.
HasCallStack =>
Fields m a
-> (a -> ExitCase b -> Fields m c)
-> (a -> Fields m b)
-> Fields m (b, c)
MonadMask)

instance MonadBaseControl b m => MonadBaseControl b (Fields m) where
#if MIN_VERSION_monad_control(1,0,0)
  type StM (Fields m) a = ComposeSt Fields m a
  liftBaseWith :: forall a. (RunInBase (Fields m) b -> b a) -> Fields m a
liftBaseWith = (RunInBaseDefault Fields m b -> b a) -> Fields m a
(RunInBase (Fields m) b -> b a) -> Fields m a
forall (t :: (* -> *) -> * -> *) (b :: * -> *) (m :: * -> *) a.
(MonadTransControl t, MonadBaseControl b m) =>
(RunInBaseDefault t m b -> b a) -> t m a
defaultLiftBaseWith
  restoreM :: forall a. StM (Fields m) a -> Fields m a
restoreM     = ComposeSt Fields m a -> Fields m a
StM (Fields m) a -> Fields m a
forall (t :: (* -> *) -> * -> *) (b :: * -> *) (m :: * -> *) a.
(MonadTransControl t, MonadBaseControl b m) =>
ComposeSt t m a -> t m a
defaultRestoreM
#else
  newtype StM (Fields m) a = StM { unStM :: ComposeSt Fields m a }
  liftBaseWith = defaultLiftBaseWith StM
  restoreM     = defaultRestoreM unStM
#endif
  {-# INLINE liftBaseWith #-}
  {-# INLINE restoreM #-}

instance MonadTransControl Fields where
#if MIN_VERSION_monad_control(1,0,0)
  type StT Fields m = StT InnerFields m
  liftWith :: forall (m :: * -> *) a.
Monad m =>
(Run Fields -> m a) -> Fields m a
liftWith = (forall b. StateT [(String, SElem String)] m b -> Fields m b)
-> (forall (m :: * -> *) a. Fields m a -> InnerFields m a)
-> (RunDefault Fields (StateT [(String, SElem String)]) -> m a)
-> Fields m a
forall (m :: * -> *) (n :: (* -> *) -> * -> *)
       (t :: (* -> *) -> * -> *) a.
(Monad m, MonadTransControl n) =>
(forall b. n m b -> t m b)
-> (forall (o :: * -> *) b. t o b -> n o b)
-> (RunDefault t n -> m a)
-> t m a
defaultLiftWith InnerFields m b -> Fields m b
forall b. StateT [(String, SElem String)] m b -> Fields m b
forall (m :: * -> *) a. InnerFields m a -> Fields m a
Fields Fields o b -> InnerFields o b
forall (m :: * -> *) a. Fields m a -> InnerFields m a
unFields
  restoreT :: forall (m :: * -> *) a. Monad m => m (StT Fields a) -> Fields m a
restoreT = (StateT [(String, SElem String)] m a -> Fields m a)
-> m (StT (StateT [(String, SElem String)]) a) -> Fields m a
forall (m :: * -> *) (n :: (* -> *) -> * -> *) a
       (t :: (* -> *) -> * -> *).
(Monad m, MonadTransControl n) =>
(n m a -> t m a) -> m (StT n a) -> t m a
defaultRestoreT StateT [(String, SElem String)] m a -> Fields m a
forall (m :: * -> *) a. InnerFields m a -> Fields m a
Fields
#else
  newtype StT Fields m = StT { unStT :: StT InnerFields m }
  liftWith = defaultLiftWith Fields unFields StT
  restoreT = defaultRestoreT Fields unStT
#endif
  {-# INLINE liftWith #-}
  {-# INLINE restoreT #-}

-- | get all collected template params
runFields :: Monad m => Fields m () -> m [(String, SElem String)]
runFields :: forall (m :: * -> *).
Monad m =>
Fields m () -> m [(String, SElem String)]
runFields (Fields InnerFields m ()
f) = InnerFields m ()
-> [(String, SElem String)] -> m [(String, SElem String)]
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
execStateT InnerFields m ()
f []

-- | create a new named template parameter
value :: (Monad m, ToSElem a) => String -> a -> Fields m ()
value :: forall (m :: * -> *) a.
(Monad m, ToSElem a) =>
String -> a -> Fields m ()
value String
name a
val = InnerFields m () -> Fields m ()
forall (m :: * -> *) a. InnerFields m a -> Fields m a
Fields (InnerFields m () -> Fields m ())
-> InnerFields m () -> Fields m ()
forall a b. (a -> b) -> a -> b
$ ([(String, SElem String)] -> [(String, SElem String)])
-> InnerFields m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((String
name, a -> SElem String
forall b. Stringable b => a -> SElem b
forall a b. (ToSElem a, Stringable b) => a -> SElem b
toSElem a
val) (String, SElem String)
-> [(String, SElem String)] -> [(String, SElem String)]
forall a. a -> [a] -> [a]
:)

-- | create a new named template parameter (monad version)
valueM :: (Monad m, ToSElem a) => String -> m a -> Fields m ()
valueM :: forall (m :: * -> *) a.
(Monad m, ToSElem a) =>
String -> m a -> Fields m ()
valueM String
name m a
mval = m a -> Fields m a
forall (m :: * -> *) a. Monad m => m a -> Fields m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m a
mval Fields m a -> (a -> Fields m ()) -> Fields m ()
forall a b. Fields m a -> (a -> Fields m b) -> Fields m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> a -> Fields m ()
forall (m :: * -> *) a.
(Monad m, ToSElem a) =>
String -> a -> Fields m ()
value String
name

-- | collect all params under a new namespace
object :: Monad m => String -> Fields m () -> Fields m ()
object :: forall (m :: * -> *).
Monad m =>
String -> Fields m () -> Fields m ()
object String
name Fields m ()
obj = InnerFields m () -> Fields m ()
forall (m :: * -> *) a. InnerFields m a -> Fields m a
Fields (InnerFields m () -> Fields m ())
-> InnerFields m () -> Fields m ()
forall a b. (a -> b) -> a -> b
$ do
  Map String (SElem String)
val <- [(String, SElem String)] -> Map String (SElem String)
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(String, SElem String)] -> Map String (SElem String))
-> StateT [(String, SElem String)] m [(String, SElem String)]
-> StateT [(String, SElem String)] m (Map String (SElem String))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m [(String, SElem String)]
-> StateT [(String, SElem String)] m [(String, SElem String)]
forall (m :: * -> *) a.
Monad m =>
m a -> StateT [(String, SElem String)] m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Fields m () -> m [(String, SElem String)]
forall (m :: * -> *).
Monad m =>
Fields m () -> m [(String, SElem String)]
runFields Fields m ()
obj)
  ([(String, SElem String)] -> [(String, SElem String)])
-> InnerFields m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((String
name, Map String (SElem String) -> SElem String
forall b. Stringable b => Map String (SElem String) -> SElem b
forall a b. (ToSElem a, Stringable b) => a -> SElem b
toSElem Map String (SElem String)
val) (String, SElem String)
-> [(String, SElem String)] -> [(String, SElem String)]
forall a. a -> [a] -> [a]
:)

-- | collect all params under a new list namespace
objects :: Monad m => String -> [Fields m ()] -> Fields m ()
objects :: forall (m :: * -> *).
Monad m =>
String -> [Fields m ()] -> Fields m ()
objects String
name [Fields m ()]
objs = InnerFields m () -> Fields m ()
forall (m :: * -> *) a. InnerFields m a -> Fields m a
Fields (InnerFields m () -> Fields m ())
-> InnerFields m () -> Fields m ()
forall a b. (a -> b) -> a -> b
$ do
  [Map String (SElem String)]
vals <- (Fields m ()
 -> StateT [(String, SElem String)] m (Map String (SElem String)))
-> [Fields m ()]
-> StateT [(String, SElem String)] m [Map String (SElem String)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (([(String, SElem String)] -> Map String (SElem String))
-> StateT [(String, SElem String)] m [(String, SElem String)]
-> StateT [(String, SElem String)] m (Map String (SElem String))
forall a b.
(a -> b)
-> StateT [(String, SElem String)] m a
-> StateT [(String, SElem String)] m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(String, SElem String)] -> Map String (SElem String)
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList (StateT [(String, SElem String)] m [(String, SElem String)]
 -> StateT [(String, SElem String)] m (Map String (SElem String)))
-> (Fields m ()
    -> StateT [(String, SElem String)] m [(String, SElem String)])
-> Fields m ()
-> StateT [(String, SElem String)] m (Map String (SElem String))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m [(String, SElem String)]
-> StateT [(String, SElem String)] m [(String, SElem String)]
forall (m :: * -> *) a.
Monad m =>
m a -> StateT [(String, SElem String)] m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m [(String, SElem String)]
 -> StateT [(String, SElem String)] m [(String, SElem String)])
-> (Fields m () -> m [(String, SElem String)])
-> Fields m ()
-> StateT [(String, SElem String)] m [(String, SElem String)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fields m () -> m [(String, SElem String)]
forall (m :: * -> *).
Monad m =>
Fields m () -> m [(String, SElem String)]
runFields) [Fields m ()]
objs
  ([(String, SElem String)] -> [(String, SElem String)])
-> InnerFields m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((String
name, [Map String (SElem String)] -> SElem String
forall b. Stringable b => [Map String (SElem String)] -> SElem b
forall a b. (ToSElem a, Stringable b) => a -> SElem b
toSElem [Map String (SElem String)]
vals) (String, SElem String)
-> [(String, SElem String)] -> [(String, SElem String)]
forall a. a -> [a] -> [a]
:)

-- Missing orphan instances of ToSElem we need

instance ToSElem Int16 where
  toSElem :: forall b. Stringable b => Int16 -> SElem b
toSElem = String -> SElem b
forall a. String -> SElem a
STR (String -> SElem b) -> (Int16 -> String) -> Int16 -> SElem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int16 -> String
forall a. Show a => a -> String
show

instance ToSElem Int32 where
  toSElem :: forall b. Stringable b => Int32 -> SElem b
toSElem = String -> SElem b
forall a. String -> SElem a
STR (String -> SElem b) -> (Int32 -> String) -> Int32 -> SElem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> String
forall a. Show a => a -> String
show

instance ToSElem Int64 where
  toSElem :: forall b. Stringable b => Int64 -> SElem b
toSElem = String -> SElem b
forall a. String -> SElem a
STR (String -> SElem b) -> (Int64 -> String) -> Int64 -> SElem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> String
forall a. Show a => a -> String
show

instance ToSElem Word where
  toSElem :: forall b. Stringable b => Word -> SElem b
toSElem = String -> SElem b
forall a. String -> SElem a
STR (String -> SElem b) -> (Word -> String) -> Word -> SElem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word -> String
forall a. Show a => a -> String
show

instance ToSElem Word8 where
  toSElem :: forall b. Stringable b => Word8 -> SElem b
toSElem = String -> SElem b
forall a. String -> SElem a
STR (String -> SElem b) -> (Word8 -> String) -> Word8 -> SElem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> String
forall a. Show a => a -> String
show

instance ToSElem Word16 where
  toSElem :: forall b. Stringable b => Word16 -> SElem b
toSElem = String -> SElem b
forall a. String -> SElem a
STR (String -> SElem b) -> (Word16 -> String) -> Word16 -> SElem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word16 -> String
forall a. Show a => a -> String
show

instance ToSElem Word32 where
  toSElem :: forall b. Stringable b => Word32 -> SElem b
toSElem = String -> SElem b
forall a. String -> SElem a
STR (String -> SElem b) -> (Word32 -> String) -> Word32 -> SElem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word32 -> String
forall a. Show a => a -> String
show

instance ToSElem Word64 where
  toSElem :: forall b. Stringable b => Word64 -> SElem b
toSElem = String -> SElem b
forall a. String -> SElem a
STR (String -> SElem b) -> (Word64 -> String) -> Word64 -> SElem b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> String
forall a. Show a => a -> String
show

-- For some reasons the SElem a is not of class ToSElem
instance Stringable a => ToSElem (SElem a) where
  toSElem :: forall b. Stringable b => SElem a -> SElem b
toSElem (STR String
a) = (String -> SElem b
forall a. String -> SElem a
STR String
a)
  toSElem (BS ByteString
a) = (ByteString -> SElem b
forall a. ByteString -> SElem a
BS ByteString
a)
  toSElem (STSH STShow
a) = (STShow -> SElem b
forall a. STShow -> SElem a
STSH STShow
a)
  toSElem (SM SMap a
a) = (SMap b -> SElem b
forall a. SMap a -> SElem a
SM (SMap b -> SElem b) -> SMap b -> SElem b
forall a b. (a -> b) -> a -> b
$ (SElem a -> SElem b) -> SMap a -> SMap b
forall a b. (a -> b) -> Map String a -> Map String b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (SElem a -> SElem b
forall b. Stringable b => SElem a -> SElem b
forall a b. (ToSElem a, Stringable b) => a -> SElem b
toSElem) SMap a
a)
  toSElem (LI [SElem a]
a) = ([SElem b] -> SElem b
forall a. [SElem a] -> SElem a
LI ([SElem b] -> SElem b) -> [SElem b] -> SElem b
forall a b. (a -> b) -> a -> b
$ (SElem a -> SElem b) -> [SElem a] -> [SElem b]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (SElem a -> SElem b
forall b. Stringable b => SElem a -> SElem b
forall a b. (ToSElem a, Stringable b) => a -> SElem b
toSElem) [SElem a]
a)
  toSElem (SBLE a
a) = (b -> SElem b
forall a. a -> SElem a
SBLE (b -> SElem b) -> b -> SElem b
forall a b. (a -> b) -> a -> b
$ a -> b
forall a b. (Stringable a, Stringable b) => a -> b
convert a
a)
  toSElem (SNAT a
a) = (b -> SElem b
forall a. a -> SElem a
SNAT (b -> SElem b) -> b -> SElem b
forall a b. (a -> b) -> a -> b
$ a -> b
forall a b. (Stringable a, Stringable b) => a -> b
convert a
a)
  toSElem (TXT Text
a) = (Text -> SElem b
forall a. Text -> SElem a
TXT Text
a)
  toSElem SElem a
SNull = SElem b
forall a. SElem a
SNull

convert :: (Stringable a, Stringable b) => a -> b
convert :: forall a b. (Stringable a, Stringable b) => a -> b
convert = String -> b
forall a. Stringable a => String -> a
stFromString (String -> b) -> (a -> String) -> a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Stringable a => a -> String
stToString