ttc-0.1.0.0: examples/Username.hs
------------------------------------------------------------------------------
-- |
-- Module : Username
-- Description : username data type
-- Copyright : Copyright (c) 2019 Travis Cardwell
-- License : MIT
--
-- This module defines a username data type, with 'TTC.Render' and 'TTC.Parse'
-- instances, as an example of TTC usage.
--
-- The constructor for 'Username' is not exported. The 'TTC.Parse' instance
-- serves as a "smart constructor," ensuring that all values are valid.
------------------------------------------------------------------------------
module Username (Username) where
-- https://hackage.haskell.org/package/base
import Control.Monad (unless, when)
import Data.Char (isAsciiLower)
-- https://hackage.haskell.org/package/text
import qualified Data.Text as T
import Data.Text (Text)
-- ttc
import qualified Data.TTC as TTC
------------------------------------------------------------------------------
-- | A 'Username' must consist of 3 to 12 lowercase ASCII letters.
newtype Username = Username Text
deriving (Eq, Ord, Show)
instance TTC.Render Username where
render (Username t) = TTC.convert t
instance TTC.Parse Username where
parse = TTC.asT $ \t -> do
unless (T.all isAsciiLower t) $ Left "username has invalid characters"
let len = T.length t
when (len < 3) $ Left "username has fewer than 3 characters"
when (len > 12) $ Left "username has more than 12 characters"
pure $ Username t