{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes          #-}
{-# LANGUAGE TypeApplications    #-}

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

import           Data.Text.Lazy                 ( Text )
import           System.Nix.Hash                ( Digest
                                                , SomeNamedDigest(SomeDigest)
                                                , BaseEncoding(Base32)
                                                )
import           System.Nix.StorePath           ( ContentAddressableAddress(..)
                                                )

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

import qualified System.Nix.Hash

-- | Marshall `ContentAddressableAddress` to `Text`
-- in form suitable for remote protocol usage.
buildContentAddressableAddress :: ContentAddressableAddress -> Text
buildContentAddressableAddress :: ContentAddressableAddress -> Text
buildContentAddressableAddress =
  Builder -> Text
Data.Text.Lazy.Builder.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 :: HashAlgorithm). 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
Data.Text.Lazy.Builder.fromText (Text -> Builder) -> Text -> Builder
forall a b. (a -> b) -> a -> b
$ NamedAlgo a => Text
forall (a :: HashAlgorithm). NamedAlgo a => Text
System.Nix.Hash.algoName @hashAlgo)
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Digest a -> Builder
forall (a :: HashAlgorithm). Digest a -> Builder
digestBuilder Digest a
digest

digestBuilder :: Digest a -> Builder
digestBuilder :: Digest a -> Builder
digestBuilder =
  Text -> Builder
Data.Text.Lazy.Builder.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 :: HashAlgorithm). BaseEncoding -> Digest a -> Text
System.Nix.Hash.encodeInBase BaseEncoding
Base32