{-# LANGUAGE CPP #-} module Util ( (.::) ) where import Data.Aeson import Data.Aeson.Types import Data.Char import Data.ByteString (ByteString, cons, empty) import Data.Text (Text, uncons) #if !(MIN_VERSION_aeson(2,0,0)) type Key = Text #endif (.::) :: Object -> Key -> Parser ByteString o .:: name = (o .: name) >>= fromBase16 fromBase16 :: Text -> Parser ByteString fromBase16 t = case uncons t of Nothing -> return empty Just (a, as) -> case uncons as of Nothing -> fail "incomplete Base16" Just (b, bs) -> do ia <- fromHexDigit a ib <- fromHexDigit b let w = fromIntegral (ia * 16 + ib) cons w <$> fromBase16 bs fromHexDigit :: Char -> Parser Int fromHexDigit c | isHexDigit c = return (digitToInt c) | otherwise = fail "invalid hex digit"