{-# LANGUAGE RecordWildCards   #-}
{-# LANGUAGE OverloadedStrings #-}

module Nix.NarInfo.Builder
    ( -- * Builder
      buildNarInfo
    , buildNarInfoWith
    ) where

import Data.Set (Set)
import Data.Text (Text)
import Data.Text.Lazy.Builder (Builder)
import Nix.NarInfo.Types

import qualified Control.Applicative
import qualified Data.Char
import qualified Data.Set
import qualified Data.List
import qualified Data.Text
import qualified Data.Text.Lazy.Builder

buildNarInfo :: (NarInfo FilePath Text Text) -> Builder
buildNarInfo :: NarInfo FilePath Text Text -> Builder
buildNarInfo = (Bool -> FilePath -> Builder)
-> (Text -> Builder)
-> (Text -> Builder)
-> NarInfo FilePath Text Text
-> Builder
forall fp txt hash.
Ord fp =>
(Bool -> fp -> Builder)
-> (txt -> Builder)
-> (hash -> Builder)
-> NarInfo fp txt hash
-> Builder
buildNarInfoWith
  (\_needPrefix :: Bool
_needPrefix fp :: FilePath
fp -> FilePath -> Builder
Data.Text.Lazy.Builder.fromString FilePath
fp)
  Text -> Builder
Data.Text.Lazy.Builder.fromText
  Text -> Builder
Data.Text.Lazy.Builder.fromText

buildNarInfoWith :: (Ord fp)
                 => (Bool -> fp -> Builder)
                 -> (txt -> Builder)
                 -> (hash -> Builder)
                 -> NarInfo fp txt hash
                 -> Builder
buildNarInfoWith :: (Bool -> fp -> Builder)
-> (txt -> Builder)
-> (hash -> Builder)
-> NarInfo fp txt hash
-> Builder
buildNarInfoWith filepath :: Bool -> fp -> Builder
filepath string :: txt -> Builder
string hash :: hash -> Builder
hash (NarInfo{..}) =
     Builder -> fp -> Builder
keyPath "StorePath"   fp
storePath
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> txt -> Builder
key     "URL"         txt
url
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> txt -> Builder
key     "Compression" txt
compression
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> hash -> Builder
keyHash "FileHash"    hash
fileHash
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Integer -> Builder
forall a. Show a => Builder -> a -> Builder
keyNum  "FileSize"    Integer
fileSize
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> hash -> Builder
keyHash "NarHash"     hash
narHash
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Integer -> Builder
forall a. Show a => Builder -> a -> Builder
keyNum  "NarSize"     Integer
narSize

  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Builder -> Builder
forall a. (Semigroup a, IsString a) => a -> a -> a
key'    "References"  ([Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat
      ([Builder] -> Builder) -> [Builder] -> Builder
forall a b. (a -> b) -> a -> b
$ Builder -> [Builder] -> [Builder]
forall a. a -> [a] -> [a]
Data.List.intersperse " "
        ([Builder] -> [Builder]) -> [Builder] -> [Builder]
forall a b. (a -> b) -> a -> b
$ (fp -> Builder) -> [fp] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map (Bool -> fp -> Builder
filepath Bool
False)
          ([fp] -> [Builder]) -> [fp] -> [Builder]
forall a b. (a -> b) -> a -> b
$ [fp] -> [fp]
forall a. Ord a => [a] -> [a]
Data.List.sort ([fp] -> [fp]) -> [fp] -> [fp]
forall a b. (a -> b) -> a -> b
$ Set fp -> [fp]
forall a. Set a -> [a]
Data.Set.toList Set fp
references)

  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Maybe txt -> Builder
optKey  "Deriver"     Maybe txt
deriver
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Maybe txt -> Builder
optKey  "System"      Maybe txt
system
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Maybe txt -> Builder
optKey  "Sig"         Maybe txt
sig
  Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Maybe txt -> Builder
optKey  "Ca"          Maybe txt
ca
  where
    key' :: a -> a -> a
key' k :: a
k v :: a
v    = a
k a -> a -> a
forall a. Semigroup a => a -> a -> a
<> ": " a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
v a -> a -> a
forall a. Semigroup a => a -> a -> a
<> "\n"
    key :: Builder -> txt -> Builder
key k :: Builder
k v :: txt
v     = Builder -> Builder -> Builder
forall a. (Semigroup a, IsString a) => a -> a -> a
key' Builder
k (txt -> Builder
string txt
v)
    keyNum :: Builder -> a -> Builder
keyNum k :: Builder
k v :: a
v  = Builder -> Builder -> Builder
forall a. (Semigroup a, IsString a) => a -> a -> a
key' Builder
k (FilePath -> Builder
Data.Text.Lazy.Builder.fromString (FilePath -> Builder) -> (a -> FilePath) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> FilePath
forall a. Show a => a -> FilePath
show (a -> Builder) -> a -> Builder
forall a b. (a -> b) -> a -> b
$ a
v)
    keyPath :: Builder -> fp -> Builder
keyPath k :: Builder
k v :: fp
v = Builder -> Builder -> Builder
forall a. (Semigroup a, IsString a) => a -> a -> a
key' Builder
k (Bool -> fp -> Builder
filepath Bool
True fp
v)
    keyHash :: Builder -> hash -> Builder
keyHash k :: Builder
k v :: hash
v = Builder -> Builder -> Builder
forall a. (Semigroup a, IsString a) => a -> a -> a
key' Builder
k (hash -> Builder
hash hash
v)
    optKey :: Builder -> Maybe txt -> Builder
optKey k :: Builder
k    = Builder -> (txt -> Builder) -> Maybe txt -> Builder
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Builder
forall a. Monoid a => a
mempty (Builder -> txt -> Builder
key Builder
k)