packages feed

mldsa-0.1.0.0: tests/Util.hs

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

(.::?) :: Object -> Key -> Parser (Maybe ByteString)
o .::? name = (o .:? name) >>= opt fromBase16

opt :: Monad m => (a -> m b) -> Maybe a -> m (Maybe b)
opt f = maybe (return Nothing) (fmap Just . f)

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"