keuringsdienst-0.1.0.2: src/Keuringsdienst.hs
{-
Copyright © 2023 Josep Bigorra
This file is part of Keuringsdienst.
Keuringsdienst is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation,
either version 3 of the License, or (at your option) any later version.
Keuringsdienst is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Keuringsdienst.
If not, see <https://www.gnu.org/licenses/>.
-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Keuringsdienst
( (*||*),
(|??|),
(|?|),
ValidationResult,
ValidationRule (..),
Validation (..),
keuren,
misschienKeuren,
validate,
maybeValidate,
ofDitOfDat,
)
where
import Data.Aeson hiding (Success)
import Data.Text as T
import GHC.Generics
type ErrMsg = Text
data Validation err
= Success
| Failure err
deriving (Eq, Show, Generic, FromJSON, ToJSON)
type ValidationResult = Validation [ErrMsg]
instance Semigroup ValidationResult where
(<>) a b = case a of
Success -> case b of
Success -> Success
Failure errorsB -> Failure errorsB
Failure errorsA -> case b of
Success -> Failure errorsA
Failure errorsB -> Failure (errorsA <> errorsB)
instance Monoid ValidationResult where
mempty = Success
newtype ValidationRule a = ValidationRule
{ performValidation :: a -> ValidationResult
}
instance Semigroup (ValidationRule x) where
(<>) a b = do
ValidationRule
{ performValidation = \value -> performValidation a value <> performValidation b value
}
instance Monoid (ValidationRule a) where
mempty = ValidationRule {performValidation = const Success}
-- keuren operator
keuren :: a -> ValidationRule a -> ValidationResult
keuren x rule = performValidation rule x
infixl 8 |?|
-- keuren operator
(|?|) :: a -> ValidationRule a -> ValidationResult
(|?|) = keuren
-- keuren operator
validate :: a -> ValidationRule a -> ValidationResult
validate = keuren
-- misschienKeuren operator
misschienKeuren :: Maybe a -> ValidationRule a -> ValidationResult
misschienKeuren x rule = maybe Success (performValidation rule) x
infixl 8 |??|
-- misschienKeuren operator
(|??|) :: Maybe a -> ValidationRule a -> ValidationResult
(|??|) = misschienKeuren
-- misschienKeuren operator
maybeValidate :: Maybe a -> ValidationRule a -> ValidationResult
maybeValidate = misschienKeuren
-- if one of the validations has a successful result, then the validation is a success
ofDitOfDat :: ValidationRule a -> ValidationRule a -> ValidationRule a
ofDitOfDat rule1 rule2 = ValidationRule $ \actual ->
case (performValidation rule1 actual, performValidation rule2 actual) of
(Failure e1, Failure e2) -> Failure (e1 <> e2)
(Success, _) -> Success
(_, Success) -> Success
infixl 6 *||*
-- ofDitOfDat operator
(*||*) :: ValidationRule a -> ValidationRule a -> ValidationRule a
(*||*) = ofDitOfDat