casa-reoc-0.1.0.0: src/ReOC/Render/Error.hs
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -Wall #-}
{- | The errors of filling in a form, as text: where each is, what is wrong,
and the help text of its field.
>>> import qualified Data.Text.IO as Text
>>> import ReOC.Model
>>> Text.putStrLn (renderPath [StepField ReOCOperator, StepField OperatorFleet, StepIndex 1, StepField OperatedTypeAirframes])
operator › fleet › 2 › airframes
-}
module ReOC.Render.Error (
renderPath,
renderInvalidValue,
renderReOCError,
renderReOCErrors,
) where
import Data.Foldable (toList)
import Data.Text (Text)
import qualified Data.Text as Text
import ReOC.Help (fieldHelp, fieldLabel)
import ReOC.Model
-- | A path, as the labels of its fields, and each index of a list counted from 1.
renderPath :: [Step] -> Text
renderPath =
Text.intercalate " › " . map label
where
label = \case
StepField f -> fieldLabel f
StepIndex i -> Text.pack (show (i + 1))
-- | What is wrong with an invalid value.
renderInvalidValue :: InvalidValue -> Text
renderInvalidValue = \case
InvalidText1 t -> quoted t <> " is blank, or has a character that a document cannot hold"
InvalidFormText t -> quoted t <> " does not fit its box on the form, or has a character that the form cannot show"
InvalidABN t -> quoted t <> " is not an ABN: 11 digits with valid check digits"
InvalidARN t -> quoted t <> " is not an ARN: digits only"
InvalidEmailAddress t -> quoted t <> " is not an email address that fits the form"
InvalidPhoneNumber t -> quoted t <> " is not an Australian phone number"
InvalidPostcode t -> quoted t <> " is not a four-digit postcode"
InvalidPositive n -> number n <> " is not a positive number"
InvalidPercentage n -> number n <> " is not a percentage from 0 to 100"
InvalidGrossWeight n -> number n <> " g is not a gross weight from 1 g to 25 kg"
InvalidReviewMonths n -> number n <> " is not a number of months from 1 to 12"
InvalidPassMark n -> number n <> " is not a pass mark from 70 to 100"
where
quoted t = "“" <> t <> "”"
number = Text.pack . show
-- The help text of the field at the end of a path, if it ends at a field.
helpAt :: [Step] -> Text
helpAt p =
case [f | StepField f <- reverse p] of
f : _ -> " (" <> fieldHelp f <> ")"
[] -> ""
-- | An error: where it is, what is wrong, and the help text of the field.
renderReOCError :: ReOCError -> Text
renderReOCError = \case
ReOCErrorUnfilled (Unfilled p) -> renderPath p <> ": not filled in" <> helpAt p
ReOCErrorInvalid (Invalid p v) -> renderPath p <> ": " <> renderInvalidValue v <> helpAt p
ReOCErrorTooMany (TooMany p most given) ->
renderPath p <> ": " <> Text.pack (show given) <> " given, but it holds at most " <> Text.pack (show most) <> helpAt p
-- | Errors, one to a line.
renderReOCErrors :: (Foldable t) => t ReOCError -> Text
renderReOCErrors =
Text.unlines . map renderReOCError . toList