module Cardano.Api.Governance.Metadata.Parsers (textWithMaxLength) where

import           Data.Aeson.Types (Parser, Value, parseJSON)
import           Data.Text (Text)
import qualified Data.Text as T

-- | Parser for 'Text' that validates that the number of characters is
-- under a given maximum. The 'String' parameter is meant to be the name
-- of the field in order to be able to give context in case of error.
textWithMaxLength :: String -> Int -> Value -> Parser Text
textWithMaxLength :: [Char] -> Int -> Value -> Parser Text
textWithMaxLength [Char]
fieldName Int
maxLen Value
value = do
  Text
txt <- Value -> Parser Text
forall a. FromJSON a => Value -> Parser a
parseJSON Value
value
  if Text -> Int
T.length Text
txt Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
maxLen
    then Text -> Parser Text
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
txt
    else
      [Char] -> Parser Text
forall a. [Char] -> Parser a
forall (m :: * -> *) a. MonadFail m => [Char] -> m a
fail ([Char] -> Parser Text) -> [Char] -> Parser Text
forall a b. (a -> b) -> a -> b
$
        [Char]
"key \""
          [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
fieldName
          [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\" exceeds maximum length of "
          [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
maxLen
          [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" characters. Got length: "
          [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show (Text -> Int
T.length Text
txt)