packages feed

string-conv 0.1.2 → 0.2.0

raw patch · 6 files changed

+298/−147 lines, 6 filesdep +quickcheck-instancesdep +string-convdep +tastysetup-changed

Dependencies added: quickcheck-instances, string-conv, tasty, tasty-quickcheck

Files

− Data/String/Conv.hs
@@ -1,118 +0,0 @@-{-# LANGUAGE FlexibleInstances     #-}-{-# LANGUAGE MultiParamTypeClasses #-}--module Data.String.Conv-  ( StringConv (..)-  , toS-  , toSL-  , convS-  , convSL-  , Leniency (..)-  ) where---------------------------------------------------------------------------------import           Data.ByteString.Char8      as B-import           Data.ByteString.Lazy.Char8 as LB-import           Data.Text                  as T-import           Data.Text.Encoding         as T-import           Data.Text.Encoding.Error   as T-import           Data.Text.Lazy             as LT-import           Data.Text.Lazy.Encoding    as LT------------------------------------------------------------------------------------------------------------------------------------------------------------------- | Data type representing the two leniency modes defining how decoding--- failure is handled.-data Leniency = Lenient | Strict-  deriving (Eq,Show,Read,Ord,Enum,Bounded)------------------------------------------------------------------------------------ | A type class to standardize string conversions.  With this type class you--- only need to remember one function for converting between any two string--- variants.  This package includes support for String, ByteString, and Text--- as well as the Lazy and Strict variants where necessary.------ This type class lets you control how conversion should behave when failure--- is possible.  Strict mode will cause an exception to be thrown when--- decoding fails.  Lenient mode will attempt to recover, inserting a--- replacement character for invalid bytes.------ StringConv's `toS` function is most useful when you have a fully defined--- string conversion with a fixed (non-polymorphic) input and output type.  Of--- course you can still use it when you don't have a fixed type.  In that case--- you might need to specify a type class constraint such as @StringConv--- s String@.-class StringConv a b where-    strConv :: Leniency -> a -> b------------------------------------------------------------------------------------ | Universal string conversion function for strict decoding.-toS :: StringConv a b => a -> b-toS = strConv Strict------------------------------------------------------------------------------------ | Universal string conversion function for lenient decoding.-toSL :: StringConv a b => a -> b-toSL = strConv Lenient---instance StringConv String String where strConv _ = id-instance StringConv String B.ByteString where strConv l = T.encodeUtf8 . strConv l-instance StringConv String LB.ByteString where strConv l = LT.encodeUtf8 . strConv l-instance StringConv String T.Text where strConv _ = T.pack-instance StringConv String LT.Text where strConv _ = LT.pack--instance StringConv B.ByteString String where strConv l = T.unpack . strConv l-instance StringConv B.ByteString B.ByteString where strConv _ = id-instance StringConv B.ByteString LB.ByteString where strConv _ = LB.fromChunks . return-instance StringConv B.ByteString T.Text where strConv = decodeUtf8T-instance StringConv B.ByteString LT.Text where strConv l = strConv l . LB.fromChunks . return--instance StringConv LB.ByteString String where strConv l = LT.unpack . strConv l-instance StringConv LB.ByteString B.ByteString where strConv _ = B.concat . LB.toChunks-instance StringConv LB.ByteString LB.ByteString where strConv _ = id-instance StringConv LB.ByteString T.Text where strConv l = decodeUtf8T l . strConv l-instance StringConv LB.ByteString LT.Text where strConv = decodeUtf8LT--instance StringConv T.Text String where strConv _ = T.unpack-instance StringConv T.Text B.ByteString where strConv _ = T.encodeUtf8-instance StringConv T.Text LB.ByteString where strConv l = strConv l . T.encodeUtf8-instance StringConv T.Text LT.Text where strConv _ = LT.fromStrict-instance StringConv T.Text T.Text where strConv _ = id--instance StringConv LT.Text String where strConv _ = LT.unpack-instance StringConv LT.Text T.Text where strConv _ = LT.toStrict-instance StringConv LT.Text LT.Text where strConv _ = id-instance StringConv LT.Text LB.ByteString where strConv _ = LT.encodeUtf8-instance StringConv LT.Text B.ByteString where strConv l = strConv l . LT.encodeUtf8------------------------------------------------------------------------------------ | Convenience helper for dispatching based on leniency.-decodeUtf8T :: Leniency -> B.ByteString -> T.Text-decodeUtf8T Lenient = T.decodeUtf8With T.lenientDecode-decodeUtf8T Strict = T.decodeUtf8With T.strictDecode------------------------------------------------------------------------------------ | Convenience helper for dispatching based on leniency.-decodeUtf8LT :: Leniency -> LB.ByteString -> LT.Text-decodeUtf8LT Lenient = LT.decodeUtf8With T.lenientDecode-decodeUtf8LT Strict = LT.decodeUtf8With T.strictDecode------------------------------------------------------------------------------------ | A lens for 'toS' to make it slightly more convenient in some scenarios.-convS :: (StringConv a b, StringConv b a, Functor f) => (b -> f b) -> a -> f a-convS f a = fmap toS (f (toS a))------------------------------------------------------------------------------------ | A lens for 'toSL' to make it slightly more convenient in some scenarios.-convSL :: (StringConv a b, StringConv b a, Functor f) => (b -> f b) -> a -> f a-convSL f a = fmap toSL (f (toSL a))-
Setup.hs view
@@ -1,2 +1,3 @@ import Distribution.Simple+ main = defaultMain
changelog.md view
@@ -1,6 +1,8 @@-0.1.2+0.2.0 =====-* Fixed bug where String <-> ByteString conversion would trim characters to 8 bits. Now it goes through conversion to Text first.+* Don't set optimization flag for library+* Add property tests and fix to make String <-> ByteString conversion safer [PR 6](https://github.com/Soostone/string-conv/pull/6).+* Add lib-Werror flag for development  0.1.1 =====
+ src/Data/String/Conv.hs view
@@ -0,0 +1,138 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++module Data.String.Conv+  ( StringConv (..),+    toS,+    toSL,+    convS,+    convSL,+    Leniency (..),+  )+where++------------------------------------------------------------------------------+import Data.ByteString as B+import Data.ByteString.Lazy as LB+import Data.Text as T+import Data.Text.Encoding as T+import Data.Text.Encoding.Error as T+import Data.Text.Lazy as LT+import Data.Text.Lazy.Encoding as LT++------------------------------------------------------------------------------++------------------------------------------------------------------------------++-- | Data type representing the two leniency modes defining how decoding+-- failure is handled.+data Leniency = Lenient | Strict+  deriving (Eq, Show, Read, Ord, Enum, Bounded)++------------------------------------------------------------------------------++-- | A type class to standardize string conversions.  With this type class you+-- only need to remember one function for converting between any two string+-- variants.  This package includes support for String, ByteString, and Text+-- as well as the Lazy and Strict variants where necessary.+--+-- This type class lets you control how conversion should behave when failure+-- is possible.  Strict mode will cause an exception to be thrown when+-- decoding fails.  Lenient mode will attempt to recover, inserting a+-- replacement character for invalid bytes.+--+-- StringConv's `toS` function is most useful when you have a fully defined+-- string conversion with a fixed (non-polymorphic) input and output type.  Of+-- course you can still use it when you don't have a fixed type.  In that case+-- you might need to specify a type class constraint such as @StringConv+-- s String@.+class StringConv a b where+  strConv :: Leniency -> a -> b++------------------------------------------------------------------------------++-- | Universal string conversion function for strict decoding.+toS :: StringConv a b => a -> b+toS = strConv Strict++------------------------------------------------------------------------------++-- | Universal string conversion function for lenient decoding.+toSL :: StringConv a b => a -> b+toSL = strConv Lenient++instance StringConv String String where strConv _ = id++instance StringConv String B.ByteString where strConv _ = T.encodeUtf8 . T.pack++instance StringConv String LB.ByteString where strConv _ = LT.encodeUtf8 . LT.pack++instance StringConv String T.Text where strConv _ = T.pack++instance StringConv String LT.Text where strConv _ = LT.pack++instance StringConv B.ByteString String where strConv l = T.unpack . decodeUtf8T l++instance StringConv B.ByteString B.ByteString where strConv _ = id++instance StringConv B.ByteString LB.ByteString where strConv _ = LB.fromChunks . return++instance StringConv B.ByteString T.Text where strConv = decodeUtf8T++instance StringConv B.ByteString LT.Text where strConv l = strConv l . LB.fromChunks . return++instance StringConv LB.ByteString String where strConv l = LT.unpack . decodeUtf8LT l++instance StringConv LB.ByteString B.ByteString where strConv _ = B.concat . LB.toChunks++instance StringConv LB.ByteString LB.ByteString where strConv _ = id++instance StringConv LB.ByteString T.Text where strConv l = decodeUtf8T l . strConv l++instance StringConv LB.ByteString LT.Text where strConv = decodeUtf8LT++instance StringConv T.Text String where strConv _ = T.unpack++instance StringConv T.Text B.ByteString where strConv _ = T.encodeUtf8++instance StringConv T.Text LB.ByteString where strConv l = strConv l . T.encodeUtf8++instance StringConv T.Text LT.Text where strConv _ = LT.fromStrict++instance StringConv T.Text T.Text where strConv _ = id++instance StringConv LT.Text String where strConv _ = LT.unpack++instance StringConv LT.Text T.Text where strConv _ = LT.toStrict++instance StringConv LT.Text LT.Text where strConv _ = id++instance StringConv LT.Text LB.ByteString where strConv _ = LT.encodeUtf8++instance StringConv LT.Text B.ByteString where strConv l = strConv l . LT.encodeUtf8++------------------------------------------------------------------------------++-- | Convenience helper for dispatching based on leniency.+decodeUtf8T :: Leniency -> B.ByteString -> T.Text+decodeUtf8T Lenient = T.decodeUtf8With T.lenientDecode+decodeUtf8T Strict = T.decodeUtf8With T.strictDecode++------------------------------------------------------------------------------++-- | Convenience helper for dispatching based on leniency.+decodeUtf8LT :: Leniency -> LB.ByteString -> LT.Text+decodeUtf8LT Lenient = LT.decodeUtf8With T.lenientDecode+decodeUtf8LT Strict = LT.decodeUtf8With T.strictDecode++------------------------------------------------------------------------------++-- | A lens for 'toS' to make it slightly more convenient in some scenarios.+convS :: (StringConv a b, StringConv b a, Functor f) => (b -> f b) -> a -> f a+convS f a = fmap toS (f (toS a))++------------------------------------------------------------------------------++-- | A lens for 'toSL' to make it slightly more convenient in some scenarios.+convSL :: (StringConv a b, StringConv b a, Functor f) => (b -> f b) -> a -> f a+convSL f a = fmap toSL (f (toSL a))
string-conv.cabal view
@@ -1,35 +1,71 @@-name:                string-conv-version:             0.1.2-synopsis:            Standardized conversion between string types-description:         Avoids the need to remember many different functions-                     for converting string types.  Just use one universal-                     function toS for all monomorphic string conversions.-license:             BSD3-license-file:        LICENSE-author:              Ozgun Ataman-maintainer:          ozgun.ataman@soostone.com-copyright:           Soostone Inc, 2012-2015-category:            Data, String, Text-homepage:            https://github.com/Soostone/string-conv-bug-reports:         https://github.com/Soostone/string-conv/issues-build-type:          Simple-cabal-version:       >=1.8+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.34.6.+--+-- see: https://github.com/sol/hpack++name:           string-conv+version:        0.2.0+synopsis:       Standardized conversion between string types+description:    Avoids the need to remember many different functions for converting string types. Just use one universal function toS for all monomorphic string conversions.+category:       Data, String, Text+homepage:       https://github.com/Soostone/string-conv+bug-reports:    https://github.com/Soostone/string-conv/issues+author:         Ozgun Ataman+maintainer:     ozgun.ataman@soostone.com+copyright:      Soostone Inc, 2012-2015+license:        BSD3+license-file:   LICENSE+build-type:     Simple extra-source-files:-  README.md-  changelog.md+    README.md+    changelog.md +source-repository head+  type: git+  location: https://github.com/Soostone/string-conv+ flag lib-Werror-  default: False-  manual: True+  description: Turn on -Wall and -Werror. Should always be enabled in development. -source-repository head-  type:     git-  location: https://github.com/Soostone/string-conv.git+  manual: True+  default: False  library-  exposed-modules:     Data.String.Conv-  build-depends:       base >= 4.4 && < 5, bytestring, text+  exposed-modules:+      Data.String.Conv+  other-modules:+      Paths_string_conv+  hs-source-dirs:+      src+  build-depends:+      base >=4.4 && <5+    , bytestring+    , text   if flag(lib-Werror)-    ghc-options: -Werror+    ghc-options: -Wall -Werror -fwarn-redundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Widentities+  else+    ghc-options: -Wall -fwarn-redundant-constraints -Wincomplete-record-updates -Widentities+  default-language: Haskell2010 -  ghc-options: -Wall+test-suite tests+  type: exitcode-stdio-1.0+  main-is: Main.hs+  other-modules:+      Paths_string_conv+  hs-source-dirs:+      test+  ghc-options: -threaded -rtsopts -with-rtsopts=-N+  build-depends:+      base >=4.4 && <5+    , bytestring+    , quickcheck-instances >=0.3.17+    , string-conv+    , tasty+    , tasty-quickcheck+    , text+  if flag(lib-Werror)+    ghc-options: -Wall -Werror -fwarn-redundant-constraints -Wincomplete-record-updates -Wincomplete-uni-patterns -Widentities+  else+    ghc-options: -Wall -fwarn-redundant-constraints -Wincomplete-record-updates -Widentities+  default-language: Haskell2010
+ test/Main.hs view
@@ -0,0 +1,92 @@+{-# LANGUAGE OverloadedStrings #-}++import Data.ByteString as B+import Data.ByteString.Lazy as LB+import Data.String.Conv+import Data.Text as T+import Data.Text.Lazy as LT+import Test.QuickCheck.Instances.ByteString ()+import Test.QuickCheck.Instances.Text ()+import Test.Tasty+import Test.Tasty.QuickCheck++main :: IO ()+main =+  defaultMain $+    testGroup+      " tests"+      [ strictDecoding,+        lenientDecoding+      ]++strictDecoding :: TestTree+strictDecoding =+  testGroup+    "strict decoding (toS method)"+    [ testProperty "converting String to String" $ do+        \s -> s == (toS (toS (s :: String) :: String)),+      testProperty "converting String to strict ByteString" $ do+        \s -> s == (toS (toS (s :: String) :: B.ByteString)),+      testProperty "converting String to lazy ByteString" $ do+        \s -> s == (toS (toS (s :: String) :: LB.ByteString)),+      testProperty "converting String to strict Text" $ do+        \s -> s == (toS (toS (s :: String) :: T.Text)),+      testProperty "converting String to lazy Text" $ do+        \s -> s == (toS (toS (s :: String) :: LT.Text)),+      testProperty "converting strict ByteString to strict ByteString" $ do+        \s -> s == (toS (toS (s :: B.ByteString) :: B.ByteString)),+      testProperty "converting strict ByteString to lazy ByteString" $ do+        \s -> s == (toS (toS (s :: B.ByteString) :: LB.ByteString)),+      testProperty "converting lazy ByteString to lazy ByteString" $ do+        \s -> s == (toS (toS (s :: LB.ByteString) :: LB.ByteString)),+      testProperty "converting strict Text to lazy ByteString" $ do+        \s -> s == (toS (toS (s :: T.Text) :: LB.ByteString)),+      testProperty "converting strict Text to strict ByteString" $ do+        \s -> s == (toS (toS (s :: LB.ByteString) :: B.ByteString)),+      testProperty "converting strict Text to strict Text" $ do+        \s -> s == (toS (toS (s :: T.Text) :: T.Text)),+      testProperty "converting strict Text to lazy Text" $ do+        \s -> s == (toS (toS (s :: T.Text) :: LT.Text)),+      testProperty "converting lazy Text to strict ByteString" $ do+        \s -> s == (toS (toS (s :: LT.Text) :: B.ByteString)),+      testProperty "converting lazy Text to lazy ByteString" $ do+        \s -> s == (toS (toS (s :: LT.Text) :: LB.ByteString)),+      testProperty "converting lazy Text to lazy Text" $ do+        \s -> s == (toS (toS (s :: LT.Text) :: LT.Text))+    ]++lenientDecoding :: TestTree+lenientDecoding =+  testGroup+    "lenient decoding (toSL method)"+    [ testProperty "converting String to String" $ do+        \s -> s == (toSL (toSL (s :: String) :: String)),+      testProperty "converting String to strict ByteString" $ do+        \s -> s == (toSL (toSL (s :: String) :: B.ByteString)),+      testProperty "converting String to lazy ByteString" $ do+        \s -> s == (toSL (toSL (s :: String) :: LB.ByteString)),+      testProperty "converting String to strict Text" $ do+        \s -> s == (toSL (toSL (s :: String) :: T.Text)),+      testProperty "converting String to lazy Text" $ do+        \s -> s == (toSL (toSL (s :: String) :: LT.Text)),+      testProperty "converting strict ByteString to strict ByteString" $ do+        \s -> s == (toSL (toSL (s :: B.ByteString) :: B.ByteString)),+      testProperty "converting strict ByteString to lazy ByteString" $ do+        \s -> s == (toSL (toSL (s :: B.ByteString) :: LB.ByteString)),+      testProperty "converting lazy ByteString to lazy ByteString" $ do+        \s -> s == (toSL (toSL (s :: LB.ByteString) :: LB.ByteString)),+      testProperty "converting strict Text to lazy ByteString" $ do+        \s -> s == (toSL (toSL (s :: T.Text) :: LB.ByteString)),+      testProperty "converting strict Text to strict ByteString" $ do+        \s -> s == (toSL (toSL (s :: LB.ByteString) :: B.ByteString)),+      testProperty "converting strict Text to strict Text" $ do+        \s -> s == (toSL (toSL (s :: T.Text) :: T.Text)),+      testProperty "converting strict Text to lazy Text" $ do+        \s -> s == (toSL (toSL (s :: T.Text) :: LT.Text)),+      testProperty "converting lazy Text to strict ByteString" $ do+        \s -> s == (toSL (toSL (s :: LT.Text) :: B.ByteString)),+      testProperty "converting lazy Text to lazy ByteString" $ do+        \s -> s == (toSL (toSL (s :: LT.Text) :: LB.ByteString)),+      testProperty "converting lazy Text to lazy Text" $ do+        \s -> s == (toSL (toSL (s :: LT.Text) :: LT.Text))+    ]