module Attoparsec.Time.Validation where

import Attoparsec.Time.Prelude


data Validator a =
  Validator String (a -> Bool)

run :: Show a => Validator a -> b -> (String -> b) -> a -> b
run :: Validator a -> b -> (String -> b) -> a -> b
run (Validator String
name a -> Bool
predicate) b
onNoError String -> b
onError a
input =
  if a -> Bool
predicate a
input
    then
      b
onNoError
    else
      String -> b
onError (String -> b) -> String -> b
forall a b. (a -> b) -> a -> b
$
      String -> ShowS
showString String
"Validator " ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
      String -> ShowS
forall a. Show a => a -> ShowS
shows String
name ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
      String -> ShowS
showString String
" failed on the following input: " ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
      a -> String
forall a. Show a => a -> String
show a
input

month :: (Num a, Ord a) => Validator a
month :: Validator a
month =
  String -> (a -> Bool) -> Validator a
forall a. String -> (a -> Bool) -> Validator a
Validator String
"month" ((Bool -> Bool -> Bool) -> (a -> Bool) -> (a -> Bool) -> a -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
1) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
12))

monthDay :: (Num a, Ord a) => Validator a
monthDay :: Validator a
monthDay =
  String -> (a -> Bool) -> Validator a
forall a. String -> (a -> Bool) -> Validator a
Validator String
"monthDay" ((Bool -> Bool -> Bool) -> (a -> Bool) -> (a -> Bool) -> a -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
1) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
31))

weekDay :: (Num a, Ord a) => Validator a
weekDay :: Validator a
weekDay =
  String -> (a -> Bool) -> Validator a
forall a. String -> (a -> Bool) -> Validator a
Validator String
"weekDay" ((Bool -> Bool -> Bool) -> (a -> Bool) -> (a -> Bool) -> a -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
1) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
7))

hour :: (Num a, Ord a) => Validator a
hour :: Validator a
hour =
  String -> (a -> Bool) -> Validator a
forall a. String -> (a -> Bool) -> Validator a
Validator String
"hour" ((Bool -> Bool -> Bool) -> (a -> Bool) -> (a -> Bool) -> a -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
0) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
24))

minute :: (Num a, Ord a) => Validator a
minute :: Validator a
minute =
  String -> (a -> Bool) -> Validator a
forall a. String -> (a -> Bool) -> Validator a
Validator String
"minute" ((Bool -> Bool -> Bool) -> (a -> Bool) -> (a -> Bool) -> a -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
0) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
60))

second :: (Num a, Ord a) => Validator a
second :: Validator a
second =
  String -> (a -> Bool) -> Validator a
forall a. String -> (a -> Bool) -> Validator a
Validator String
"second" ((Bool -> Bool -> Bool) -> (a -> Bool) -> (a -> Bool) -> a -> Bool
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
>= a
0) (a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
60))