{-# language AllowAmbiguousTypes #-}
{-# language ScopedTypeVariables #-}
{-# language RankNTypes          #-}

module System.Nix.Store.Remote.Builders
  ( buildContentAddressableAddress
  )
where

import qualified Data.Text.Lazy              as TL
import           Crypto.Hash                    ( Digest )
import           System.Nix.StorePath           ( ContentAddressableAddress(..)
                                                )

import           Data.Text.Lazy.Builder         ( Builder )
import qualified Data.Text.Lazy.Builder      as TL

import           System.Nix.Hash

-- | Marshall `ContentAddressableAddress` to `Text`
-- in form suitable for remote protocol usage.
buildContentAddressableAddress :: ContentAddressableAddress -> TL.Text
buildContentAddressableAddress :: ContentAddressableAddress -> Text
buildContentAddressableAddress =
  Builder -> Text
TL.toLazyText (Builder -> Text)
-> (ContentAddressableAddress -> Builder)
-> ContentAddressableAddress
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContentAddressableAddress -> Builder
contentAddressableAddressBuilder

contentAddressableAddressBuilder :: ContentAddressableAddress -> Builder
contentAddressableAddressBuilder :: ContentAddressableAddress -> Builder
contentAddressableAddressBuilder (Text Digest SHA256
digest) =
  Builder
"text:" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Digest SHA256 -> Builder
forall a. Digest a -> Builder
digestBuilder Digest SHA256
digest
contentAddressableAddressBuilder (Fixed NarHashMode
_narHashMode (SomeDigest (Digest a
digest :: Digest hashAlgo))) =
  Builder
"fixed:"
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
TL.fromText (NamedAlgo a => Text
forall a. NamedAlgo a => Text
System.Nix.Hash.algoName @hashAlgo)
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Digest a -> Builder
forall a. Digest a -> Builder
digestBuilder Digest a
digest

digestBuilder :: Digest a -> Builder
digestBuilder :: Digest a -> Builder
digestBuilder =
  Text -> Builder
TL.fromText (Text -> Builder) -> (Digest a -> Text) -> Digest a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BaseEncoding -> Digest a -> Text
forall a. BaseEncoding -> Digest a -> Text
encodeDigestWith BaseEncoding
NixBase32