{-# LANGUAGE NoImplicitPrelude #-} module DSV.DelimiterSplice ( charDelimiter ) where import DSV.DelimiterType import DSV.Prelude import Data.Word (Word8) import qualified Data.Char import Language.Haskell.TH.Syntax (Q, Exp, lift) -- | A Template Haskell expression of type 'Delimiter'. Rejects code points above @0xff@. -- -- === Example -- -- 'comma' is defined as: -- -- @$('charDelimiter' ',')@ -- -- This could be written equivalently as: -- -- @'Delimiter' ('fromIntegral' ('Data.Char.ord' ','))@ -- -- but the former includes a compile-time check to ensure that the character @','@ is representable by a single byte (and thus that 'fromIntegral' does not overflow). charDelimiter :: Char -> Q Exp charDelimiter c = do let n = Data.Char.ord c :: Int if n > (fromIntegral (maxBound :: Word8) :: Int) then fail ("Character " ++ [c] ++ " is outside the range of Word8.") else lift (Delimiter (fromIntegral n :: Word8))