hnix-store-json-0.1.0.0: src/System/Nix/JSON.hs
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-|
Description : JSON serialization
This module is mostly a stub for now
providing (From|To)JSON for Realisation type
which is required for `-remote`.
-}
module System.Nix.JSON where
import Data.Aeson
import Deriving.Aeson
import System.Nix.Base (BaseEncoding(NixBase32))
import System.Nix.OutputName (OutputName)
import System.Nix.Realisation (DerivationOutput, Realisation, RealisationWithId(..))
import System.Nix.Signature (Signature)
import System.Nix.StorePath (StoreDir(..), StorePath, StorePathName, StorePathHashPart)
import qualified Data.Aeson.KeyMap
import qualified Data.Aeson.Types
import qualified Data.Attoparsec.Text
import qualified Data.Char
import qualified Data.Text
import qualified Data.Text.Lazy
import qualified Data.Text.Lazy.Builder
import qualified System.Nix.Base
import qualified System.Nix.OutputName
import qualified System.Nix.Realisation
import qualified System.Nix.Signature
import qualified System.Nix.StorePath
instance ToJSON StorePathName where
toJSON = toJSON . System.Nix.StorePath.unStorePathName
toEncoding = toEncoding . System.Nix.StorePath.unStorePathName
instance FromJSON StorePathName where
parseJSON =
withText "StorePathName"
( either (fail . show) pure
. System.Nix.StorePath.mkStorePathName)
instance ToJSON StorePathHashPart where
toJSON = toJSON . System.Nix.StorePath.storePathHashPartToText
toEncoding = toEncoding . System.Nix.StorePath.storePathHashPartToText
instance FromJSON StorePathHashPart where
parseJSON =
withText "StorePathHashPart"
( either
(fail . show)
(pure . System.Nix.StorePath.unsafeMakeStorePathHashPart)
. System.Nix.Base.decodeWith NixBase32
)
instance ToJSON StorePath where
toJSON =
toJSON
-- TODO: hacky, we need to stop requiring StoreDir for
-- StorePath rendering and have a distinct
-- types for rooted|unrooted paths
. Data.Text.drop 1
. System.Nix.StorePath.storePathToText (StoreDir mempty)
toEncoding =
toEncoding
. Data.Text.drop 1
. System.Nix.StorePath.storePathToText (StoreDir mempty)
instance FromJSON StorePath where
parseJSON =
withText "StorePath"
( either
(fail . show)
pure
. System.Nix.StorePath.parsePathFromText (StoreDir mempty)
. Data.Text.cons '/'
)
instance ToJSON (DerivationOutput OutputName) where
toJSON =
toJSON
. Data.Text.Lazy.toStrict
. Data.Text.Lazy.Builder.toLazyText
. System.Nix.Realisation.derivationOutputBuilder
System.Nix.OutputName.unOutputName
toEncoding =
toEncoding
. Data.Text.Lazy.toStrict
. Data.Text.Lazy.Builder.toLazyText
. System.Nix.Realisation.derivationOutputBuilder
System.Nix.OutputName.unOutputName
instance ToJSONKey (DerivationOutput OutputName) where
toJSONKey =
Data.Aeson.Types.toJSONKeyText
$ Data.Text.Lazy.toStrict
. Data.Text.Lazy.Builder.toLazyText
. System.Nix.Realisation.derivationOutputBuilder
System.Nix.OutputName.unOutputName
instance FromJSON (DerivationOutput OutputName) where
parseJSON =
withText "DerivationOutput OutputName"
( either
(fail . show)
pure
. System.Nix.Realisation.derivationOutputParser
System.Nix.OutputName.mkOutputName
)
instance FromJSONKey (DerivationOutput OutputName) where
fromJSONKey =
FromJSONKeyTextParser
( either
(fail . show)
pure
. System.Nix.Realisation.derivationOutputParser
System.Nix.OutputName.mkOutputName
)
instance ToJSON Signature where
toJSON = toJSON . System.Nix.Signature.signatureToText
toEncoding = toEncoding . System.Nix.Signature.signatureToText
instance FromJSON Signature where
parseJSON =
withText "Signature"
( either
(fail . show)
pure
. Data.Attoparsec.Text.parseOnly
System.Nix.Signature.signatureParser
)
data LowerLeading
instance StringModifier LowerLeading where
getStringModifier "" = ""
getStringModifier (c:xs) = Data.Char.toLower c : xs
deriving
via CustomJSON
'[FieldLabelModifier
'[ StripPrefix "realisation"
, LowerLeading
, Rename "dependencies" "dependentRealisations"
]
] Realisation
instance ToJSON Realisation
deriving
via CustomJSON
'[FieldLabelModifier
'[ StripPrefix "realisation"
, LowerLeading
, Rename "dependencies" "dependentRealisations"
]
] Realisation
instance FromJSON Realisation
-- For a keyed version of Realisation
-- we use RealisationWithId (DerivationOutput OutputName, Realisation)
-- instead of Realisation.id :: (DerivationOutput OutputName)
-- field.
instance ToJSON RealisationWithId where
toJSON (RealisationWithId (drvOut, r)) =
case toJSON r of
Object o -> Object $ Data.Aeson.KeyMap.insert "id" (toJSON drvOut) o
_ -> error "absurd"
instance FromJSON RealisationWithId where
parseJSON v@(Object o) = do
r <- parseJSON @Realisation v
drvOut <- o .: "id"
pure (RealisationWithId (drvOut, r))
parseJSON x = fail $ "Expected Object but got " ++ show x