11module Data.HexString ( HexString
22 , hexString
3+ , hexString'
34 , fromBinary
5+ , fromBinary'
46 , toBinary
57 , fromBytes
8+ , fromBytes'
69 , toBytes
710 , toText ) where
811
@@ -27,33 +30,51 @@ data HexString =
2730 deriving ( Show , Eq , Ord )
2831
2932instance FromJSON HexString where
30- parseJSON = withText " HexString" $ pure . hexString . TE. encodeUtf8
33+ parseJSON = withText " HexString" $ toParser . TE. encodeUtf8
34+ where
35+ toParser input = case hexString' input of
36+ (Just value) -> pure value
37+ Nothing -> fail (" Not a valid hex string: " ++ show input)
3138
3239instance ToJSON HexString where
3340 toJSON = String . toText
3441
3542-- | Smart constructor which validates that all the text are actually
3643-- hexadecimal characters.
37- hexString :: BS. ByteString -> HexString
38- hexString bs =
44+ hexString' :: BS. ByteString -> Maybe HexString
45+ hexString' bs =
3946 let isValidHex :: Word8 -> Bool
4047 isValidHex c
4148 | (48 <= c) && (c < 58 ) = True
4249 | (97 <= c) && (c < 103 ) = True
4350 | otherwise = False
44-
4551 in if BS. all isValidHex bs
46- then HexString bs
47- else error (" Not a valid hex string: " ++ show bs)
52+ then Just (HexString bs)
53+ else Nothing
54+
55+ hexString :: BS. ByteString -> HexString
56+ hexString bs = case hexString' bs of
57+ Just hex -> hex
58+ Nothing -> error (" Not a valid hex string: " ++ show bs)
59+
60+ -- | Converts a 'B.Binary' to a 'Maybe HexString' value
61+ fromBinary' :: B. Binary a => a -> Maybe HexString
62+ fromBinary' = hexString' . BS16. encode . BSL. toStrict . B. encode
4863
4964-- | Converts a 'B.Binary' to a 'HexString' value
50- fromBinary :: B. Binary a => a -> HexString
65+ fromBinary :: B. Binary a => a -> HexString
5166fromBinary = hexString . BS16. encode . BSL. toStrict . B. encode
5267
5368-- | Converts a 'HexString' to a 'B.Binary' value
5469toBinary :: B. Binary a => HexString -> a
5570toBinary (HexString bs) = B. decode . BSL. fromStrict . fst . BS16. decode $ bs
5671
72+ -- | Reads a 'BS.ByteString' as raw bytes and converts to hex representation. We
73+ -- cannot use the instance Binary of 'BS.ByteString' because it provides
74+ -- a leading length, which is not what we want when dealing with raw bytes.
75+ fromBytes' :: BS. ByteString -> Maybe HexString
76+ fromBytes' = hexString' . BS16. encode
77+
5778-- | Reads a 'BS.ByteString' as raw bytes and converts to hex representation. We
5879-- cannot use the instance Binary of 'BS.ByteString' because it provides
5980-- a leading length, which is not what we want when dealing with raw bytes.
0 commit comments