{-# 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