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

import Capnp.Classes

import Capnp.Message (Mutability (..))

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 ('Mut s) a, Allocate s a, M.WriteCtx m s)
    => M.Message ('Mut s) -> m a
newRoot :: Message ('Mut s) -> m a
newRoot Message ('Mut s)
msg = do
    a
ret <- Message ('Mut s) -> m a
forall s e (m :: * -> *).
(Allocate s e, WriteCtx m s) =>
Message ('Mut s) -> m e
new Message ('Mut s)
msg
    a -> m ()
forall s a (m :: * -> *).
(ToStruct ('Mut 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 ('Mut s) a, M.WriteCtx m s) => a -> m ()
setRoot :: a -> m ()
setRoot = Struct ('Mut s) -> m ()
forall (m :: * -> *) s. WriteCtx m s => Struct ('Mut s) -> m ()
U.setRoot (Struct ('Mut s) -> m ()) -> (a -> Struct ('Mut s)) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Struct ('Mut s)
forall (mut :: Mutability) a. ToStruct mut a => a -> Struct mut
toStruct

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