module Data.ProtoLens.Encoding.Parser.Unsafe
    ( unsafeLiftIO ) where

import Data.ProtoLens.Encoding.Parser.Internal

-- | Runs an arbitrary @IO@ action inside a @Parser@.
-- The generated code uses this function to construct vectors
-- efficiently by incrementally building up mutable vectors.
--
-- NOTE: This is unsafe since @runParser@
-- is a pure function, which lets us lift arbitrary IO into
-- pure operations.
-- However, here are some guarantees that we do get:
--
-- - For each individual call to 'runParser', the action
--   wrapped by 'unsafeLiftIO' will be called exactly once.
-- - Different calls to 'unsafeLiftIO' within the same call to
--   'runParser' will be sequenced according to their order in the Parser
--   monad.
unsafeLiftIO :: IO a -> Parser a
unsafeLiftIO :: forall a. IO a -> Parser a
unsafeLiftIO IO a
m = (Ptr Word8 -> Ptr Word8 -> IO (ParseResult a)) -> Parser a
forall a.
(Ptr Word8 -> Ptr Word8 -> IO (ParseResult a)) -> Parser a
Parser ((Ptr Word8 -> Ptr Word8 -> IO (ParseResult a)) -> Parser a)
-> (Ptr Word8 -> Ptr Word8 -> IO (ParseResult a)) -> Parser a
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
_ Ptr Word8
p -> Ptr Word8 -> a -> ParseResult a
forall a. Ptr Word8 -> a -> ParseResult a
ParseSuccess Ptr Word8
p (a -> ParseResult a) -> IO a -> IO (ParseResult a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO a
m