base16 0.2.0.1 → 0.2.1.0
raw patch · 5 files changed
+258/−10 lines, 5 filesdep +text-shortPVP ok
version bump matches the API change (PVP)
Dependencies added: text-short
API changes (from Hackage documentation)
+ Data.ByteString.Short.Base16: decodeBase16 :: ShortByteString -> Either Text ShortByteString
+ Data.ByteString.Short.Base16: decodeBase16Lenient :: ShortByteString -> ShortByteString
+ Data.ByteString.Short.Base16: encodeBase16 :: ShortByteString -> Text
+ Data.ByteString.Short.Base16: encodeBase16' :: ShortByteString -> ShortByteString
+ Data.ByteString.Short.Base16: isBase16 :: ShortByteString -> Bool
+ Data.ByteString.Short.Base16: isValidBase16 :: ShortByteString -> Bool
+ Data.Text.Short.Encoding.Base16: decodeBase16 :: ShortText -> Either Text ShortText
+ Data.Text.Short.Encoding.Base16: decodeBase16Lenient :: ShortText -> ShortText
+ Data.Text.Short.Encoding.Base16: decodeBase16With :: (ShortByteString -> Either err ShortText) -> ShortText -> Either (Base16Error err) ShortText
+ Data.Text.Short.Encoding.Base16: encodeBase16 :: ShortText -> ShortText
+ Data.Text.Short.Encoding.Base16: isBase16 :: ShortText -> Bool
+ Data.Text.Short.Encoding.Base16: isValidBase16 :: ShortText -> Bool
Files
- README.md +14/−8
- base16.cabal +4/−1
- src/Data/ByteString/Lazy/Base16.hs +2/−1
- src/Data/ByteString/Short/Base16.hs +110/−0
- src/Data/Text/Short/Encoding/Base16.hs +128/−0
README.md view
@@ -3,19 +3,25 @@ [](https://travis-ci.com/emilypi/base16) [](https://hackage.haskell.org/package/base16) -Padded and unpadded base16 and base16hex encoding and decoding for `Text` and `ByteString` values.+RFC 4648-compliant Base16 encoding and decoding. For the companion optics and pattern synonyms, see [base16-lens](https://hackage.haskell.org/package/base16-lens). - ### Summary -What does this library provide? Here is the summary:+The following types are supported for Hex alphabet codecs: -- *Great* encoding performance compared to existing libraries (e.g. `memory`, `base16-bytestring`)-- Better decoding performance compared to existing libraries.-- Support for `Text` encodings and decodings-- Optics for handling more complex structures with Base16 representations via the `base16-lens` package-- Checks for both valid Base16 and correct Base16 and Base16hex encodings+- `Data.ByteString`+- `Data.ByteString.Lazy`+- `Data.ByteString.Short`+- `Data.Text`+- `Data.Text.Lazy`+- `Data.Text.Short`++Additionally this library has++- Much better performance than `base16-bytestring` for encode and decode, with a more conventional api.+- Optics for handling more complex structures with Base64 representations via the `base16-lens` package+- Checks for both validity and correctness of Base16 encodings. There are no dependencies aside from those bundled with GHC.
base16.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: base16-version: 0.2.0.1+version: 0.2.1.0 synopsis: RFC 4648-compliant Base16 encodings/decodings description: RFC 4648-compliant Base16 encodings and decodings.@@ -30,9 +30,11 @@ exposed-modules: Data.ByteString.Base16 Data.ByteString.Lazy.Base16+ Data.ByteString.Short.Base16 Data.Text.Encoding.Base16 Data.Text.Encoding.Base16.Error Data.Text.Lazy.Encoding.Base16+ Data.Text.Short.Encoding.Base16 other-modules: Data.ByteString.Base16.Internal.Head@@ -44,6 +46,7 @@ , bytestring ^>=0.10 , primitive , text ^>=1.2+ , text-short ^>=0.1 hs-source-dirs: src default-language: Haskell2010
src/Data/ByteString/Lazy/Base16.hs view
@@ -22,6 +22,7 @@ ) where + import Prelude hiding (all, elem) import qualified Data.ByteString as B@@ -30,8 +31,8 @@ import qualified Data.ByteString.Base16.Internal.Head as B16 import Data.ByteString.Base16.Internal.Utils (reChunk) import Data.Either-import qualified Data.Text as T import Data.Text.Lazy (Text)+import qualified Data.Text as T import qualified Data.Text.Lazy.Encoding as TL
+ src/Data/ByteString/Short/Base16.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE OverloadedStrings #-}+-- |+-- Module : Data.ByteString.Short.Base16+-- Copyright : (c) 2020 Emily Pillmore+-- License : BSD-style+--+-- Maintainer : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability : Experimental+-- Portability : portable+--+-- This module contains the combinators implementing the+-- RFC 4648 specification for the Base16 encoding including+-- unpadded and lenient variants for bytestrings+--+module Data.ByteString.Short.Base16+( encodeBase16+, encodeBase16'+, decodeBase16+, decodeBase16Lenient+, isBase16+, isValidBase16+) where+++import Prelude hiding (all, elem)++import Data.ByteString.Short (ShortByteString, toShort, fromShort)+import qualified Data.ByteString.Base16 as B16+import Data.Text (Text)+++-- | Encode a 'ShortByteString' value as Base16 'Text' with padding.+--+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>+--+encodeBase16 :: ShortByteString -> Text+encodeBase16 = B16.encodeBase16 . fromShort+{-# INLINE encodeBase16 #-}++-- | Encode a 'ShortByteString' value as a Base16 'ShortByteString' value with padding.+--+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>+--+encodeBase16' :: ShortByteString -> ShortByteString+encodeBase16' = toShort . B16.encodeBase16' . fromShort+{-# INLINE encodeBase16' #-}++-- | Decode a Base16-encoded 'ShortByteString' value.+--+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>+--+decodeBase16 :: ShortByteString -> Either Text ShortByteString+decodeBase16 = fmap toShort . B16.decodeBase16 . fromShort+{-# INLINE decodeBase16 #-}++-- | Decode a Base16-encoded 'ShortByteString' value leniently, using a+-- strategy that never fails+--+-- N.B.: this is not RFC 4648-compliant+--+decodeBase16Lenient :: ShortByteString -> ShortByteString+decodeBase16Lenient = toShort . B16.decodeBase16Lenient . fromShort+{-# INLINE decodeBase16Lenient #-}++-- | Tell whether a 'ShortByteString' value is base16 encoded.+--+-- Examples:+--+-- This example will fail. It conforms to the alphabet, but+-- is not valid because it has an incorrect (odd) length.+--+-- >>> isBase16 "666f6"+-- False+--+-- This example will succeed because it satisfies the alphabet+-- and is considered "valid" (i.e. of the correct size and shape).+--+-- >>> isBase16 "666f"+-- True+--+isBase16 :: ShortByteString -> Bool+isBase16 = B16.isBase16 . fromShort+{-# INLINE isBase16 #-}++-- | Tell whether a 'ShortByteString' value is a valid Base16 format.+--+-- This will not tell you whether or not this is a correct Base16 representation,+-- only that it conforms to the correct alphabet. To check whether it is a true+-- Base16 encoded 'ShortByteString' value, use 'isBase16'.+--+-- Examples:+--+-- This example will fail because it does not conform to the Hex+-- alphabet.+--+-- >>> isValidBase16 "666f+/6"+-- False+--+-- This example will succeed because it satisfies the alphabet+-- and is considered "valid" (i.e. of the correct size and shape), but+-- is not correct base16 because it is the wrong shape.+--+-- >>> isValidBase16 "666f6"+-- True+--+isValidBase16 :: ShortByteString -> Bool+isValidBase16 = B16.isValidBase16 . fromShort+{-# INLINE isValidBase16 #-}
+ src/Data/Text/Short/Encoding/Base16.hs view
@@ -0,0 +1,128 @@+-- |+-- Module : Data.Text.Short.Encoding.Base16+-- Copyright : (c) 2019 Emily Pillmore+-- License : BSD-style+--+-- Maintainer : Emily Pillmore <emilypi@cohomolo.gy>+-- Stability : Experimental+-- Portability : portable+--+-- This module contains the combinators implementing the+-- RFC 4648 specification for the Base16 encoding including+-- unpadded and lenient variants for text values+--+module Data.Text.Short.Encoding.Base16+( encodeBase16+, decodeBase16+, decodeBase16With+, decodeBase16Lenient+, isBase16+, isValidBase16+) where+++import Data.Bifunctor (first)+import qualified Data.ByteString.Base16 as B16+import Data.ByteString.Short (ShortByteString)+import qualified Data.ByteString.Short.Base16 as BS16+import Data.Text (Text)+import qualified Data.Text.Encoding.Base16 as B16T+import Data.Text.Encoding.Base16.Error+import Data.Text.Short+import Data.Text.Short.Unsafe+++-- | Encode a 'ShortText' value in Base16 with padding.+--+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>+--+encodeBase16 :: ShortText -> ShortText+encodeBase16 = fromByteStringUnsafe . B16.encodeBase16' . toByteString+{-# INLINE encodeBase16 #-}++-- | Decode a Base16-encoded lazy 'ShortText' value.+--+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>+--+decodeBase16 :: ShortText -> Either Text ShortText+decodeBase16 = fmap fromText . B16T.decodeBase16 . toText+{-# INLINE decodeBase16 #-}++-- | Attempt to decode a lazy 'ShortText' value as Base16, converting from+-- 'ByteString' to 'ShortText' according to some encoding function. In practice,+-- This is something like 'decodeUtf8'', which may produce an error.+--+-- See: <https://tools.ietf.org/html/rfc4648#section-8 RFC-4648 section 8>+--+-- Example:+--+-- @+-- 'decodeBase16With' 'T.decodeUtf8''+-- :: 'ShortText' -> 'Either' ('Base16Error' 'UnicodeException') 'ShortText'+-- @+--+decodeBase16With+ :: (ShortByteString -> Either err ShortText)+ -- ^ convert a bytestring to text (e.g. 'T.decodeUtf8'')+ -> ShortText+ -- ^ Input text to decode+ -> Either (Base16Error err) ShortText+decodeBase16With f t = case BS16.decodeBase16 (toShortByteString t) of+ Left de -> Left $ DecodeError de+ Right a -> first ConversionError (f a)+{-# INLINE decodeBase16With #-}++-- | Decode a Base16-encoded lazy 'ShortText' value leniently, using a+-- strategy that never fails, catching unicode exceptions raised in the+-- process of converting to text values.+--+-- N.B.: this is not RFC 4648-compliant.+--+decodeBase16Lenient :: ShortText -> ShortText+decodeBase16Lenient = fromText . B16T.decodeBase16Lenient . toText+{-# INLINE decodeBase16Lenient #-}++-- | Tell whether a 'ShortText' value is Base16-encoded.+--+-- Examples:+--+-- This example will fail. It conforms to the alphabet, but+-- is not valid because it has an incorrect (odd) length.+--+-- >>> isBase16 "666f6"+-- False+--+-- This example will succeed because it satisfies the alphabet+-- and is considered "valid" (i.e. of the correct size and shape).+--+-- >>> isBase16 "666f"+-- True+--+isBase16 :: ShortText -> Bool+isBase16 = B16.isBase16 . toByteString+{-# INLINE isBase16 #-}++-- | Tell whether a 'ShortText' value is a valid Base16 format.+--+-- This will not tell you whether or not this is a correct Base16 representation,+-- only that it conforms to the correct shape. To check whether it is a true+-- Base16 encoded 'ShortText' value, use 'isBase16'.+--+-- Examples:+--+-- This example will fail because it does not conform to the Hex+-- alphabet.+--+-- >>> isValidBase16 "666f+/6"+-- False+--+-- This example will succeed because it satisfies the alphabet+-- and is considered "valid" (i.e. of the correct size and shape), but+-- is not correct base16 because it is the wrong shape.+--+-- >>> isValidBase16 "666f6"+-- True+--+isValidBase16 :: ShortText -> Bool+isValidBase16 = B16.isValidBase16 . toByteString+{-# INLINE isValidBase16 #-}