{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies          #-}
module Codec.Capnp
    ( newRoot
    , setRoot
    , getRoot
    ) where

import Capnp.Classes

import qualified Capnp.Message as M
import qualified Capnp.Untyped as U

-- | 'newRoot' allocates and returns a new value inside the message, setting
-- it as the root object of the message.
newRoot :: (ToStruct (M.MutMsg s) a, Allocate s a, M.WriteCtx m s)
    => M.MutMsg s -> m a
newRoot :: MutMsg s -> m a
newRoot MutMsg s
msg = do
    a
ret <- MutMsg s -> m a
forall s e (m :: * -> *).
(Allocate s e, WriteCtx m s) =>
MutMsg s -> m e
new MutMsg s
msg
    a -> m ()
forall s a (m :: * -> *).
(ToStruct (MutMsg s) a, WriteCtx m s) =>
a -> m ()
setRoot a
ret
    a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
ret

-- | 'setRoot' sets its argument to be the root object in its message.
setRoot :: (ToStruct (M.MutMsg s) a, M.WriteCtx m s) => a -> m ()
setRoot :: a -> m ()
setRoot = Struct (MutMsg s) -> m ()
forall (m :: * -> *) s. WriteCtx m s => Struct (MutMsg s) -> m ()
U.setRoot (Struct (MutMsg s) -> m ())
-> (a -> Struct (MutMsg s)) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Struct (MutMsg s)
forall msg a. ToStruct msg a => a -> Struct msg
toStruct

-- | 'getRoot' returns the root object of a message.
getRoot :: (FromStruct msg a, U.ReadCtx m msg) => msg -> m a
getRoot :: msg -> m a
getRoot msg
msg = msg -> m (Struct msg)
forall (m :: * -> *) msg. ReadCtx m msg => msg -> m (Struct msg)
U.rootPtr msg
msg m (Struct msg) -> (Struct msg -> m a) -> m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Struct msg -> m a
forall msg a (m :: * -> *).
(FromStruct msg a, ReadCtx m msg) =>
Struct msg -> m a
fromStruct