packages feed

binary-generic-combinators 0.4.3.0 → 0.4.4.0

raw patch · 4 files changed

+66/−4 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Binary.Combinators: data MatchASCII (ctx :: Symbol) (ascii :: Symbol)
+ Data.Binary.Combinators: instance (GHC.TypeLits.KnownSymbol ctx, GHC.TypeLits.KnownSymbol ascii) => Data.Binary.Class.Binary (Data.Binary.Combinators.MatchASCII ctx ascii)
+ Data.Binary.Combinators: instance (GHC.TypeLits.KnownSymbol ctx, GHC.TypeLits.KnownSymbol ascii) => Test.QuickCheck.Arbitrary.Arbitrary (Data.Binary.Combinators.MatchASCII ctx ascii)
+ Data.Binary.Combinators: instance GHC.Classes.Eq (Data.Binary.Combinators.MatchASCII s ns)
+ Data.Binary.Combinators: instance GHC.Classes.Ord (Data.Binary.Combinators.MatchASCII s ns)
+ Data.Binary.Combinators: instance GHC.Show.Show (Data.Binary.Combinators.MatchASCII ctx ascii)
+ Data.Binary.Combinators: matchASCII :: (KnownSymbol ctx, KnownSymbol ascii) => MatchASCII ctx ascii

Files

ChangeLog.md view
@@ -1,5 +1,10 @@ # Changelog for binary-generic-combinators +## v0.4.4.0++- Add `MatchASCII` helper.+- Minor documentation improvements.+ ## v0.4.3.0  - Add `LE` newtype wrapper for little endian (de)serialization.
binary-generic-combinators.cabal view
@@ -1,13 +1,13 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.33.0.+-- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack ----- hash: 3a3c919e506e259e384c033410599dd1b6c49127ebccec2c46eae9bdab9401d8+-- hash: 5538ed4321c0204d5b35f264f98d0eb44d34283505bd06a5c140744f0f59dd64  name:           binary-generic-combinators-version:        0.4.3.0+version:        0.4.4.0 synopsis:       Combinators and utilities to make Generic-based deriving of Binary easier and more expressive description:    Please see the README on GitHub at <https://github.com/0xd34df00d/binary-generic-combinators#readme> category:       Data, Parsing
src/Data/Binary/Combinators.hs view
@@ -25,9 +25,15 @@ , CountedBy(..) , SkipCount(..) , SkipByte(..)+ , MatchBytes , matchBytes+ , MatchByte++, MatchASCII+, matchASCII+ , LE(..) ) where @@ -36,6 +42,7 @@ import Data.Binary import Data.Binary.Get import Data.Binary.Put+import Data.Char import Data.Functor import Data.Int import Data.Kind@@ -134,6 +141,9 @@ -- if they are equal to @[ 0xd3, 0x4d, 0xf0, 0x0d ]@ respectively, or fails otherwise. -- -- Serializing this type produces the @bytes@.+-- To easily create a value of this type, use the 'matchBytes' helper.+--+-- See also 'MatchASCII'. data MatchBytes (ctx :: Symbol) (bytes :: [Nat]) :: Type where   ConsumeNil  :: MatchBytes ctx '[]   ConsumeCons :: KnownNat n => Proxy n -> MatchBytes ctx ns -> MatchBytes ctx (n ': ns)@@ -185,6 +195,43 @@  -- | An alias for 'MatchBytes' when you only need to match a single byte. type MatchByte ctx byte = MatchBytes ctx '[ byte ]+++-- | @MatchASCII ctx ascii@ ensures that the subsequent bytes in the input stream match the ASCII characters @ascii@.+--+-- Serializing this type producers the @ascii@.+-- To easily create a value of this type, use the 'matchASCII' helper.+--+-- See also 'MatchBytes'.+data MatchASCII (ctx :: Symbol) (ascii :: Symbol) where+  ConsumeASCII :: KnownSymbol ascii => MatchASCII ctx ascii++deriving instance Eq (MatchASCII s ns)+deriving instance Ord (MatchASCII s ns)++toBytes :: forall ctx ascii. MatchASCII ctx ascii -> [Word8]+toBytes ConsumeASCII = map (fromIntegral . ord) $ symbolVal (Proxy :: Proxy ascii)++instance (KnownSymbol ctx, KnownSymbol ascii) => Binary (MatchASCII ctx ascii) where+  get = do bytes <- replicateM (length expected) get+           when (bytes /= expected) $ fail $ "Unexpected bytes " <> show bytes+                                                                 <> " (or, as ASCII, `" <> (chr . fromIntegral <$> bytes) <> "`)"+                                                                 <> " when parsing" <> symbolVal (Proxy :: Proxy ctx)+           pure resSing+    where+      resSing = ConsumeASCII+      expected = toBytes resSing+  put = mapM_ put . toBytes++instance Show (MatchASCII ctx ascii) where+  show ConsumeASCII = "Marker [ " <> symbolVal (Proxy :: Proxy ascii) <> " ]"++instance (KnownSymbol ctx, KnownSymbol ascii) => Arbitrary (MatchASCII ctx ascii) where+  arbitrary = pure matchASCII++-- | Produce the (singleton) value of type 'MatchASCII' @ctx ascii@.+matchASCII :: (KnownSymbol ctx, KnownSymbol ascii) => MatchASCII ctx ascii+matchASCII = ConsumeASCII   -- | An @a@ serialized in little endian byte order.
test/Spec.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE DerivingVia, DeriveGeneric #-}+{-# LANGUAGE DerivingVia, DeriveGeneric, DeriveAnyClass #-} {-# LANGUAGE DataKinds #-}  import Data.Binary@@ -50,6 +50,13 @@   deriving (Show, Eq, Generic)   deriving Binary via Alternatively ComplexType +newtype WithBytesMarker = WithBytesMarker (MatchBytes "test context" [ 113, 111, 105, 102 ])+  deriving (Show, Eq, Generic)+  deriving anyclass Binary+newtype WithASCIIMarker = WithASCIIMarker (MatchASCII "test context" "qoif")+  deriving (Show, Eq, Generic)+  deriving anyclass Binary+ instance Arbitrary ComplexType where   arbitrary = genericArbitrary   shrink = genericShrink@@ -80,6 +87,9 @@     it "decoding Word16" $ property $ \(n :: Word16) -> getLE (decode $ encode n) `shouldBe` swapBytes n     it "decoding Word32" $ property $ \(n :: Word32) -> getLE (decode $ encode n) `shouldBe` swapBytes n     it "decoding Word64" $ property $ \(n :: Word64) -> getLE (decode $ encode n) `shouldBe` swapBytes n+  describe "MatchASCII" $ do+    it "matches MatchBytes when encoding" $ decode (encode $ WithASCIIMarker matchASCII) `shouldBe` WithBytesMarker matchBytes+    it "matches MatchBytes when decoding" $ decode (encode $ WithBytesMarker matchBytes) `shouldBe` WithASCIIMarker matchASCII  swapBytes :: Bytes a => a -> a swapBytes n = case targetByteOrder of