packages feed

validate-input 0.3.0.0 → 0.4.0.0

raw patch · 3 files changed

+64/−13 lines, 3 filesdep +semigroupsPVP ok

version bump matches the API change (PVP)

Dependencies added: semigroups

API changes (from Hackage documentation)

- Data.Validator: instance (Monad m, Monoid e) => Alternative (ValidationT e m)
- Data.Validator: instance (Monad m, Monoid e) => MonadPlus (ValidationT e m)
- Data.Validator: instance HasLength ByteString
- Data.Validator: instance HasLength Text
- Data.Validator: instance HasLength [a]
- Data.Validator: instance Monad m => Applicative (ValidationT e m)
- Data.Validator: instance Monad m => Functor (ValidationT e m)
- Data.Validator: instance Monad m => Monad (ValidationT e m)
- Data.Validator: instance MonadTrans (ValidationT e)
+ Data.Validator: conformsPredTrans :: Monad m => (a -> Maybe b) -> e -> TransValidationRuleT e m a b
+ Data.Validator: conformsPredTransM :: Monad m => (a -> m (Maybe b)) -> e -> TransValidationRuleT e m a b
+ Data.Validator: instance (GHC.Base.Monad m, GHC.Base.Monoid e) => GHC.Base.Alternative (Data.Validator.ValidationT e m)
+ Data.Validator: instance (GHC.Base.Monad m, GHC.Base.Monoid e) => GHC.Base.MonadPlus (Data.Validator.ValidationT e m)
+ Data.Validator: instance Control.Monad.Trans.Class.MonadTrans (Data.Validator.ValidationT e)
+ Data.Validator: instance Data.Validator.HasLength Data.ByteString.Internal.ByteString
+ Data.Validator: instance Data.Validator.HasLength Data.ByteString.Lazy.Internal.ByteString
+ Data.Validator: instance Data.Validator.HasLength Data.Text.Internal.Lazy.Text
+ Data.Validator: instance Data.Validator.HasLength Data.Text.Internal.Text
+ Data.Validator: instance Data.Validator.HasLength [a]
+ Data.Validator: instance GHC.Base.Monad m => GHC.Base.Applicative (Data.Validator.ValidationT e m)
+ Data.Validator: instance GHC.Base.Monad m => GHC.Base.Functor (Data.Validator.ValidationT e m)
+ Data.Validator: instance GHC.Base.Monad m => GHC.Base.Monad (Data.Validator.ValidationT e m)
+ Data.Validator: nonEmptyList :: Monad m => e -> TransValidationRuleT e m [a] (NonEmpty a)
+ Data.Validator: requiredValue :: Monad m => e -> TransValidationRuleT e m (Maybe a) a
+ Data.Validator: type TransValidationRule e a b = TransValidationRuleT e Identity a b
+ Data.Validator: type TransValidationRuleT e m a b = a -> ValidationT e m b
- Data.Validator: runValidator :: ValidationRule e a -> a -> Either e a
+ Data.Validator: runValidator :: TransValidationRule e a b -> a -> Either e b
- Data.Validator: runValidatorT :: Monad m => ValidationRuleT e m a -> a -> m (Either e a)
+ Data.Validator: runValidatorT :: Monad m => TransValidationRuleT e m a b -> a -> m (Either e b)
- Data.Validator: type ValidationRuleT e m a = a -> ValidationT e m a
+ Data.Validator: type ValidationRuleT e m a = TransValidationRuleT e m a a

Files

README.md view
@@ -24,8 +24,16 @@    = Example    { ex_username :: T.Text    , ex_dogs :: Int+   , ex_friendName :: Maybe T.Text    } deriving (Show) +data ExampleChecked+   = ExampleChecked+   { exc_username :: T.Text+   , exc_dogs :: Int+   , exc_friendName :: T.Text+   } deriving (Show)+ main :: IO () main =     do putStrLn "Check results:"@@ -40,17 +48,20 @@ checkNumber =     smallerThan 5 "No more than 5 dogs allowed" -checkExample :: Monad m => ValidationRuleT String m Example+checkExample :: Monad m => TransValidationRuleT String m Example ExampleChecked checkExample e =-    Example <$> checkUsername (ex_username e)-            <*> checkNumber (ex_dogs e)+    ExampleChecked+    <$> checkUsername (ex_username e)+    <*> checkNumber (ex_dogs e)+    <*> requiredValue "You must provide a friend name!" (ex_friendName e) -example :: Either String Example+example :: Either String ExampleChecked example =     runValidator checkExample $     Example     { ex_username = "alex"     , ex_dogs = 23+    , ex_friendName = Nothing     }  ```
src/Data/Validator.hs view
@@ -4,7 +4,9 @@ {-# LANGUAGE OverloadedStrings #-} module Data.Validator     ( -- * Core monad and runners-      ValidationM, ValidationT, ValidationRule, ValidationRuleT+      ValidationM, ValidationT+    , ValidationRule, ValidationRuleT+    , TransValidationRule, TransValidationRuleT     , runValidator, runValidatorT       -- * Combinators     , (>=>), (<=<)@@ -13,6 +15,9 @@     , largerThan, smallerThan, valueBetween     , matchesRegex     , conformsPred, conformsPredM+      -- * Transforming checks+    , requiredValue, nonEmptyList+    , conformsPredTrans, conformsPredTransM       -- * Helper classes and types     , HasLength(..), ConvertibleStrings(..)     , Int64@@ -29,6 +34,7 @@ import Data.Int import Data.String.Conversions import Text.Regex.PCRE.Heavy+import qualified Data.List.NonEmpty as NEL import qualified Data.Text as T import qualified Data.Text.Lazy as TL import qualified Data.ByteString as BS@@ -43,12 +49,12 @@       deriving (Monad, Functor, Applicative, Alternative, MonadPlus, MonadTrans)  -- | Run a validation on a type 'a'-runValidator :: ValidationRule e a -> a -> Either e a+runValidator :: TransValidationRule e a b -> a -> Either e b runValidator a b = runIdentity $ runValidatorT a b {-# INLINE runValidator #-}  -- | Run a validation on a type 'a'-runValidatorT :: Monad m => ValidationRuleT e m a -> a -> m (Either e a)+runValidatorT :: Monad m => TransValidationRuleT e m a b -> a -> m (Either e b) runValidatorT validationSteps input =     runEitherT $ unValidationT (validationSteps input) {-# INLINE runValidatorT #-}@@ -57,8 +63,14 @@ type ValidationRule e a = ValidationRuleT e Identity a  -- | A validation rule. Combine using @('>=>')@ or @('<=<')@-type ValidationRuleT e m a = a -> ValidationT e m a+type ValidationRuleT e m a = TransValidationRuleT e m a a +-- | A transforming validation rule. Combine using @('>=>')@ or @('<=<')@+type TransValidationRule e a b = TransValidationRuleT e Identity a b++-- | A transforming validation rule. Combine using @('>=>')@ or @('<=<')@+type TransValidationRuleT e m a b = a -> ValidationT e m b+ -- | All types that have a length, eg. 'String', '[a]', 'Vector a', etc. class HasLength a where     getLength :: a -> Int64@@ -124,6 +136,11 @@ valueBetween lowerBound upperBound e = largerThan lowerBound e >=> smallerThan upperBound e {-# INLINE valueBetween #-} +-- | Checks that a value matches a regular expression+matchesRegex :: (ConvertibleStrings SBS a, ConvertibleStrings a SBS, Monad m) => Regex -> e -> ValidationRuleT e m a+matchesRegex r = conformsPred (=~ r)+{-# INLINE matchesRegex #-}+ -- | Check that a value conforms a predicate conformsPred :: Monad m => (a -> Bool) -> e -> ValidationRuleT e m a conformsPred predicate e obj = unless (predicate obj) (checkFailed e) >> return obj@@ -136,7 +153,29 @@        unless res (checkFailed e) >> return obj {-# INLINE conformsPredM #-} --- | Checks that a value matches a regular expression-matchesRegex :: (ConvertibleStrings SBS a, ConvertibleStrings a SBS, Monad m) => Regex -> e -> ValidationRuleT e m a-matchesRegex r = conformsPred (=~ r)-{-# INLINE matchesRegex #-}+-- | Check that an optional value is actually set to 'Just a'+requiredValue :: Monad m => e -> TransValidationRuleT e m (Maybe a) a+requiredValue = conformsPredTrans id+{-# INLINE requiredValue #-}++-- | Check that a list is not empty+nonEmptyList :: Monad m => e -> TransValidationRuleT e m [a] (NEL.NonEmpty a)+nonEmptyList = conformsPredTrans NEL.nonEmpty+{-# INLINE nonEmptyList #-}++-- | Do some check returning 'Nothing' if the value is invalid and 'Just a' otherwise.+conformsPredTrans :: Monad m => (a -> Maybe b) -> e -> TransValidationRuleT e m a b+conformsPredTrans f e obj =+    case f obj of+      Nothing -> checkFailed e+      Just val -> return val+{-# INLINE conformsPredTrans #-}++-- | Do some check returning 'Nothing' if the value is invalid and 'Just a' otherwise.+conformsPredTransM :: Monad m => (a -> m (Maybe b)) -> e -> TransValidationRuleT e m a b+conformsPredTransM f e obj =+    do res <- lift $ f obj+       case res of+         Nothing -> checkFailed e+         Just val -> return val+{-# INLINE conformsPredTransM #-}
validate-input.cabal view
@@ -1,5 +1,5 @@ name:                validate-input-version:             0.3.0.0+version:             0.4.0.0 synopsis:            Input validation combinator library description:         A small Haskell combinator library that provides a simple way of                      validating user provided data structures.@@ -32,6 +32,7 @@                        mtl >=2.1,                        pcre-heavy >=1.0,                        string-conversions >=0.4,+                       semigroups >=0.16,                        text >=1.2   hs-source-dirs:      src   default-language:    Haskell2010