module System.Nix.Store.Remote.Types.StoreReply
  ( StoreReply(..)
  ) where

import Data.HashSet (HashSet)
import Data.Map (Map)
import System.Nix.Build (BuildResult)
import System.Nix.StorePath (StorePath, StorePathName)
import System.Nix.StorePath.Metadata (Metadata)
import System.Nix.Store.Remote.Serializer
import System.Nix.Store.Remote.Types.NoReply (NoReply(..))
import System.Nix.Store.Remote.Types.SuccessCodeReply (SuccessCodeReply)
import System.Nix.Store.Remote.Types.GC (GCResult, GCRoot)
import System.Nix.Store.Remote.Types.Query.Missing (Missing)
import System.Nix.Store.Remote.Types.StoreConfig (ProtoStoreConfig)

-- | Get @NixSerializer@ for some type @a@
-- This could also be generalized for every type
-- we have a serializer for but we mostly need
-- this for replies and it would make look serializers
-- quite hodor, like @a <- getS get; b <- getS get@
class StoreReply a where
  getReplyS :: NixSerializer ProtoStoreConfig ReplySError a

instance StoreReply SuccessCodeReply where
  getReplyS :: NixSerializer ProtoStoreConfig ReplySError SuccessCodeReply
getReplyS = NixSerializer ProtoStoreConfig ReplySError SuccessCodeReply
forall r. NixSerializer r ReplySError SuccessCodeReply
opSuccess

instance StoreReply NoReply where
  getReplyS :: NixSerializer ProtoStoreConfig ReplySError NoReply
getReplyS = NoReply -> NixSerializer ProtoStoreConfig ReplySError NoReply
forall a r. a -> NixSerializer r ReplySError a
noop NoReply
NoReply

instance StoreReply Bool where
  getReplyS :: NixSerializer ProtoStoreConfig ReplySError Bool
getReplyS = NixSerializer ProtoStoreConfig SError Bool
-> NixSerializer ProtoStoreConfig ReplySError Bool
forall r a.
NixSerializer r SError a -> NixSerializer r ReplySError a
mapPrimE NixSerializer ProtoStoreConfig SError Bool
forall r. NixSerializer r SError Bool
bool

instance StoreReply BuildResult where
  getReplyS :: NixSerializer ProtoStoreConfig ReplySError BuildResult
getReplyS = NixSerializer ProtoStoreConfig ReplySError BuildResult
forall r.
(HasProtoVersion r, HasStoreDir r) =>
NixSerializer r ReplySError BuildResult
buildResult

instance StoreReply GCResult where
  getReplyS :: NixSerializer ProtoStoreConfig ReplySError GCResult
getReplyS = NixSerializer ProtoStoreConfig ReplySError GCResult
forall r. HasStoreDir r => NixSerializer r ReplySError GCResult
gcResult

instance StoreReply (Map GCRoot StorePath) where
  getReplyS :: NixSerializer ProtoStoreConfig ReplySError (Map GCRoot StorePath)
getReplyS = NixSerializer ProtoStoreConfig ReplySError GCRoot
-> NixSerializer ProtoStoreConfig ReplySError StorePath
-> NixSerializer
     ProtoStoreConfig ReplySError (Map GCRoot StorePath)
forall k r e v.
Ord k =>
NixSerializer r e k
-> NixSerializer r e v -> NixSerializer r e (Map k v)
mapS NixSerializer ProtoStoreConfig ReplySError GCRoot
forall r. NixSerializer r ReplySError GCRoot
gcRoot (NixSerializer ProtoStoreConfig SError StorePath
-> NixSerializer ProtoStoreConfig ReplySError StorePath
forall r a.
NixSerializer r SError a -> NixSerializer r ReplySError a
mapPrimE NixSerializer ProtoStoreConfig SError StorePath
forall r. HasStoreDir r => NixSerializer r SError StorePath
storePath)

instance StoreReply Missing where
  getReplyS :: NixSerializer ProtoStoreConfig ReplySError Missing
getReplyS = NixSerializer ProtoStoreConfig ReplySError Missing
forall r. HasStoreDir r => NixSerializer r ReplySError Missing
missing

instance StoreReply (Maybe (Metadata StorePath)) where
  getReplyS :: NixSerializer
  ProtoStoreConfig ReplySError (Maybe (Metadata StorePath))
getReplyS = NixSerializer
  ProtoStoreConfig ReplySError (Maybe (Metadata StorePath))
forall r.
HasStoreDir r =>
NixSerializer r ReplySError (Maybe (Metadata StorePath))
maybePathMetadata

instance StoreReply StorePath where
  getReplyS :: NixSerializer ProtoStoreConfig ReplySError StorePath
getReplyS = NixSerializer ProtoStoreConfig SError StorePath
-> NixSerializer ProtoStoreConfig ReplySError StorePath
forall r a.
NixSerializer r SError a -> NixSerializer r ReplySError a
mapPrimE NixSerializer ProtoStoreConfig SError StorePath
forall r. HasStoreDir r => NixSerializer r SError StorePath
storePath

instance StoreReply (HashSet StorePath) where
  getReplyS :: NixSerializer ProtoStoreConfig ReplySError (HashSet StorePath)
getReplyS = NixSerializer ProtoStoreConfig SError (HashSet StorePath)
-> NixSerializer ProtoStoreConfig ReplySError (HashSet StorePath)
forall r a.
NixSerializer r SError a -> NixSerializer r ReplySError a
mapPrimE (NixSerializer ProtoStoreConfig SError StorePath
-> NixSerializer ProtoStoreConfig SError (HashSet StorePath)
forall a r e.
(Eq a, Hashable a) =>
NixSerializer r e a -> NixSerializer r e (HashSet a)
hashSet NixSerializer ProtoStoreConfig SError StorePath
forall r. HasStoreDir r => NixSerializer r SError StorePath
storePath)

instance StoreReply (HashSet StorePathName) where
  getReplyS :: NixSerializer ProtoStoreConfig ReplySError (HashSet StorePathName)
getReplyS = NixSerializer ProtoStoreConfig SError (HashSet StorePathName)
-> NixSerializer
     ProtoStoreConfig ReplySError (HashSet StorePathName)
forall r a.
NixSerializer r SError a -> NixSerializer r ReplySError a
mapPrimE (NixSerializer ProtoStoreConfig SError StorePathName
-> NixSerializer ProtoStoreConfig SError (HashSet StorePathName)
forall a r e.
(Eq a, Hashable a) =>
NixSerializer r e a -> NixSerializer r e (HashSet a)
hashSet NixSerializer ProtoStoreConfig SError StorePathName
forall r. NixSerializer r SError StorePathName
storePathName)

mapPrimE
  :: NixSerializer r SError a
  -> NixSerializer r ReplySError a
mapPrimE :: forall r a.
NixSerializer r SError a -> NixSerializer r ReplySError a
mapPrimE = (SError -> ReplySError)
-> NixSerializer r SError a -> NixSerializer r ReplySError a
forall e e' r a.
(e -> e') -> NixSerializer r e a -> NixSerializer r e' a
mapErrorS SError -> ReplySError
ReplySError_PrimGet