module Ecluse.Composition.Vet (
Vet,
runVet,
withRole,
decided,
Severity (..),
rule,
byStoreRole,
) where
import Validation (Validation (Failure, Success), validationToEither)
import Ecluse.Composition.BootError (Advisory, BootError)
import Ecluse.Composition.Types (RegistryRole (MirrorPreviewer, MirrorPruner, MirrorWriter))
newtype Vet a = Vet (RegistryRole -> ([Advisory], Validation [BootError] a))
instance Functor Vet where
fmap :: forall a b. (a -> b) -> Vet a -> Vet b
fmap a -> b
f (Vet RegistryRole -> ([Advisory], Validation [BootError] a)
run) = (RegistryRole -> ([Advisory], Validation [BootError] b)) -> Vet b
forall a.
(RegistryRole -> ([Advisory], Validation [BootError] a)) -> Vet a
Vet ((RegistryRole -> ([Advisory], Validation [BootError] b)) -> Vet b)
-> (RegistryRole -> ([Advisory], Validation [BootError] b))
-> Vet b
forall a b. (a -> b) -> a -> b
$ \RegistryRole
role ->
let ([Advisory]
advisories, Validation [BootError] a
outcome) = RegistryRole -> ([Advisory], Validation [BootError] a)
run RegistryRole
role
in ([Advisory]
advisories, (a -> b) -> Validation [BootError] a -> Validation [BootError] b
forall a b.
(a -> b) -> Validation [BootError] a -> Validation [BootError] b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Validation [BootError] a
outcome)
instance Applicative Vet where
pure :: forall a. a -> Vet a
pure a
a = (RegistryRole -> ([Advisory], Validation [BootError] a)) -> Vet a
forall a.
(RegistryRole -> ([Advisory], Validation [BootError] a)) -> Vet a
Vet (([Advisory], Validation [BootError] a)
-> RegistryRole -> ([Advisory], Validation [BootError] a)
forall a b. a -> b -> a
const ([], a -> Validation [BootError] a
forall e a. a -> Validation e a
Success a
a))
Vet RegistryRole -> ([Advisory], Validation [BootError] (a -> b))
runF <*> :: forall a b. Vet (a -> b) -> Vet a -> Vet b
<*> Vet RegistryRole -> ([Advisory], Validation [BootError] a)
runA = (RegistryRole -> ([Advisory], Validation [BootError] b)) -> Vet b
forall a.
(RegistryRole -> ([Advisory], Validation [BootError] a)) -> Vet a
Vet ((RegistryRole -> ([Advisory], Validation [BootError] b)) -> Vet b)
-> (RegistryRole -> ([Advisory], Validation [BootError] b))
-> Vet b
forall a b. (a -> b) -> a -> b
$ \RegistryRole
role ->
let ([Advisory]
fAdvisories, Validation [BootError] (a -> b)
f) = RegistryRole -> ([Advisory], Validation [BootError] (a -> b))
runF RegistryRole
role
([Advisory]
aAdvisories, Validation [BootError] a
a) = RegistryRole -> ([Advisory], Validation [BootError] a)
runA RegistryRole
role
in ([Advisory]
fAdvisories [Advisory] -> [Advisory] -> [Advisory]
forall a. Semigroup a => a -> a -> a
<> [Advisory]
aAdvisories, Validation [BootError] (a -> b)
f Validation [BootError] (a -> b)
-> Validation [BootError] a -> Validation [BootError] b
forall a b.
Validation [BootError] (a -> b)
-> Validation [BootError] a -> Validation [BootError] b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Validation [BootError] a
a)
runVet :: RegistryRole -> Vet a -> ([Advisory], Either [BootError] a)
runVet :: forall a.
RegistryRole -> Vet a -> ([Advisory], Either [BootError] a)
runVet RegistryRole
role (Vet RegistryRole -> ([Advisory], Validation [BootError] a)
run) = (Validation [BootError] a -> Either [BootError] a)
-> ([Advisory], Validation [BootError] a)
-> ([Advisory], Either [BootError] a)
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second Validation [BootError] a -> Either [BootError] a
forall e a. Validation e a -> Either e a
validationToEither (RegistryRole -> ([Advisory], Validation [BootError] a)
run RegistryRole
role)
withRole :: (RegistryRole -> Vet a) -> Vet a
withRole :: forall a. (RegistryRole -> Vet a) -> Vet a
withRole RegistryRole -> Vet a
select = (RegistryRole -> ([Advisory], Validation [BootError] a)) -> Vet a
forall a.
(RegistryRole -> ([Advisory], Validation [BootError] a)) -> Vet a
Vet ((RegistryRole -> ([Advisory], Validation [BootError] a)) -> Vet a)
-> (RegistryRole -> ([Advisory], Validation [BootError] a))
-> Vet a
forall a b. (a -> b) -> a -> b
$ \RegistryRole
role -> let Vet RegistryRole -> ([Advisory], Validation [BootError] a)
run = RegistryRole -> Vet a
select RegistryRole
role in RegistryRole -> ([Advisory], Validation [BootError] a)
run RegistryRole
role
decided :: Either [BootError] a -> Vet a
decided :: forall a. Either [BootError] a -> Vet a
decided Either [BootError] a
outcome = (RegistryRole -> ([Advisory], Validation [BootError] a)) -> Vet a
forall a.
(RegistryRole -> ([Advisory], Validation [BootError] a)) -> Vet a
Vet ((RegistryRole -> ([Advisory], Validation [BootError] a)) -> Vet a)
-> (([Advisory], Validation [BootError] a)
-> RegistryRole -> ([Advisory], Validation [BootError] a))
-> ([Advisory], Validation [BootError] a)
-> Vet a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Advisory], Validation [BootError] a)
-> RegistryRole -> ([Advisory], Validation [BootError] a)
forall a b. a -> b -> a
const (([Advisory], Validation [BootError] a) -> Vet a)
-> ([Advisory], Validation [BootError] a) -> Vet a
forall a b. (a -> b) -> a -> b
$ case Either [BootError] a
outcome of
Left [BootError]
errs -> ([], [BootError] -> Validation [BootError] a
forall e a. e -> Validation e a
Failure [BootError]
errs)
Right a
a -> ([], a -> Validation [BootError] a
forall e a. a -> Validation e a
Success a
a)
data Severity finding
=
Refuse (finding -> BootError)
|
Advise (finding -> Advisory)
|
Ignore
byStoreRole :: Severity finding -> Severity finding -> RegistryRole -> Severity finding
byStoreRole :: forall finding.
Severity finding
-> Severity finding -> RegistryRole -> Severity finding
byStoreRole Severity finding
stores Severity finding
writer = \case
RegistryRole
MirrorPruner -> Severity finding
stores
RegistryRole
MirrorPreviewer -> Severity finding
stores
RegistryRole
MirrorWriter -> Severity finding
writer
rule :: (RegistryRole -> Severity finding) -> (input -> Maybe finding) -> input -> Vet ()
rule :: forall finding input.
(RegistryRole -> Severity finding)
-> (input -> Maybe finding) -> input -> Vet ()
rule RegistryRole -> Severity finding
severity input -> Maybe finding
detect input
input = (RegistryRole -> ([Advisory], Validation [BootError] ())) -> Vet ()
forall a.
(RegistryRole -> ([Advisory], Validation [BootError] a)) -> Vet a
Vet ((RegistryRole -> ([Advisory], Validation [BootError] ()))
-> Vet ())
-> (RegistryRole -> ([Advisory], Validation [BootError] ()))
-> Vet ()
forall a b. (a -> b) -> a -> b
$ \RegistryRole
role ->
case (input -> Maybe finding
detect input
input, RegistryRole -> Severity finding
severity RegistryRole
role) of
(Maybe finding
Nothing, Severity finding
_) -> ([], () -> Validation [BootError] ()
forall e a. a -> Validation e a
Success ())
(Just finding
finding, Refuse finding -> BootError
toRefusal) -> ([], [BootError] -> Validation [BootError] ()
forall e a. e -> Validation e a
Failure [finding -> BootError
toRefusal finding
finding])
(Just finding
finding, Advise finding -> Advisory
toAdvisory) -> ([finding -> Advisory
toAdvisory finding
finding], () -> Validation [BootError] ()
forall e a. a -> Validation e a
Success ())
(Just finding
_, Severity finding
Ignore) -> ([], () -> Validation [BootError] ()
forall e a. a -> Validation e a
Success ())