{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

module Development.Guardian.Types where

import Algebra.Graph (Graph)
import Algebra.Graph.AdjacencyMap.Algorithm (Cycle)
import qualified Algebra.Graph.Class as GC
import Algebra.Graph.Label
import qualified Algebra.Graph.Labelled as L
import Algebra.Graph.Relation.Preorder (PreorderRelation)
import Control.Applicative
import Control.Exception (Exception)
import Control.Monad.Trans.Reader (ReaderT (ReaderT, runReaderT))
import Data.Aeson (FromJSON (..), FromJSONKey, genericParseJSON, withObject, withText, (.:), (.:?))
import qualified Data.Aeson as J
import Data.Coerce (coerce)
import qualified Data.HashMap.Strict as HM
import Data.Hashable (Hashable)
import Data.Map (Map)
import qualified Data.Map.Strict as Map
import Data.Set (Set)
import Data.String (IsString)
import Data.Text (Text)
import qualified Data.Vector as V
import GHC.Generics (Generic)

type DomainGraph = PreorderRelation DomainName

type PackageGraph = Graph PackageName

type ActualGraph' e = L.Graph e DomainName

type ActualGraph = ActualGraph' (Path PackageName)

type PackageDic = Map PackageName (DomainName, V.Vector Dependency)

data DomainGraphError
  = CyclicDomainDep (Cycle DomainName)
  | OverlappingPackages (Map PackageName (Set DomainName))
  deriving (Int -> DomainGraphError -> ShowS
[DomainGraphError] -> ShowS
DomainGraphError -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DomainGraphError] -> ShowS
$cshowList :: [DomainGraphError] -> ShowS
show :: DomainGraphError -> String
$cshow :: DomainGraphError -> String
showsPrec :: Int -> DomainGraphError -> ShowS
$cshowsPrec :: Int -> DomainGraphError -> ShowS
Show, DomainGraphError -> DomainGraphError -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DomainGraphError -> DomainGraphError -> Bool
$c/= :: DomainGraphError -> DomainGraphError -> Bool
== :: DomainGraphError -> DomainGraphError -> Bool
$c== :: DomainGraphError -> DomainGraphError -> Bool
Eq, Eq DomainGraphError
DomainGraphError -> DomainGraphError -> Bool
DomainGraphError -> DomainGraphError -> Ordering
DomainGraphError -> DomainGraphError -> DomainGraphError
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: DomainGraphError -> DomainGraphError -> DomainGraphError
$cmin :: DomainGraphError -> DomainGraphError -> DomainGraphError
max :: DomainGraphError -> DomainGraphError -> DomainGraphError
$cmax :: DomainGraphError -> DomainGraphError -> DomainGraphError
>= :: DomainGraphError -> DomainGraphError -> Bool
$c>= :: DomainGraphError -> DomainGraphError -> Bool
> :: DomainGraphError -> DomainGraphError -> Bool
$c> :: DomainGraphError -> DomainGraphError -> Bool
<= :: DomainGraphError -> DomainGraphError -> Bool
$c<= :: DomainGraphError -> DomainGraphError -> Bool
< :: DomainGraphError -> DomainGraphError -> Bool
$c< :: DomainGraphError -> DomainGraphError -> Bool
compare :: DomainGraphError -> DomainGraphError -> Ordering
$ccompare :: DomainGraphError -> DomainGraphError -> Ordering
Ord, forall x. Rep DomainGraphError x -> DomainGraphError
forall x. DomainGraphError -> Rep DomainGraphError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DomainGraphError x -> DomainGraphError
$cfrom :: forall x. DomainGraphError -> Rep DomainGraphError x
Generic)
  deriving anyclass (Show DomainGraphError
Typeable DomainGraphError
SomeException -> Maybe DomainGraphError
DomainGraphError -> String
DomainGraphError -> SomeException
forall e.
Typeable e
-> Show e
-> (e -> SomeException)
-> (SomeException -> Maybe e)
-> (e -> String)
-> Exception e
displayException :: DomainGraphError -> String
$cdisplayException :: DomainGraphError -> String
fromException :: SomeException -> Maybe DomainGraphError
$cfromException :: SomeException -> Maybe DomainGraphError
toException :: DomainGraphError -> SomeException
$ctoException :: DomainGraphError -> SomeException
Exception)

data CheckResult
  = Ok
  | OkWithDiagnostics Diagnostics
  deriving (Int -> CheckResult -> ShowS
[CheckResult] -> ShowS
CheckResult -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CheckResult] -> ShowS
$cshowList :: [CheckResult] -> ShowS
show :: CheckResult -> String
$cshow :: CheckResult -> String
showsPrec :: Int -> CheckResult -> ShowS
$cshowsPrec :: Int -> CheckResult -> ShowS
Show, CheckResult -> CheckResult -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CheckResult -> CheckResult -> Bool
$c/= :: CheckResult -> CheckResult -> Bool
== :: CheckResult -> CheckResult -> Bool
$c== :: CheckResult -> CheckResult -> Bool
Eq, Eq CheckResult
CheckResult -> CheckResult -> Bool
CheckResult -> CheckResult -> Ordering
CheckResult -> CheckResult -> CheckResult
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CheckResult -> CheckResult -> CheckResult
$cmin :: CheckResult -> CheckResult -> CheckResult
max :: CheckResult -> CheckResult -> CheckResult
$cmax :: CheckResult -> CheckResult -> CheckResult
>= :: CheckResult -> CheckResult -> Bool
$c>= :: CheckResult -> CheckResult -> Bool
> :: CheckResult -> CheckResult -> Bool
$c> :: CheckResult -> CheckResult -> Bool
<= :: CheckResult -> CheckResult -> Bool
$c<= :: CheckResult -> CheckResult -> Bool
< :: CheckResult -> CheckResult -> Bool
$c< :: CheckResult -> CheckResult -> Bool
compare :: CheckResult -> CheckResult -> Ordering
$ccompare :: CheckResult -> CheckResult -> Ordering
Ord, forall x. Rep CheckResult x -> CheckResult
forall x. CheckResult -> Rep CheckResult x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CheckResult x -> CheckResult
$cfrom :: forall x. CheckResult -> Rep CheckResult x
Generic)

isEmptyDiagnostics :: Diagnostics -> Bool
isEmptyDiagnostics :: Diagnostics -> Bool
isEmptyDiagnostics Diagnostics {Map PackageName (Set Dependency)
usedExceptionalRules :: Diagnostics -> Map PackageName (Set Dependency)
redundantExtraDeps :: Diagnostics -> Map PackageName (Set Dependency)
usedExceptionalRules :: Map PackageName (Set Dependency)
redundantExtraDeps :: Map PackageName (Set Dependency)
..} =
  forall k a. Map k a -> Bool
Map.null Map PackageName (Set Dependency)
redundantExtraDeps
    -- && Set.null redundantDomainDeps
    Bool -> Bool -> Bool
&& forall k a. Map k a -> Bool
Map.null Map PackageName (Set Dependency)
usedExceptionalRules

data Diagnostics = Diagnostics
  { Diagnostics -> Map PackageName (Set Dependency)
redundantExtraDeps :: Map PackageName (Set Dependency)
  , -- , redundantDomainDeps :: Set (DomainName, DomainName)
    Diagnostics -> Map PackageName (Set Dependency)
usedExceptionalRules :: Map PackageName (Set Dependency)
  }
  deriving (Int -> Diagnostics -> ShowS
[Diagnostics] -> ShowS
Diagnostics -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Diagnostics] -> ShowS
$cshowList :: [Diagnostics] -> ShowS
show :: Diagnostics -> String
$cshow :: Diagnostics -> String
showsPrec :: Int -> Diagnostics -> ShowS
$cshowsPrec :: Int -> Diagnostics -> ShowS
Show, Diagnostics -> Diagnostics -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Diagnostics -> Diagnostics -> Bool
$c/= :: Diagnostics -> Diagnostics -> Bool
== :: Diagnostics -> Diagnostics -> Bool
$c== :: Diagnostics -> Diagnostics -> Bool
Eq, Eq Diagnostics
Diagnostics -> Diagnostics -> Bool
Diagnostics -> Diagnostics -> Ordering
Diagnostics -> Diagnostics -> Diagnostics
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Diagnostics -> Diagnostics -> Diagnostics
$cmin :: Diagnostics -> Diagnostics -> Diagnostics
max :: Diagnostics -> Diagnostics -> Diagnostics
$cmax :: Diagnostics -> Diagnostics -> Diagnostics
>= :: Diagnostics -> Diagnostics -> Bool
$c>= :: Diagnostics -> Diagnostics -> Bool
> :: Diagnostics -> Diagnostics -> Bool
$c> :: Diagnostics -> Diagnostics -> Bool
<= :: Diagnostics -> Diagnostics -> Bool
$c<= :: Diagnostics -> Diagnostics -> Bool
< :: Diagnostics -> Diagnostics -> Bool
$c< :: Diagnostics -> Diagnostics -> Bool
compare :: Diagnostics -> Diagnostics -> Ordering
$ccompare :: Diagnostics -> Diagnostics -> Ordering
Ord, forall x. Rep Diagnostics x -> Diagnostics
forall x. Diagnostics -> Rep Diagnostics x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Diagnostics x -> Diagnostics
$cfrom :: forall x. Diagnostics -> Rep Diagnostics x
Generic)

data DomainInfo = DomainInfo
  { DomainInfo -> Domains
domainConfig :: Domains
  , DomainInfo -> DomainGraph
domainGraph :: DomainGraph
  , DomainInfo -> PackageDic
packageDic :: PackageDic
  }
  deriving (Int -> DomainInfo -> ShowS
[DomainInfo] -> ShowS
DomainInfo -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DomainInfo] -> ShowS
$cshowList :: [DomainInfo] -> ShowS
show :: DomainInfo -> String
$cshow :: DomainInfo -> String
showsPrec :: Int -> DomainInfo -> ShowS
$cshowsPrec :: Int -> DomainInfo -> ShowS
Show, DomainInfo -> DomainInfo -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DomainInfo -> DomainInfo -> Bool
$c/= :: DomainInfo -> DomainInfo -> Bool
== :: DomainInfo -> DomainInfo -> Bool
$c== :: DomainInfo -> DomainInfo -> Bool
Eq, Eq DomainInfo
DomainInfo -> DomainInfo -> Bool
DomainInfo -> DomainInfo -> Ordering
DomainInfo -> DomainInfo -> DomainInfo
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: DomainInfo -> DomainInfo -> DomainInfo
$cmin :: DomainInfo -> DomainInfo -> DomainInfo
max :: DomainInfo -> DomainInfo -> DomainInfo
$cmax :: DomainInfo -> DomainInfo -> DomainInfo
>= :: DomainInfo -> DomainInfo -> Bool
$c>= :: DomainInfo -> DomainInfo -> Bool
> :: DomainInfo -> DomainInfo -> Bool
$c> :: DomainInfo -> DomainInfo -> Bool
<= :: DomainInfo -> DomainInfo -> Bool
$c<= :: DomainInfo -> DomainInfo -> Bool
< :: DomainInfo -> DomainInfo -> Bool
$c< :: DomainInfo -> DomainInfo -> Bool
compare :: DomainInfo -> DomainInfo -> Ordering
$ccompare :: DomainInfo -> DomainInfo -> Ordering
Ord, forall x. Rep DomainInfo x -> DomainInfo
forall x. DomainInfo -> Rep DomainInfo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DomainInfo x -> DomainInfo
$cfrom :: forall x. DomainInfo -> Rep DomainInfo x
Generic)

data PackageViolation
  = DomainBoundaryViolation
      { PackageViolation -> DomainName
fromDom :: DomainName
      , PackageViolation -> DomainName
toDom :: DomainName
      , PackageViolation -> [(PackageName, PackageName)]
introducedBy :: [(PackageName, PackageName)]
      }
  | CyclicPackageDep (Cycle PackageName)
  | UncoveredPackages [PackageName]
  deriving (Int -> PackageViolation -> ShowS
[PackageViolation] -> ShowS
PackageViolation -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PackageViolation] -> ShowS
$cshowList :: [PackageViolation] -> ShowS
show :: PackageViolation -> String
$cshow :: PackageViolation -> String
showsPrec :: Int -> PackageViolation -> ShowS
$cshowsPrec :: Int -> PackageViolation -> ShowS
Show, PackageViolation -> PackageViolation -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PackageViolation -> PackageViolation -> Bool
$c/= :: PackageViolation -> PackageViolation -> Bool
== :: PackageViolation -> PackageViolation -> Bool
$c== :: PackageViolation -> PackageViolation -> Bool
Eq, Eq PackageViolation
PackageViolation -> PackageViolation -> Bool
PackageViolation -> PackageViolation -> Ordering
PackageViolation -> PackageViolation -> PackageViolation
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PackageViolation -> PackageViolation -> PackageViolation
$cmin :: PackageViolation -> PackageViolation -> PackageViolation
max :: PackageViolation -> PackageViolation -> PackageViolation
$cmax :: PackageViolation -> PackageViolation -> PackageViolation
>= :: PackageViolation -> PackageViolation -> Bool
$c>= :: PackageViolation -> PackageViolation -> Bool
> :: PackageViolation -> PackageViolation -> Bool
$c> :: PackageViolation -> PackageViolation -> Bool
<= :: PackageViolation -> PackageViolation -> Bool
$c<= :: PackageViolation -> PackageViolation -> Bool
< :: PackageViolation -> PackageViolation -> Bool
$c< :: PackageViolation -> PackageViolation -> Bool
compare :: PackageViolation -> PackageViolation -> Ordering
$ccompare :: PackageViolation -> PackageViolation -> Ordering
Ord, forall x. Rep PackageViolation x -> PackageViolation
forall x. PackageViolation -> Rep PackageViolation x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PackageViolation x -> PackageViolation
$cfrom :: forall x. PackageViolation -> Rep PackageViolation x
Generic)
  deriving anyclass (Show PackageViolation
Typeable PackageViolation
SomeException -> Maybe PackageViolation
PackageViolation -> String
PackageViolation -> SomeException
forall e.
Typeable e
-> Show e
-> (e -> SomeException)
-> (SomeException -> Maybe e)
-> (e -> String)
-> Exception e
displayException :: PackageViolation -> String
$cdisplayException :: PackageViolation -> String
fromException :: SomeException -> Maybe PackageViolation
$cfromException :: SomeException -> Maybe PackageViolation
toException :: PackageViolation -> SomeException
$ctoException :: PackageViolation -> SomeException
Exception)

newtype PackageName = PackageName {PackageName -> Text
getPackageName :: Text}
  deriving (PackageName -> PackageName -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PackageName -> PackageName -> Bool
$c/= :: PackageName -> PackageName -> Bool
== :: PackageName -> PackageName -> Bool
$c== :: PackageName -> PackageName -> Bool
Eq, Eq PackageName
PackageName -> PackageName -> Bool
PackageName -> PackageName -> Ordering
PackageName -> PackageName -> PackageName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PackageName -> PackageName -> PackageName
$cmin :: PackageName -> PackageName -> PackageName
max :: PackageName -> PackageName -> PackageName
$cmax :: PackageName -> PackageName -> PackageName
>= :: PackageName -> PackageName -> Bool
$c>= :: PackageName -> PackageName -> Bool
> :: PackageName -> PackageName -> Bool
$c> :: PackageName -> PackageName -> Bool
<= :: PackageName -> PackageName -> Bool
$c<= :: PackageName -> PackageName -> Bool
< :: PackageName -> PackageName -> Bool
$c< :: PackageName -> PackageName -> Bool
compare :: PackageName -> PackageName -> Ordering
$ccompare :: PackageName -> PackageName -> Ordering
Ord, forall x. Rep PackageName x -> PackageName
forall x. PackageName -> Rep PackageName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PackageName x -> PackageName
$cfrom :: forall x. PackageName -> Rep PackageName x
Generic)
  deriving newtype (Int -> PackageName -> ShowS
[PackageName] -> ShowS
PackageName -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PackageName] -> ShowS
$cshowList :: [PackageName] -> ShowS
show :: PackageName -> String
$cshow :: PackageName -> String
showsPrec :: Int -> PackageName -> ShowS
$cshowsPrec :: Int -> PackageName -> ShowS
Show, String -> PackageName
forall a. (String -> a) -> IsString a
fromString :: String -> PackageName
$cfromString :: String -> PackageName
IsString, Value -> Parser [PackageName]
Value -> Parser PackageName
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [PackageName]
$cparseJSONList :: Value -> Parser [PackageName]
parseJSON :: Value -> Parser PackageName
$cparseJSON :: Value -> Parser PackageName
FromJSON, Eq PackageName
Int -> PackageName -> Int
PackageName -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: PackageName -> Int
$chash :: PackageName -> Int
hashWithSalt :: Int -> PackageName -> Int
$chashWithSalt :: Int -> PackageName -> Int
Hashable)

newtype DomainName = DomainName {DomainName -> Text
getDomainName :: Text}
  deriving (DomainName -> DomainName -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DomainName -> DomainName -> Bool
$c/= :: DomainName -> DomainName -> Bool
== :: DomainName -> DomainName -> Bool
$c== :: DomainName -> DomainName -> Bool
Eq, Eq DomainName
DomainName -> DomainName -> Bool
DomainName -> DomainName -> Ordering
DomainName -> DomainName -> DomainName
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: DomainName -> DomainName -> DomainName
$cmin :: DomainName -> DomainName -> DomainName
max :: DomainName -> DomainName -> DomainName
$cmax :: DomainName -> DomainName -> DomainName
>= :: DomainName -> DomainName -> Bool
$c>= :: DomainName -> DomainName -> Bool
> :: DomainName -> DomainName -> Bool
$c> :: DomainName -> DomainName -> Bool
<= :: DomainName -> DomainName -> Bool
$c<= :: DomainName -> DomainName -> Bool
< :: DomainName -> DomainName -> Bool
$c< :: DomainName -> DomainName -> Bool
compare :: DomainName -> DomainName -> Ordering
$ccompare :: DomainName -> DomainName -> Ordering
Ord, forall x. Rep DomainName x -> DomainName
forall x. DomainName -> Rep DomainName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep DomainName x -> DomainName
$cfrom :: forall x. DomainName -> Rep DomainName x
Generic)
  deriving newtype (Int -> DomainName -> ShowS
[DomainName] -> ShowS
DomainName -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DomainName] -> ShowS
$cshowList :: [DomainName] -> ShowS
show :: DomainName -> String
$cshow :: DomainName -> String
showsPrec :: Int -> DomainName -> ShowS
$cshowsPrec :: Int -> DomainName -> ShowS
Show, String -> DomainName
forall a. (String -> a) -> IsString a
fromString :: String -> DomainName
$cfromString :: String -> DomainName
IsString, Value -> Parser [DomainName]
Value -> Parser DomainName
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [DomainName]
$cparseJSONList :: Value -> Parser [DomainName]
parseJSON :: Value -> Parser DomainName
$cparseJSON :: Value -> Parser DomainName
FromJSON, FromJSONKeyFunction [DomainName]
FromJSONKeyFunction DomainName
forall a.
FromJSONKeyFunction a -> FromJSONKeyFunction [a] -> FromJSONKey a
fromJSONKeyList :: FromJSONKeyFunction [DomainName]
$cfromJSONKeyList :: FromJSONKeyFunction [DomainName]
fromJSONKey :: FromJSONKeyFunction DomainName
$cfromJSONKey :: FromJSONKeyFunction DomainName
FromJSONKey, Eq DomainName
Int -> DomainName -> Int
DomainName -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: DomainName -> Int
$chash :: DomainName -> Int
hashWithSalt :: Int -> DomainName -> Int
$chashWithSalt :: Int -> DomainName -> Int
Hashable)

data Domain = Domain
  { Domain -> Maybe (Vector DomainName)
dependsOn :: Maybe (V.Vector DomainName)
  , Domain -> Vector PackageDef
packages :: V.Vector PackageDef
  }
  deriving (Int -> Domain -> ShowS
[Domain] -> ShowS
Domain -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Domain] -> ShowS
$cshowList :: [Domain] -> ShowS
show :: Domain -> String
$cshow :: Domain -> String
showsPrec :: Int -> Domain -> ShowS
$cshowsPrec :: Int -> Domain -> ShowS
Show, Domain -> Domain -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Domain -> Domain -> Bool
$c/= :: Domain -> Domain -> Bool
== :: Domain -> Domain -> Bool
$c== :: Domain -> Domain -> Bool
Eq, Eq Domain
Domain -> Domain -> Bool
Domain -> Domain -> Ordering
Domain -> Domain -> Domain
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Domain -> Domain -> Domain
$cmin :: Domain -> Domain -> Domain
max :: Domain -> Domain -> Domain
$cmax :: Domain -> Domain -> Domain
>= :: Domain -> Domain -> Bool
$c>= :: Domain -> Domain -> Bool
> :: Domain -> Domain -> Bool
$c> :: Domain -> Domain -> Bool
<= :: Domain -> Domain -> Bool
$c<= :: Domain -> Domain -> Bool
< :: Domain -> Domain -> Bool
$c< :: Domain -> Domain -> Bool
compare :: Domain -> Domain -> Ordering
$ccompare :: Domain -> Domain -> Ordering
Ord, forall x. Rep Domain x -> Domain
forall x. Domain -> Rep Domain x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Domain x -> Domain
$cfrom :: forall x. Domain -> Rep Domain x
Generic)

instance FromJSON Domain where
  parseJSON :: Value -> Parser Domain
parseJSON =
    forall a.
(Generic a, GFromJSON Zero (Rep a)) =>
Options -> Value -> Parser a
genericParseJSON
      Options
J.defaultOptions
        { omitNothingFields :: Bool
J.omitNothingFields = Bool
True
        , fieldLabelModifier :: ShowS
J.fieldLabelModifier = Char -> ShowS
J.camelTo2 Char
'_'
        }

newtype Domains = Domains {Domains -> HashMap DomainName Domain
domains :: HM.HashMap DomainName Domain}
  deriving (Int -> Domains -> ShowS
[Domains] -> ShowS
Domains -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Domains] -> ShowS
$cshowList :: [Domains] -> ShowS
show :: Domains -> String
$cshow :: Domains -> String
showsPrec :: Int -> Domains -> ShowS
$cshowsPrec :: Int -> Domains -> ShowS
Show, Domains -> Domains -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Domains -> Domains -> Bool
$c/= :: Domains -> Domains -> Bool
== :: Domains -> Domains -> Bool
$c== :: Domains -> Domains -> Bool
Eq, Eq Domains
Domains -> Domains -> Bool
Domains -> Domains -> Ordering
Domains -> Domains -> Domains
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Domains -> Domains -> Domains
$cmin :: Domains -> Domains -> Domains
max :: Domains -> Domains -> Domains
$cmax :: Domains -> Domains -> Domains
>= :: Domains -> Domains -> Bool
$c>= :: Domains -> Domains -> Bool
> :: Domains -> Domains -> Bool
$c> :: Domains -> Domains -> Bool
<= :: Domains -> Domains -> Bool
$c<= :: Domains -> Domains -> Bool
< :: Domains -> Domains -> Bool
$c< :: Domains -> Domains -> Bool
compare :: Domains -> Domains -> Ordering
$ccompare :: Domains -> Domains -> Ordering
Ord, forall x. Rep Domains x -> Domains
forall x. Domains -> Rep Domains x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Domains x -> Domains
$cfrom :: forall x. Domains -> Rep Domains x
Generic)
  deriving anyclass (Value -> Parser [Domains]
Value -> Parser Domains
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [Domains]
$cparseJSONList :: Value -> Parser [Domains]
parseJSON :: Value -> Parser Domains
$cparseJSON :: Value -> Parser Domains
FromJSON)

data PackageDef = PackageDef
  { PackageDef -> PackageName
packageName :: !PackageName
  , PackageDef -> Vector Dependency
extraDeps :: V.Vector Dependency
  }
  deriving (Int -> PackageDef -> ShowS
[PackageDef] -> ShowS
PackageDef -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PackageDef] -> ShowS
$cshowList :: [PackageDef] -> ShowS
show :: PackageDef -> String
$cshow :: PackageDef -> String
showsPrec :: Int -> PackageDef -> ShowS
$cshowsPrec :: Int -> PackageDef -> ShowS
Show, PackageDef -> PackageDef -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PackageDef -> PackageDef -> Bool
$c/= :: PackageDef -> PackageDef -> Bool
== :: PackageDef -> PackageDef -> Bool
$c== :: PackageDef -> PackageDef -> Bool
Eq, Eq PackageDef
PackageDef -> PackageDef -> Bool
PackageDef -> PackageDef -> Ordering
PackageDef -> PackageDef -> PackageDef
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PackageDef -> PackageDef -> PackageDef
$cmin :: PackageDef -> PackageDef -> PackageDef
max :: PackageDef -> PackageDef -> PackageDef
$cmax :: PackageDef -> PackageDef -> PackageDef
>= :: PackageDef -> PackageDef -> Bool
$c>= :: PackageDef -> PackageDef -> Bool
> :: PackageDef -> PackageDef -> Bool
$c> :: PackageDef -> PackageDef -> Bool
<= :: PackageDef -> PackageDef -> Bool
$c<= :: PackageDef -> PackageDef -> Bool
< :: PackageDef -> PackageDef -> Bool
$c< :: PackageDef -> PackageDef -> Bool
compare :: PackageDef -> PackageDef -> Ordering
$ccompare :: PackageDef -> PackageDef -> Ordering
Ord, forall x. Rep PackageDef x -> PackageDef
forall x. PackageDef -> Rep PackageDef x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PackageDef x -> PackageDef
$cfrom :: forall x. PackageDef -> Rep PackageDef x
Generic)

instance FromJSON PackageDef where
  parseJSON :: Value -> Parser PackageDef
parseJSON =
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT forall a b. (a -> b) -> a -> b
$
      forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT (forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"package name" (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PackageName -> Vector Dependency -> PackageDef
`PackageDef` forall a. Vector a
V.empty) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> PackageName
PackageName))
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT do
          forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"object" forall a b. (a -> b) -> a -> b
$ \Object
dic -> do
            PackageName
packageName <- Object
dic forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"package"
            Maybe Object
excepts <- Object
dic forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"exception"
            Vector Dependency
extraDeps <- forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Vector a
V.empty) (forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"depends_on") Maybe Object
excepts
            forall (f :: * -> *) a. Applicative f => a -> f a
pure PackageDef {Vector Dependency
PackageName
extraDeps :: Vector Dependency
packageName :: PackageName
extraDeps :: Vector Dependency
packageName :: PackageName
..}

data Dependency
  = DomainDep !DomainName
  | PackageDep !PackageName
  deriving (Int -> Dependency -> ShowS
[Dependency] -> ShowS
Dependency -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Dependency] -> ShowS
$cshowList :: [Dependency] -> ShowS
show :: Dependency -> String
$cshow :: Dependency -> String
showsPrec :: Int -> Dependency -> ShowS
$cshowsPrec :: Int -> Dependency -> ShowS
Show, Dependency -> Dependency -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Dependency -> Dependency -> Bool
$c/= :: Dependency -> Dependency -> Bool
== :: Dependency -> Dependency -> Bool
$c== :: Dependency -> Dependency -> Bool
Eq, Eq Dependency
Dependency -> Dependency -> Bool
Dependency -> Dependency -> Ordering
Dependency -> Dependency -> Dependency
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Dependency -> Dependency -> Dependency
$cmin :: Dependency -> Dependency -> Dependency
max :: Dependency -> Dependency -> Dependency
$cmax :: Dependency -> Dependency -> Dependency
>= :: Dependency -> Dependency -> Bool
$c>= :: Dependency -> Dependency -> Bool
> :: Dependency -> Dependency -> Bool
$c> :: Dependency -> Dependency -> Bool
<= :: Dependency -> Dependency -> Bool
$c<= :: Dependency -> Dependency -> Bool
< :: Dependency -> Dependency -> Bool
$c< :: Dependency -> Dependency -> Bool
compare :: Dependency -> Dependency -> Ordering
$ccompare :: Dependency -> Dependency -> Ordering
Ord, forall x. Rep Dependency x -> Dependency
forall x. Dependency -> Rep Dependency x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Dependency x -> Dependency
$cfrom :: forall x. Dependency -> Rep Dependency x
Generic)

instance FromJSON Dependency where
  parseJSON :: Value -> Parser Dependency
parseJSON =
    forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT forall a b. (a -> b) -> a -> b
$
      forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT (forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"domain name" (forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. DomainName -> Dependency
DomainDep forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> DomainName
DomainName))
        forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT
          ( forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject
              String
"{package: ...} or {domain: ...}"
              ( \Object
obj ->
                  DomainName -> Dependency
DomainDep forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"domain"
                    forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> PackageName -> Dependency
PackageDep forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"package"
              )
          )

newtype Overlayed gr = Overlayed {forall gr. Overlayed gr -> gr
getOverlayed :: gr}
  deriving (Int -> Overlayed gr -> ShowS
forall gr. Show gr => Int -> Overlayed gr -> ShowS
forall gr. Show gr => [Overlayed gr] -> ShowS
forall gr. Show gr => Overlayed gr -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Overlayed gr] -> ShowS
$cshowList :: forall gr. Show gr => [Overlayed gr] -> ShowS
show :: Overlayed gr -> String
$cshow :: forall gr. Show gr => Overlayed gr -> String
showsPrec :: Int -> Overlayed gr -> ShowS
$cshowsPrec :: forall gr. Show gr => Int -> Overlayed gr -> ShowS
Show, Overlayed gr -> Overlayed gr -> Bool
forall gr. Eq gr => Overlayed gr -> Overlayed gr -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Overlayed gr -> Overlayed gr -> Bool
$c/= :: forall gr. Eq gr => Overlayed gr -> Overlayed gr -> Bool
== :: Overlayed gr -> Overlayed gr -> Bool
$c== :: forall gr. Eq gr => Overlayed gr -> Overlayed gr -> Bool
Eq, Overlayed gr -> Overlayed gr -> Bool
Overlayed gr -> Overlayed gr -> Ordering
Overlayed gr -> Overlayed gr -> Overlayed gr
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {gr}. Ord gr => Eq (Overlayed gr)
forall gr. Ord gr => Overlayed gr -> Overlayed gr -> Bool
forall gr. Ord gr => Overlayed gr -> Overlayed gr -> Ordering
forall gr. Ord gr => Overlayed gr -> Overlayed gr -> Overlayed gr
min :: Overlayed gr -> Overlayed gr -> Overlayed gr
$cmin :: forall gr. Ord gr => Overlayed gr -> Overlayed gr -> Overlayed gr
max :: Overlayed gr -> Overlayed gr -> Overlayed gr
$cmax :: forall gr. Ord gr => Overlayed gr -> Overlayed gr -> Overlayed gr
>= :: Overlayed gr -> Overlayed gr -> Bool
$c>= :: forall gr. Ord gr => Overlayed gr -> Overlayed gr -> Bool
> :: Overlayed gr -> Overlayed gr -> Bool
$c> :: forall gr. Ord gr => Overlayed gr -> Overlayed gr -> Bool
<= :: Overlayed gr -> Overlayed gr -> Bool
$c<= :: forall gr. Ord gr => Overlayed gr -> Overlayed gr -> Bool
< :: Overlayed gr -> Overlayed gr -> Bool
$c< :: forall gr. Ord gr => Overlayed gr -> Overlayed gr -> Bool
compare :: Overlayed gr -> Overlayed gr -> Ordering
$ccompare :: forall gr. Ord gr => Overlayed gr -> Overlayed gr -> Ordering
Ord)

instance GC.Graph gr => Semigroup (Overlayed gr) where
  <> :: Overlayed gr -> Overlayed gr -> Overlayed gr
(<>) = coerce :: forall a b. Coercible a b => a -> b
coerce forall a b. (a -> b) -> a -> b
$ forall g. Graph g => g -> g -> g
GC.overlay @gr

instance GC.Graph gr => Monoid (Overlayed gr) where
  mempty :: Overlayed gr
mempty = forall gr. gr -> Overlayed gr
Overlayed forall g. Graph g => g
GC.empty