burrito-1.0.2.0: src/lib/Burrito/Type/VarChar.hs
{-# LANGUAGE DeriveLift #-}
-- | Warning: This module is not considered part of Burrito's public API. As
-- such, it may change at any time. Use it with caution!.
module Burrito.Type.VarChar
( VarChar(..)
, makeEncoded
, makeUnencoded
, isVarchar
)
where
import qualified Data.Char as Char
import qualified Language.Haskell.TH.Syntax as TH
-- | Represents a single logical character in a variable name.
data VarChar
= Encoded Char Char
-- ^ A percent encoded triple. Note that this represents three literal
-- characters in the input, even though logically we always treat it as one
-- character. The two arguments are the high and the low hexadecimal digits,
-- respectively. This representation intentially keeps track of their case,
-- so as to avoid confusing values like @%aa@ and @%AA@. You should use
-- @makeEncoded@ to build these values.
| Unencoded Char
-- ^ A literal unencoded character. You should use @makeUnencoded@ to build
-- these values.
deriving (Eq, TH.Lift, Show)
-- | Makes sure that both characters are valid hexadecimal digits. If they are,
-- returns an @Encoded@ character. Otherwise returns nothing.
makeEncoded :: Char -> Char -> Maybe VarChar
makeEncoded hi lo = if Char.isHexDigit hi && Char.isHexDigit lo
then Just $ Encoded hi lo
else Nothing
-- | Makes sure that the character passes the @isVarchar@ predicate. If it
-- does, returns an @Unencoded@ character. Otherwise returns nothing.
makeUnencoded :: Char -> Maybe VarChar
makeUnencoded char = if isVarchar char then Just $ Unencoded char else Nothing
-- | Returns true if the given character is in the @varchar@ range defined by
-- section 2.3 of the RFC. Note that this does not include the @pct-encoded@
-- part of the grammar because that requires multiple characters to match.
isVarchar :: Char -> Bool
isVarchar x = case x of
'_' -> True
_ -> isAlpha x || Char.isDigit x
-- | Returns true if the given character is in the @ALPHA@ range defined by
-- section 1.5 of the RFC.
isAlpha :: Char -> Bool
isAlpha x = Char.isAsciiUpper x || Char.isAsciiLower x