module Text.Digestive.Result
( Result (..)
, FormId (..)
, FormRange (..)
, incrementFormId
, isInRange
, isSubRange
, retainErrors
, retainChildErrors
) where
import Control.Applicative (Applicative (..))
data Result e ok = Error [(FormRange, e)]
| Ok ok
deriving (Show, Eq)
instance Functor (Result e) where
fmap _ (Error x) = Error x
fmap f (Ok x) = Ok (f x)
instance Monad (Result e) where
return = Ok
Error x >>= _ = Error x
Ok x >>= f = f x
instance Applicative (Result e) where
pure = Ok
Error x <*> Error y = Error $ x ++ y
Error x <*> Ok _ = Error x
Ok _ <*> Error y = Error y
Ok x <*> Ok y = Ok $ x y
data FormId = FormId
{ formPrefix :: String
, formId :: Integer
} deriving (Eq, Ord)
instance Show FormId where
show (FormId p x) = p ++ "-f" ++ show x
data FormRange = FormRange FormId FormId
deriving (Eq, Show)
incrementFormId :: FormId -> FormId
incrementFormId (FormId p x) = FormId p $ x + 1
isInRange :: FormId
-> FormRange
-> Bool
isInRange (FormId _ a) (FormRange b c) = a >= formId b && a < formId c
isSubRange :: FormRange
-> FormRange
-> Bool
isSubRange (FormRange a b) (FormRange c d) = formId a >= formId c
&& formId b <= formId d
retainErrors :: FormRange -> [(FormRange, e)] -> [e]
retainErrors range = map snd . filter ((== range) . fst)
retainChildErrors :: FormRange -> [(FormRange, e)] -> [e]
retainChildErrors range = map snd . filter ((`isSubRange` range) . fst)