hexstring 0.9.0 → 0.10.0
raw patch · 3 files changed
+59/−51 lines, 3 filesdep +binarydep ~base16-bytestringdep ~bytestringdep ~textPVP ok
version bump matches the API change (PVP)
Dependencies added: binary
Dependency ranges changed: base16-bytestring, bytestring, text
API changes (from Hackage documentation)
- Data.HexString: HexString :: !ByteString -> HexString
- Data.HexString: decodeByteString :: ByteString -> HexString
- Data.HexString: decodeString :: String -> HexString
- Data.HexString: decodeText :: Text -> HexString
- Data.HexString: encodeByteString :: HexString -> ByteString
- Data.HexString: encodeString :: HexString -> String
- Data.HexString: encodeText :: HexString -> Text
- Data.HexString: getBinary :: HexString -> ByteString
- Data.HexString: setBinary :: ByteString -> HexString
+ Data.HexString: asText :: HexString -> Text
+ Data.HexString: fromHex :: Binary a => HexString -> a
+ Data.HexString: hexString :: ByteString -> HexString
+ Data.HexString: toHex :: Binary a => a -> HexString
Files
- hexstring.cabal +6/−4
- src/Data/HexString.hs +38/−35
- test/Data/HexStringSpec.hs +15/−12
hexstring.cabal view
@@ -1,6 +1,6 @@ name: hexstring category: Data -version: 0.9.0 +version: 0.10.0 license: MIT license-file: LICENSE copyright: (c) 2015 Leon Mergen @@ -11,9 +11,8 @@ stability: experimental synopsis: Fast and safe representation of a hex string description: - Provides an interface for representing a HexString. It uses fast conversion - functions to convert to-and-from String or Text formats. Internally, the - HexString is represented by a ByteString. + Provides an interface for converting any object that has a 'Binary' instance + to and from a hexadecimal Text representation. build-type: Simple data-files: LICENSE, README.md @@ -28,6 +27,7 @@ exposed-modules: Data.HexString build-depends: base >= 4.3 && < 5 + , binary , text , bytestring , base16-bytestring @@ -48,6 +48,8 @@ , text , bytestring + , binary + , hexstring source-repository head
src/Data/HexString.hs view
@@ -1,45 +1,48 @@-module Data.HexString where - -import qualified Data.ByteString as BS -import qualified Data.ByteString.Char8 as BS8 -import qualified Data.ByteString.Base16 as BS16 +module Data.HexString ( HexString + , hexString + , toHex + , fromHex + , asText ) where -import qualified Data.Text as T -import qualified Data.Text.Encoding as TE +import Data.Word (Word8) --- | Data type representing a HexString. -data HexString - = HexString !BS.ByteString - deriving ( Show, Eq, Ord ) +import qualified Data.ByteString.Base16 as BS16 (decode, encode) +import qualified Data.ByteString as BS +import qualified Data.ByteString.Lazy as BSL --- | Access to the raw binary data this HexString represents -getBinary :: HexString -> BS.ByteString -getBinary (HexString bs) = bs +import qualified Data.Text as T +import qualified Data.Text.Encoding as TE --- | Create new HexString based on raw binary data -setBinary :: BS.ByteString -> HexString -setBinary = HexString +import qualified Data.Binary as B (Binary, decode, encode) --- | Converts `BS.ByteString` to a `HexString` -decodeByteString :: BS.ByteString -> HexString -decodeByteString = HexString . fst . BS16.decode +-- | Represents a Hex string. Guarantees that all characters it contains +-- are valid hex characters. +data HexString = + HexString BS.ByteString + deriving ( Show, Eq, Ord ) --- | Converts a `T.Text` representation to a `HexString` -decodeText :: T.Text -> HexString -decodeText = decodeByteString . TE.encodeUtf8 +-- | Smart constructor which validates that all the text are actually +-- hexadecimal characters. +hexString :: BS.ByteString -> HexString +hexString bs = + let isValidHex :: Word8 -> Bool + isValidHex c + | (48 <= c) && (c < 58) = True + | (97 <= c) && (c < 103) = True + | otherwise = False --- | Converts a `String` representation to a `HexString` -decodeString :: String -> HexString -decodeString = decodeByteString . BS8.pack + in if BS.all isValidHex bs + then HexString bs + else error ("Not a valid hex string: " ++ show bs) --- | Converts a `HexString` to a `BS.ByteString` -encodeByteString :: HexString -> BS.ByteString -encodeByteString = BS16.encode . getBinary +-- | Converts a 'B.Binary' to a 'HexString' value +toHex :: B.Binary a => a -> HexString +toHex = hexString . BS16.encode . BSL.toStrict . B.encode --- | Converts a `HexString` to a `T.Text` representation -encodeText :: HexString -> T.Text -encodeText = TE.decodeUtf8 . encodeByteString +-- | Converts a 'HexString' to a 'B.Binary' value +fromHex :: B.Binary a => HexString -> a +fromHex (HexString bs) = B.decode . BSL.fromStrict . fst . BS16.decode $ bs --- | Converts a `HexString` to a `String` representation -encodeString :: HexString -> String -encodeString = BS8.unpack . encodeByteString +-- | Access to a 'T.Text' representation of the 'HexString' +asText :: HexString -> T.Text +asText (HexString bs) = TE.decodeUtf8 bs
test/Data/HexStringSpec.hs view
@@ -1,23 +1,26 @@ module Data.HexStringSpec where -import Data.HexString +import Data.HexString ( hexString + , toHex + , fromHex + , asText ) +import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BS8 import qualified Data.Text as T +import qualified Data.Binary as B ( encode ) + import Test.Hspec spec :: Spec spec = do - describe "when decoding hex data" $ do - it "should be able to parse basic hex data" $ do - (getBinary . decodeByteString) (BS8.pack "ffff") `shouldBe` BS8.pack "\255\255" - (getBinary . decodeString) "ffff" `shouldBe` BS8.pack "\255\255" - (getBinary . decodeText) (T.pack "ffff") `shouldBe` BS8.pack "\255\255" + describe "when constructing a hex string" $ do + it "should accept strings that fall within a valid range" $ + hexString (BS8.pack "0123456789abcdef") `shouldBe` hexString (BS8.pack "0123456789abcdef") - it "should be able to recode basic hex data to different formats" $ - let hex = BS8.pack "ffff" - in do - (encodeText . decodeByteString) hex `shouldBe` T.pack "ffff" - (encodeString . decodeByteString) hex `shouldBe` "ffff" - (encodeByteString . decodeByteString) hex `shouldBe` BS8.pack "ffff" + it "should reject strings outside the range" $ do + putStrLn (show (hexString (BS8.pack "/"))) `shouldThrow` anyErrorCall + putStrLn (show (hexString (BS8.pack ":"))) `shouldThrow` anyErrorCall + putStrLn (show (hexString (BS8.pack "`"))) `shouldThrow` anyErrorCall + putStrLn (show (hexString (BS8.pack "g"))) `shouldThrow` anyErrorCall