module ToolShed.SelfValidate(
SelfValidator(..),
getFirstError,
extractErrors
) where
import qualified Data.Array.IArray
import qualified Data.Map
import qualified Data.Set
class SelfValidator v where
getErrors :: v -> [String]
isValid :: v -> Bool
isValid = null . getErrors
instance (SelfValidator v) => SelfValidator (Maybe v) where
getErrors (Just v) = getErrors v
getErrors _ = []
instance (SelfValidator a, SelfValidator b) => SelfValidator (a, b) where
getErrors (x, y) = getErrors x ++ getErrors y
instance (SelfValidator a, SelfValidator b, SelfValidator c) => SelfValidator (a, b, c) where
getErrors (x, y, z) = getErrors x ++ getErrors y ++ getErrors z
instance SelfValidator v => SelfValidator [v] where
getErrors = concatMap getErrors
instance SelfValidator v => SelfValidator (Data.Set.Set v) where
getErrors = Data.Set.foldr ((++) . getErrors) []
instance SelfValidator v => SelfValidator (Data.Map.Map k v) where
getErrors = Data.Map.foldr ((++) . getErrors) []
instance (Data.Array.IArray.Ix index, SelfValidator element) => SelfValidator (Data.Array.IArray.Array index element) where
getErrors = concatMap getErrors . Data.Array.IArray.elems
getFirstError :: SelfValidator v => v -> String
getFirstError selfValidator
| null errors = error "ToolShed.SelfValidate.getFirstError:\tzero errors ?!"
| otherwise = head errors
where
errors = getErrors selfValidator
extractErrors :: [(Bool, String)] -> [String]
extractErrors = map snd . filter fst