inferno-vc-0.1.0: src/Inferno/VersionControl/Types.hs
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}
module Inferno.VersionControl.Types
( VCObjectHash (..),
VCObject (..),
VCObjectVisibility (..),
VCMeta (..),
VCCommitMessage (..),
VCIncompatReason (..),
VCObjectPred (..),
VCHashUpdate (..),
Pinned (..),
vcObjectHashToByteString,
vcHash,
showVCObjectType,
)
where
import Data.Aeson (FromJSON, ToJSON)
import Data.Map (Map)
import qualified Data.Map as Map
import Data.Maybe (catMaybes)
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Text (Text)
import Foreign.C.Types (CTime)
import GHC.Generics (Generic)
import Inferno.Types.Module (Module (..))
import Inferno.Types.Syntax (Dependencies (..), Expr (..), Ident (..))
import Inferno.Types.Type (Namespace, TCScheme (..)) -- TypeMetadata(..),
import Inferno.Types.VersionControl (Pinned (..), VCHashUpdate (..), VCObjectHash (..), pinnedUnderVCToMaybe, vcHash, vcObjectHashToByteString)
import Test.QuickCheck (Arbitrary (..), oneof)
import Test.QuickCheck.Arbitrary.ADT (ToADTArbitrary)
import Test.QuickCheck.Instances.Text ()
data VCObject
= VCModule (Module (Map Ident VCObjectHash))
| VCFunction (Expr (Pinned VCObjectHash) ()) TCScheme -- (Map (SourcePos, SourcePos) (TypeMetadata TCScheme))
| VCTestFunction (Expr (Pinned VCObjectHash) ())
| VCEnum Ident (Set Ident)
deriving (Eq, Generic, ToJSON, FromJSON, VCHashUpdate)
showVCObjectType :: VCObject -> Text
showVCObjectType = \case
VCModule _ -> "module"
VCFunction _ _ -> "function"
VCTestFunction _ -> "test function"
VCEnum _ _ -> "enum"
instance Dependencies VCObject VCObjectHash where
getDependencies = \case
VCModule Module {moduleObjects = os} -> Set.fromList $ Map.elems os
VCFunction expr _ -> Set.fromList $ catMaybes $ map pinnedUnderVCToMaybe $ Set.toList $ getDependencies expr
VCTestFunction expr -> Set.fromList $ catMaybes $ map pinnedUnderVCToMaybe $ Set.toList $ getDependencies expr
VCEnum _ _ -> mempty
data VCObjectVisibility = VCObjectPublic | VCObjectPrivate deriving (Show, Eq, Generic, ToJSON, FromJSON, VCHashUpdate)
instance Arbitrary VCObjectVisibility where
arbitrary = oneof $ map pure [VCObjectPublic, VCObjectPrivate]
deriving instance ToADTArbitrary VCObjectVisibility
newtype VCCommitMessage = VCCommitMessage {unVCCommitMessage :: Text}
deriving stock (Show, Eq, Generic)
deriving newtype (ToJSON, FromJSON, VCHashUpdate)
data VCIncompatReason
= TypeSignatureChange
| EnumConstructorsChanged
deriving (Show, Eq, Generic, ToJSON, FromJSON, VCHashUpdate)
instance Arbitrary VCIncompatReason where
arbitrary = oneof $ map pure [TypeSignatureChange, EnumConstructorsChanged]
deriving instance ToADTArbitrary VCIncompatReason
data VCObjectPred
= -- | Original script (root of the histories).
Init
| CompatibleWithPred VCObjectHash
| IncompatibleWithPred VCObjectHash [(Namespace, VCIncompatReason)]
| MarkedBreakingWithPred VCObjectHash
| -- | Similar to 'Init' but this script is init'd by cloning the original script.
CloneOf VCObjectHash
| -- | CloneOfRemoved' is a "virtual" constructor to differentiate that the source of the script has been removed (but can
-- still be found in removed directory). However, in the DB the field is still stored as 'CloneOf'. When we build the histories
-- of a script, it will be differentiated between these 3 constructors for cloned script.
CloneOfRemoved VCObjectHash
| -- | 'CloneOfNotFound' is similar to 'CloneOfRemoved' but it is for case where the original script is not found
-- i.e. the removed folder might get cleared so we lost the original script information.
CloneOfNotFound VCObjectHash
deriving (Show, Eq, Generic, ToJSON, FromJSON, VCHashUpdate)
instance Arbitrary VCObjectPred where
arbitrary =
oneof
[ pure Init,
CompatibleWithPred <$> arbitrary,
IncompatibleWithPred <$> arbitrary <*> arbitrary,
MarkedBreakingWithPred <$> arbitrary,
CloneOf <$> arbitrary
]
deriving instance ToADTArbitrary VCObjectPred
-- the owner information and commit messages will be added in further revisions with other metadata as needed
data VCMeta author group o = VCMeta
{ timestamp :: CTime,
author :: author,
group :: group,
name :: Text,
description :: Text,
pred :: VCObjectPred,
-- commitMessage :: VCCommitMessage,
visibility :: VCObjectVisibility,
obj :: o
}
deriving (Show, Eq, Functor, Generic, ToJSON, FromJSON, VCHashUpdate)
instance (Arbitrary a, Arbitrary g, Arbitrary o) => Arbitrary (VCMeta a g o) where
arbitrary =
VCMeta
<$> arbitrary
<*> arbitrary
<*> arbitrary
<*> arbitrary
<*> arbitrary
<*> arbitrary
<*> arbitrary
<*> arbitrary
deriving instance (Arbitrary a, Arbitrary g, Arbitrary o) => ToADTArbitrary (VCMeta a g o)