-- |
-- Module      : Util
-- License     : BSD-3-Clause
-- Copyright   : (c) 2025 Olivier Chéron
--
-- Utility to read hexadecimal byte arrays with aeson
--
{-# 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"
