diff --git a/src/lib/Witch/Instances.hs b/src/lib/Witch/Instances.hs index 2ca9298..1273d09 100644 --- a/src/lib/Witch/Instances.hs +++ b/src/lib/Witch/Instances.hs @@ -8,6 +8,9 @@ module Witch.Instances where import qualified Data.Bits as Bits +import qualified Data.ByteString as ByteString +import qualified Data.ByteString.Lazy as LazyByteString +import qualified Data.ByteString.Short as ShortByteString import qualified Data.Complex as Complex import qualified Data.Fixed as Fixed import qualified Data.Foldable as Foldable @@ -724,6 +727,42 @@ instance Cast.Cast [a] (Seq.Seq a) where instance Cast.Cast (Seq.Seq a) [a] where cast = Foldable.toList +-- ByteString + +instance Cast.Cast [Word.Word8] ByteString.ByteString where + cast = ByteString.pack + +instance Cast.Cast ByteString.ByteString [Word.Word8] where + cast = ByteString.unpack + +instance Cast.Cast ByteString.ByteString LazyByteString.ByteString where + cast = LazyByteString.fromStrict + +instance Cast.Cast ByteString.ByteString ShortByteString.ShortByteString where + cast = ShortByteString.toShort + +-- LazyByteString + +instance Cast.Cast [Word.Word8] LazyByteString.ByteString where + cast = LazyByteString.pack + +instance Cast.Cast LazyByteString.ByteString [Word.Word8] where + cast = LazyByteString.unpack + +instance Cast.Cast LazyByteString.ByteString ByteString.ByteString where + cast = LazyByteString.toStrict + +-- ShortByteString + +instance Cast.Cast [Word.Word8] ShortByteString.ShortByteString where + cast = ShortByteString.pack + +instance Cast.Cast ShortByteString.ShortByteString [Word.Word8] where + cast = ShortByteString.unpack + +instance Cast.Cast ShortByteString.ShortByteString ByteString.ByteString where + cast = ShortByteString.fromShort + fromNonNegativeIntegral :: (Integral s, Num t) => s -> Maybe t fromNonNegativeIntegral x = if x < 0 then Nothing else Just $ fromIntegral x diff --git a/src/test/Main.hs b/src/test/Main.hs index 392f705..b166372 100644 --- a/src/test/Main.hs +++ b/src/test/Main.hs @@ -5,6 +5,9 @@ import qualified Control.Exception as Exception import qualified Control.Monad as Monad +import qualified Data.ByteString as ByteString +import qualified Data.ByteString.Lazy as LazyByteString +import qualified Data.ByteString.Short as ShortByteString import qualified Data.Complex as Complex import qualified Data.Either as Either import qualified Data.Fixed as Fixed @@ -1498,6 +1501,72 @@ main = Hspec.hspec . Hspec.describe "Witch" $ do test $ f (Seq.fromList [1]) `Hspec.shouldBe` [1] test $ f (Seq.fromList [1, 2]) `Hspec.shouldBe` [1, 2] + -- ByteString + + Hspec.describe "Cast [Word8] ByteString" $ do + let f = Witch.cast @[Word.Word8] @ByteString.ByteString + test $ f [] `Hspec.shouldBe` ByteString.pack [] + test $ f [0x00] `Hspec.shouldBe` ByteString.pack [0x00] + test $ f [0x0f, 0xf0] `Hspec.shouldBe` ByteString.pack [0x0f, 0xf0] + + Hspec.describe "Cast ByteString [Word8]" $ do + let f = Witch.cast @ByteString.ByteString @[Word.Word8] + test $ f (ByteString.pack []) `Hspec.shouldBe` [] + test $ f (ByteString.pack [0x00]) `Hspec.shouldBe` [0x00] + test $ f (ByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` [0x0f, 0xf0] + + Hspec.describe "Cast ByteString LazyByteString" $ do + let f = Witch.cast @ByteString.ByteString @LazyByteString.ByteString + test $ f (ByteString.pack []) `Hspec.shouldBe` LazyByteString.pack [] + test $ f (ByteString.pack [0x00]) `Hspec.shouldBe` LazyByteString.pack [0x00] + test $ f (ByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` LazyByteString.pack [0x0f, 0xf0] + + Hspec.describe "Cast ByteString ShortByteString" $ do + let f = Witch.cast @ByteString.ByteString @ShortByteString.ShortByteString + test $ f (ByteString.pack []) `Hspec.shouldBe` ShortByteString.pack [] + test $ f (ByteString.pack [0x00]) `Hspec.shouldBe` ShortByteString.pack [0x00] + test $ f (ByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` ShortByteString.pack [0x0f, 0xf0] + + -- LazyByteString + + Hspec.describe "Cast [Word8] LazyByteString" $ do + let f = Witch.cast @[Word.Word8] @LazyByteString.ByteString + test $ f [] `Hspec.shouldBe` LazyByteString.pack [] + test $ f [0x00] `Hspec.shouldBe` LazyByteString.pack [0x00] + test $ f [0x0f, 0xf0] `Hspec.shouldBe` LazyByteString.pack [0x0f, 0xf0] + + Hspec.describe "Cast LazyByteString [Word8]" $ do + let f = Witch.cast @LazyByteString.ByteString @[Word.Word8] + test $ f (LazyByteString.pack []) `Hspec.shouldBe` [] + test $ f (LazyByteString.pack [0x00]) `Hspec.shouldBe` [0x00] + test $ f (LazyByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` [0x0f, 0xf0] + + Hspec.describe "Cast LazyByteString ByteString" $ do + let f = Witch.cast @LazyByteString.ByteString @ByteString.ByteString + test $ f (LazyByteString.pack []) `Hspec.shouldBe` ByteString.pack [] + test $ f (LazyByteString.pack [0x00]) `Hspec.shouldBe` ByteString.pack [0x00] + test $ f (LazyByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` ByteString.pack [0x0f, 0xf0] + + -- ShortByteString + + Hspec.describe "Cast [Word8] ShortByteString" $ do + let f = Witch.cast @[Word.Word8] @ShortByteString.ShortByteString + test $ f [] `Hspec.shouldBe` ShortByteString.pack [] + test $ f [0x00] `Hspec.shouldBe` ShortByteString.pack [0x00] + test $ f [0x0f, 0xf0] `Hspec.shouldBe` ShortByteString.pack [0x0f, 0xf0] + + Hspec.describe "Cast ShortByteString [Word8]" $ do + let f = Witch.cast @ShortByteString.ShortByteString @[Word.Word8] + test $ f (ShortByteString.pack []) `Hspec.shouldBe` [] + test $ f (ShortByteString.pack [0x00]) `Hspec.shouldBe` [0x00] + test $ f (ShortByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` [0x0f, 0xf0] + + Hspec.describe "Cast ShortByteString ByteString" $ do + let f = Witch.cast @ShortByteString.ShortByteString @ByteString.ByteString + test $ f (ShortByteString.pack []) `Hspec.shouldBe` ByteString.pack [] + test $ f (ShortByteString.pack [0x00]) `Hspec.shouldBe` ByteString.pack [0x00] + test $ f (ShortByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` ByteString.pack [0x0f, 0xf0] + test :: Hspec.Example a => a -> Hspec.SpecWith (Hspec.Arg a) test = Hspec.it "" diff --git a/witch.cabal b/witch.cabal index 44f409c..2f11f40 100644 --- a/witch.cabal +++ b/witch.cabal @@ -19,6 +19,7 @@ source-repository head common basics build-depends: , base >= 4.13.0 && < 4.16 + , bytestring >= 0.10.12 && < 0.11 , containers >= 0.6.2 && < 0.7 default-language: Haskell2010 ghc-options: