hercules-ci-agent-0.7.1: src-cnix/CNix/Internal/Typed.hs
{-# LANGUAGE EmptyDataDecls #-}
module CNix.Internal.Typed where
import CNix.Internal.Context
import CNix.Internal.Raw
import Protolude hiding
( evalState,
throwIO,
)
import Prelude (userError)
-- | Runtime-Typed Value. This implies that it has been forced,
-- because otherwise the type would not be known.
newtype Value a = Value {rtValue :: RawValue}
data NixInt
data NixFloat
data NixString
data NixPath
data NixAttrs
data NixFunction
data NixList
data NixPrimOp
data NixPrimOpApp
data NixExternal
-- TODO: actually encapsulate the constructor
unsafeAssertType :: RawValue -> Value a
unsafeAssertType = Value
-- This is useful because you regain exhaustiveness checking.
-- Otherwise a bunch of downcast functions might do.
data Match
= IsInt (Value NixInt)
| IsBool (Value Bool)
| IsString (Value NixString)
| IsPath (Value NixPath)
| IsNull (Value ())
| IsAttrs (Value NixAttrs)
| IsList (Value NixList)
| IsFunction (Value NixFunction)
| IsExternal (Value NixExternal)
| IsFloat (Value NixFloat)
-- FIXME: errors don't provide any clue here
match :: Ptr EvalState -> RawValue -> IO (Either SomeException Match)
match es v = forceValue es v >>= \case
Left e -> pure (Left e)
Right _ -> rawValueType v <&> \case
Int -> pure $ IsInt $ unsafeAssertType v
Bool -> pure $ IsBool $ unsafeAssertType v
String -> pure $ IsString $ unsafeAssertType v
Path -> pure $ IsPath $ unsafeAssertType v
Null -> pure $ IsNull $ unsafeAssertType v
Attrs -> pure $ IsAttrs $ unsafeAssertType v
List -> pure $ IsList $ unsafeAssertType v
Thunk -> Left $ SomeException $ userError "Could not force Nix thunk" -- FIXME: custom exception?
App -> Left $ SomeException $ userError "Could not force Nix thunk (App)"
Blackhole ->
Left $ SomeException $ userError "Could not force Nix thunk (Blackhole)"
Lambda -> pure $ IsFunction $ unsafeAssertType v
PrimOp -> pure $ IsFunction $ unsafeAssertType v
PrimOpApp -> pure $ IsFunction $ unsafeAssertType v
External -> pure $ IsExternal $ unsafeAssertType v
Float -> pure $ IsFloat $ unsafeAssertType v
Other ->
Left $ SomeException $ userError "Unknown runtime type in Nix value"