packages feed

base64 0.1.0.0 → 0.2.0.0

raw patch · 6 files changed

+23/−362 lines, 6 filesdep −lensdep ~bytestringdep ~deepseqdep ~textPVP ok

version bump matches the API change (PVP)

Dependencies removed: lens

Dependency ranges changed: bytestring, deepseq, text

API changes (from Hackage documentation)

- Data.ByteString.Base64.Lens: _Base64 :: Prism' ByteString ByteString
- Data.ByteString.Base64.Lens: _Base64Unpadded :: Prism' ByteString ByteString
- Data.ByteString.Base64.Lens: _Base64Url :: Prism' ByteString ByteString
- Data.ByteString.Base64.Lens: _Base64UrlUnpadded :: Prism' ByteString ByteString
- Data.ByteString.Base64.Lens: pattern Base64 :: ByteString -> ByteString
- Data.ByteString.Base64.Lens: pattern Base64Unpadded :: ByteString -> ByteString
- Data.ByteString.Base64.Lens: pattern Base64Url :: ByteString -> ByteString
- Data.ByteString.Base64.Lens: pattern Base64UrlUnpadded :: ByteString -> ByteString
- Data.Text.Encoding.Base64.Lens: _Base64 :: Prism' Text Text
- Data.Text.Encoding.Base64.Lens: _Base64Unpadded :: Prism' Text Text
- Data.Text.Encoding.Base64.Lens: _Base64Url :: Prism' Text Text
- Data.Text.Encoding.Base64.Lens: _Base64UrlUnpadded :: Prism' Text Text
- Data.Text.Encoding.Base64.Lens: pattern Base64 :: Text -> Text
- Data.Text.Encoding.Base64.Lens: pattern Base64Unpadded :: Text -> Text
- Data.Text.Encoding.Base64.Lens: pattern Base64Url :: Text -> Text
- Data.Text.Encoding.Base64.Lens: pattern Base64UrlUnpadded :: Text -> Text

Files

CHANGELOG.md view
@@ -1,5 +1,17 @@ # Revision history for base64 -## 0.1.0.0 -- YYYY-mm-dd+## 0.2.0.0 -- 2020-01-05 +* After a discussion with phadej, we're doing away with the flags, and splitting the optics out into their own separate library+* Removed unnecessary inline pragmas++## 0.1.0.0 -- 2020-01-05++* Do away with the typeclasses, and just provide prisms + synonyms+* Continued performance improvements to decoding+* Corrected benchmarks++## 0.0.1.0 -- 2020-01-03+ * First version. Released on an unsuspecting world.+* Preliminary release
README.md view
@@ -13,79 +13,14 @@ - Better performance over existing Base64 libraries (2x and 3x for most use-cases - see [PERFORMANCE.md](benchmarks/PERFORMANCE.md)) - Support for unpadded Base64 and Base64-url - Support for `Text` encodings and decodings-- Optics for handling more complex structures with Base64 representations+- Optics for handling more complex structures with Base64 representations via the `base64-lens` package +There are no dependencies aside from `base`: +![base64 dependencies](https://i.imgur.com/qynI5HM.png)+ ### Motivation  Haskell has two main libraries for Base64: `memory`, and `base64-bytestring`. -Of these, `memory` is geared towards integration with other memory primitives in the library, without much of an eye towards performance, while `base64-bytestring` is built to exclusively address `ByteString` encoding and decoding, and is very performant. Many great strides have been made in the realm of Base64 performance and vectorization just in the past 5 years, which this library attempts to capture. Additionally, we attempt to fix percieved shortcomings with both APIs in the support of unpadded Base64 and Base64-url support (which `memory` provides, but not `base64-bytestring`), as well as supporting `Text` values (neither libraries provide), supplying some optics for composing structures with Base64-encodable/decodable focii (neither libraries provide), and convenient pattern synonyms (no library to date does this).--### Patterns--The pattern synonyms provided in this library are:--```haskell-pattern Base64 :: ByteString -> ByteString-pattern Base64Url :: ByteString -> ByteString-pattern Base64Unpadded :: ByteString -> ByteString-pattern Base64UrlUnpadded :: ByteString -> ByteString---- and--pattern Base64 :: Text -> Text-pattern Base64Url :: Text -> Text-pattern Base64Unpadded :: Text -> Text-pattern Base64UrlUnpadded :: Text -> Text-```--These provide a convenient high level interface for passing Base64 encoded values.---### Optics--`Prism`s for encoding and decoding `Text` and `ByteString` values are given as part of the library:---```haskell-_Base64 :: Prism' ByteString ByteString-_Base64Url :: Prism' ByteString ByteString-_Base64Unpadded :: Prism' ByteString ByteString-_Base64UrlUnpadded :: Prism' ByteString ByteString---- and--_Base64 :: Prism' Text Text-_Base64Url :: Prism' Text Text-_Base64Unpadded :: Prism' Text Text-_Base64UrlUnpadded :: Prism' Text Text--```--If a particular structure has a `Lens` into some `Text` or `ByteString` value they might want to encode (or decode), then composing such a `Lens` with these `Prisms` yields an affine `Traversal`, resulting in a structure which has the focus of its `Lens` encoded as or decoded from Base64(-url). All one needs to do is compose their optics:--```haskell--data MyStruct = MyStruct-  { _a :: Int-  , _b :: Text-  } deriving Show--b :: Lens' MyStruct Text-b = lens _b (\t b_ -> t { _b = b_ })--myB64Struct :: Traversal' s Text-myB64Struct = b . _Base64---- >>> MyStruct 3 "U3Vu" ^? b . _Base64--- MyStruct {_a = 3, _b = "Sun"}--bRe :: Review MyStruct Text-bRe = unto (\b -> MyStruct 0 b)---- >>> bRe . _Base64 # "Sun"--- MyStruct {_a = 0, _b = "UV3u"}-```--The data of a `Prism` naturally conforms to this "encoding/decoding" dichotomy, where the `Review`, or "builder" half of the `Prism` of type `b -> t` is an encoding, and the "Matcher" half of the prism, of type `s -> Either t a`, represents a decoding of a similar structure. Hence, `Prism` is the most appropriate structure.+Of these, `memory` is geared towards integration with other memory primitives in the library, without much of an eye towards performance, while `base64-bytestring` is built to exclusively address `ByteString` encoding and decoding, and is very performant. Many great strides have been made in the realm of Base64 performance and vectorization just in the past 5 years, which this library attempts to capture. Additionally, we attempt to fix percieved shortcomings with both APIs in the support of unpadded Base64 and Base64-url support (which `memory` provides, but not `base64-bytestring`), as well as supporting `Text` values (neither libraries provide).
base64.cabal view
@@ -1,7 +1,7 @@ cabal-version:       2.4  name:                base64-version:             0.1.0.0+version:             0.2.0.0 synopsis:            RFC 4648-compliant padded and unpadded base64 and base64url encodings description:   RFC 4648-compliant padded and unpadded base64 and base64url encoding and decoding.@@ -24,18 +24,6 @@   type:     git   location: https://github.com/emilypi/base64.git --flag optics-  description: Enable optics for base64-encoding text and bytestrings-  manual: True-  default: True--flag perf-flags-  description: Performance tuning flags and information-  manual: True-  default: False-- library   exposed-modules:     Data.ByteString.Base64                      , Data.ByteString.Base64.URL@@ -45,24 +33,14 @@    other-modules:       Data.ByteString.Base64.Internal -  build-depends:       base       >=4.10 && <5-                     , bytestring-                     , deepseq-                     , text+  build-depends:       base        >=4.10 && <5+                     , bytestring ^>=0.10+                     , deepseq    ^>=1.4+                     , text       ^>=1.2    hs-source-dirs:      src   default-language:    Haskell2010   ghc-options:         -Wall--  if flag(optics)-    exposed-modules:   Data.ByteString.Base64.Lens-                     , Data.Text.Encoding.Base64.Lens-    build-depends:     lens ^>= 4.18--  if flag(perf-flags)-    ghc-options:       -ddump-simpl-                       -ddump-to-file-                       -ddump-stranal   test-suite tasty
src/Data/ByteString/Base64/Internal.hs view
@@ -92,7 +92,6 @@             , !j <- [0..63]             ]       in EncodingTable (Ptr alphabet) (writeNPlainForeignPtrBytes 8192 bs)-{-# INLINE packTable #-}  base64UrlTable :: EncodingTable base64UrlTable = packTable "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"#@@ -134,11 +133,9 @@ encodeBase64_' !padded (Ptr !alpha) !etable !sptr !dptr !end = go sptr dptr   where     ix (W8# i) = W8# (indexWord8OffAddr# alpha (word2Int# i))-    {-# INLINE ix #-}      w32 :: Word8 -> Word32     w32 = fromIntegral-    {-# INLINE w32 #-}      go !src !dst       | plusPtr src 2 >= end = finalize src (castPtr dst)@@ -280,17 +277,14 @@ decodeBase64_' !dtable !sptr !dptr !end !dfp = go dptr sptr 0   where     err = return . Left . T.pack-    {-# INLINE err #-}      finalize !n = return (Right (PS dfp 0 n))-    {-# INLINE finalize #-}      look :: Ptr Word8 -> IO Word32     look p = do       !i <- peekByteOff @Word8 p 0       !v <- peekByteOff @Word8 dtable (fromIntegral i)       return (fromIntegral v)-    {-# INLINE look #-}      go !dst !src !n       | src >= end = return (Right (PS dfp 0 n))
− src/Data/ByteString/Base64/Lens.hs
@@ -1,129 +0,0 @@-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE ViewPatterns #-}--- |--- Module       : Data.Text.Encoding.Base64.Lens--- Copyright 	: (c) 2019 Emily Pillmore--- License	: BSD-style------ Maintainer	: Emily Pillmore <emilypi@cohomolo.gy>--- Stability	: Experimental--- Portability	: non-portable------ This module contains 'Control.Lens.Type.Prism's Base64-encoding and--- decoding 'ByteString' values.----module Data.ByteString.Base64.Lens-( -- * Prisms-  _Base64-, _Base64Url-, _Base64Unpadded-, _Base64UrlUnpadded-  -- * Patterns-, pattern Base64-, pattern Base64Url-, pattern Base64Unpadded-, pattern Base64UrlUnpadded-) where---import Control.Lens--import Data.ByteString (ByteString)-import qualified Data.ByteString.Base64 as B64-import qualified Data.ByteString.Base64.URL as B64U----- -------------------------------------------------------------------------- ----- Optics---- | A 'Control.Lens.Type.Prism' into the Base64 encoding of a 'ByteString' value------ >>> _Base64 # "Sun"--- "UV3u"------ >>> "UV3u" ^? _Base64--- Just "Sun"----_Base64 :: Prism' ByteString ByteString-_Base64 = prism' B64.encodeBase64 $ \s -> case B64.decodeBase64 s of-    Left _ -> Nothing-    Right a -> Just a-{-# INLINE _Base64 #-}---- | A 'Control.Lens.Type.Prism' into the Base64-url encoding of a 'ByteString' value------ >>> _Base64Url # "Sun"--- "UV3u"------ >>> "PDw_Pz8-Pg==" ^? _Base64Url--- Just "<<???>>"----_Base64Url :: Prism' ByteString ByteString-_Base64Url = prism' B64U.encodeBase64 $ \s -> case B64U.decodeBase64 s of-    Left _ -> Nothing-    Right a -> Just a-{-# INLINE _Base64Url #-}---- | A 'Control.Lens.Type.Prism' into the unpadded Base64 encoding of a--- 'ByteString' value------ Please note that unpadded variants should only be used--- when assumptions about the data can be made. In particular, if the length of--- the input is divisible by 3, then this is a safe function to call.------ >>> _Base64Unpadded # "Sun"--- "UV3u"------ >>> "UV3u" ^? _Base64Unpadded--- Just "Sun"----_Base64Unpadded :: Prism' ByteString ByteString-_Base64Unpadded = prism' B64.encodeBase64Unpadded $ \s -> case B64.decodeBase64Unpadded s of-    Left _ -> Nothing-    Right a -> Just a-{-# INLINE _Base64Unpadded #-}---- | A 'Control.Lens.Type.Prism' into the Base64-url encoding of a 'ByteString' value------ Please note that unpadded variants should only be used--- when assumptions about the data can be made. In particular, if the length of--- the input is divisible by 3, then this is a safe function to call.------ >>> _Base64UrlUnpadded # "<<??>>"--- "PDw_Pz4-"------ >>> "PDw_Pz4-" ^? _Base64UrlUnpadded--- Just "<<??>>"----_Base64UrlUnpadded :: Prism' ByteString ByteString-_Base64UrlUnpadded = prism' B64U.encodeBase64Unpadded $ \s -> case B64U.decodeBase64Unpadded s of-    Left _ -> Nothing-    Right a -> Just a-{-# INLINE _Base64UrlUnpadded #-}---- -------------------------------------------------------------------------- ----- Patterns---- | Unidirectional pattern synonym for base64-encoded 'ByteString' values.----pattern Base64 :: ByteString -> ByteString-pattern Base64 a <- (preview _Base64 -> Just a) where-    Base64 a = _Base64 # a---- | Unidirectional pattern synonym for base64url-encoded 'ByteString' values.----pattern Base64Url :: ByteString -> ByteString-pattern Base64Url a <- (preview _Base64Url -> Just a) where-    Base64Url a = _Base64Url # a---- | Unidirectional pattern synonym for unpadded base64-encoded 'ByteString' values.----pattern Base64Unpadded :: ByteString -> ByteString-pattern Base64Unpadded a <- (preview _Base64Unpadded -> Just a) where-    Base64Unpadded a = _Base64Unpadded # a---- | Unidirectional pattern synonym for unpadded base64url-encoded 'ByteString' values.----pattern Base64UrlUnpadded :: ByteString -> ByteString-pattern Base64UrlUnpadded a <- (preview _Base64UrlUnpadded -> Just a) where-    Base64UrlUnpadded a = _Base64UrlUnpadded # a
− src/Data/Text/Encoding/Base64/Lens.hs
@@ -1,129 +0,0 @@-{-# LANGUAGE PatternSynonyms #-}-{-# LANGUAGE ViewPatterns #-}--- |--- Module       : Data.Text.Encoding.Base64.Lens--- Copyright 	: (c) 2019 Emily Pillmore--- License	: BSD-style------ Maintainer	: Emily Pillmore <emilypi@cohomolo.gy>--- Stability	: Experimental--- Portability	: non-portable------ This module contains 'Control.Lens.Type.Prism's Base64-encoding and--- decoding 'Text' values.----module Data.Text.Encoding.Base64.Lens-( -- * Prisms-  _Base64-, _Base64Url-, _Base64Unpadded-, _Base64UrlUnpadded-  -- * Patterns-, pattern Base64-, pattern Base64Url-, pattern Base64Unpadded-, pattern Base64UrlUnpadded-) where---import Control.Lens--import Data.Text (Text)-import qualified Data.Text.Encoding.Base64 as B64T-import qualified Data.Text.Encoding.Base64.URL as B64TU----- -------------------------------------------------------------------------- ----- Optics---- | A 'Control.Lens.Type.Prism' into the Base64 encoding of a 'Text' value.------ >>> _Base64 # "Sun"--- "UV3u"------ >>> "UV3u" ^? _Base64--- Just "Sun"----_Base64 :: Prism' Text Text-_Base64 = prism' B64T.encodeBase64 $ \s -> case B64T.decodeBase64 s of-    Left _ -> Nothing-    Right a -> Just a-{-# INLINE _Base64 #-}---- | A 'Control.Lens.Type.Prism' into the Base64-url encoding of a 'Text' value.------ >>> _Base64Url # "Sun"--- "UV3u"------ >>> "PDw_Pz8-Pg==" ^? _Base64Url--- Just "<<???>>"----_Base64Url :: Prism' Text Text-_Base64Url = prism' B64TU.encodeBase64 $ \s -> case B64TU.decodeBase64 s of-    Left _ -> Nothing-    Right a -> Just a-{-# INLINE _Base64Url #-}---- | A 'Control.Lens.Type.Prism' into the unpadded Base64 encoding of a--- 'Text' value.------ Please note that unpadded variants should only be used--- when assumptions about the data can be made. In particular, if the length of--- the input is divisible by 3, then this is a safe function to call.------ >>> _Base64Unpadded # "Sun"--- "UV3u"------ >>> "UV3u" ^? _Base64Unpadded--- Just "Sun"----_Base64Unpadded :: Prism' Text Text-_Base64Unpadded = prism' B64T.encodeBase64Unpadded $ \s -> case B64T.decodeBase64Unpadded s of-    Left _ -> Nothing-    Right a -> Just a-{-# INLINE _Base64Unpadded #-}---- | A 'Control.Lens.Type.Prism' into the Base64-url encoding of a 'Text' value.------ Please note that unpadded variants should only be used--- when assumptions about the data can be made. In particular, if the length of--- the input is divisible by 3, then this is a safe function to call.------ >>> _Base64UrlUnpadded # "<<??>>"--- "PDw_Pz4-"------ >>> "PDw_Pz4-" ^? _Base64UrlUnpadded--- Just "<<??>>"----_Base64UrlUnpadded :: Prism' Text Text-_Base64UrlUnpadded = prism' B64TU.encodeBase64Unpadded $ \s -> case B64TU.decodeBase64Unpadded s of-    Left _ -> Nothing-    Right a -> Just a-{-# INLINE _Base64UrlUnpadded #-}---- -------------------------------------------------------------------------- ----- Patterns---- | Unidirectional pattern synonym for base64-encoded 'Text' values.----pattern Base64 :: Text -> Text-pattern Base64 a <- (preview _Base64 -> Just a) where-    Base64 a = _Base64 # a---- | Unidirectional pattern synonym for base64url-encoded 'Text' values.----pattern Base64Url :: Text -> Text-pattern Base64Url a <- (preview _Base64Url -> Just a) where-    Base64Url a = _Base64Url # a---- | Unidirectional pattern synonym for unpadded base64-encoded 'Text' values.----pattern Base64Unpadded :: Text -> Text-pattern Base64Unpadded a <- (preview _Base64Unpadded -> Just a) where-    Base64Unpadded a = _Base64Unpadded # a---- | Unidirectional pattern synonym for unpadded base64url-encoded 'Text' values.----pattern Base64UrlUnpadded :: Text -> Text-pattern Base64UrlUnpadded a <- (preview _Base64UrlUnpadded -> Just a) where-    Base64UrlUnpadded a = _Base64UrlUnpadded # a