avro 0.1.0.1 → 0.2.0.0
raw patch · 15 files changed
+369/−204 lines, 15 files
Files
- avro.cabal +7/−4
- src/Data/Avro.hs +16/−154
- src/Data/Avro/Deriving.hs +23/−17
- src/Data/Avro/FromAvro.hs +101/−0
- src/Data/Avro/HasAvroSchema.hs +89/−0
- src/Data/Avro/ToAvro.hs +96/−0
- test/Avro/Codec/ArraySpec.hs +2/−2
- test/Avro/Codec/BoolSpec.hs +5/−4
- test/Avro/Codec/DoubleSpec.hs +4/−3
- test/Avro/Codec/Int64Spec.hs +7/−9
- test/Avro/Codec/MaybeSpec.hs +4/−3
- test/Avro/Codec/NestedSpec.hs +7/−3
- test/Avro/Codec/TextSpec.hs +4/−3
- test/Avro/THSimpleSpec.hs +1/−1
- test/Avro/ToAvroSpec.hs +3/−1
avro.cabal view
@@ -2,14 +2,14 @@ -- see http://haskell.org/cabal/users-guide/ name: avro-version: 0.1.0.1+version: 0.2.0.0 synopsis: Avro serialization support for Haskell description: Avro serialization and deserialization support for Haskell-homepage: https://github.com/GaloisInc/avro.git+homepage: https://github.com/haskell-works/hw-haskell-avro.git license: BSD3 license-file: LICENSE author: Thomas M. DuBuisson-maintainer: tommd@galois.com+maintainer: Alexey Raga <alexey.raga@gmail.com> -- copyright: category: Data build-type: Simple@@ -39,7 +39,10 @@ Data.Avro.Schema, Data.Avro.Types, Data.Avro.Zag,- Data.Avro.Zig+ Data.Avro.Zig,+ Data.Avro.HasAvroSchema,+ Data.Avro.FromAvro,+ Data.Avro.ToAvro other-extensions: OverloadedStrings build-depends: base >=4.8 && <5.0, aeson,
src/Data/Avro.hs view
@@ -71,11 +71,13 @@ module Data.Avro ( FromAvro(..) , ToAvro(..)+ , HasAvroSchema(..) , Avro , (.:) , (.=), record , Result(..), badValue , decode+ , decodeWithSchema , decodeContainer , decodeContainerBytes , encode@@ -109,9 +111,21 @@ import qualified Data.Vector as V import Data.Word +import Data.Avro.FromAvro+import Data.Avro.ToAvro+import Data.Avro.HasAvroSchema++type Avro a = (FromAvro a, ToAvro a)+ -- |Decode a lazy bytestring using a given Schema.-decode :: FromAvro a => Schema -> ByteString -> Result a-decode sch bytes =+decode :: forall a. FromAvro a => ByteString -> Result a+decode bytes =+ case D.decodeAvro (untag (schema :: Tagged a Type)) bytes of+ Right val -> fromAvro val+ Left err -> Error err++decodeWithSchema :: FromAvro a => Schema -> ByteString -> Result a+decodeWithSchema sch bytes = case D.decodeAvro sch bytes of Right val -> fromAvro val Left err -> Error err@@ -161,161 +175,9 @@ G.bytesRead G.getLazyByteString (end-start) -type Avro a = (FromAvro a, ToAvro a)-class FromAvro a where- fromAvro :: Value Type -> Result a--instance FromAvro (Value Type) where- fromAvro = pure-instance (ToAvro a, ToAvro b, FromAvro a, FromAvro b) => FromAvro (Either a b) where- fromAvro e@(T.Union _ v x) =- if | v == untag (schema :: Tagged a Type) -> Left <$> fromAvro x- | v == untag (schema :: Tagged b Type) -> Right <$> fromAvro x- | otherwise -> badValue e "either"- fromAvro x = badValue x "either"-instance FromAvro Bool where- fromAvro (T.Boolean b) = pure b- fromAvro v = badValue v "Bool"-instance FromAvro B.ByteString where- fromAvro (T.Bytes b) = pure b- fromAvro v = badValue v "ByteString"-instance FromAvro BL.ByteString where- fromAvro (T.Bytes b) = pure (BL.fromStrict b)- fromAvro v = badValue v "Lazy ByteString"-instance FromAvro Int where- fromAvro (T.Int i) | (fromIntegral i :: Integer) < fromIntegral (maxBound :: Int)- = pure (fromIntegral i)- fromAvro (T.Long i) | (fromIntegral i :: Integer) < fromIntegral (maxBound :: Int)- = pure (fromIntegral i)- fromAvro v = badValue v "Int"-instance FromAvro Int32 where- fromAvro (T.Int i) = pure (fromIntegral i)- fromAvro v = badValue v "Int32"-instance FromAvro Int64 where- fromAvro (T.Long i) = pure i- fromAvro (T.Int i) = pure (fromIntegral i)- fromAvro v = badValue v "Int64"-instance FromAvro Double where- fromAvro (T.Double d) = pure d- fromAvro v = badValue v "Double"-instance FromAvro a => FromAvro (Maybe a) where- fromAvro (T.Union (S.Null :| [_]) _ T.Null) = pure Nothing- fromAvro (T.Union (S.Null :| [_]) _ v) = Just <$> fromAvro v- fromAvro v = badValue v "Maybe a"--instance FromAvro a => FromAvro [a] where- fromAvro (T.Array vec) = mapM fromAvro $ toList vec- fromAvro v = badValue v "[a]"--instance FromAvro Text where- fromAvro (T.String txt) = pure txt- fromAvro v = badValue v "Text"--instance FromAvro TL.Text where- fromAvro (T.String txt) = pure (TL.fromStrict txt)- fromAvro v = badValue v "Lazy Text"--instance (FromAvro a) => FromAvro (Map.Map Text a) where- fromAvro (T.Record _ mp) = mapM fromAvro $ Map.fromList (HashMap.toList mp)- fromAvro (T.Map mp) = mapM fromAvro $ Map.fromList (HashMap.toList mp)- fromAvro v = badValue v "Map Text a"--instance (FromAvro a) => FromAvro (HashMap.HashMap Text a) where- fromAvro (T.Record _ mp) = mapM fromAvro mp- fromAvro (T.Map mp) = mapM fromAvro mp- fromAvro v = badValue v "HashMap Text a"--badValue :: Value Type -> String -> Result a-badValue v t = fail $ "Unexpected value when decoding for '" <> t <> "': " <> show v--(.:) :: FromAvro a => HashMap.HashMap Text (Value Type) -> Text -> Result a-(.:) obj key =- case HashMap.lookup key obj of- Nothing -> fail $ "Requested field not available: " <> show key- Just v -> fromAvro v--(.=) :: ToAvro a => Text -> a -> (Text,T.Value Type)-(.=) nm val = (nm,toAvro val)- record :: Foldable f => Type -> f (Text,T.Value Type) -> T.Value Type record ty = T.Record ty . HashMap.fromList . toList -class ToAvro a where- toAvro :: a -> T.Value Type- schema :: Tagged a Type--schemaOf :: (ToAvro a) => a -> Type-schemaOf = witness schema--instance ToAvro Bool where- toAvro = T.Boolean- schema = Tagged S.Boolean-instance ToAvro () where- toAvro _ = T.Null- schema = Tagged S.Null-instance ToAvro Int where- toAvro = T.Long . fromIntegral- schema = Tagged S.Long-instance ToAvro Int32 where- toAvro = T.Int- schema = Tagged S.Int-instance ToAvro Int64 where- toAvro = T.Long- schema = Tagged S.Long-instance ToAvro Double where- toAvro = T.Double- schema = Tagged S.Double-instance ToAvro Text.Text where- toAvro = T.String- schema = Tagged S.String-instance ToAvro TL.Text where- toAvro = T.String . TL.toStrict- schema = Tagged S.String-instance ToAvro B.ByteString where- toAvro = T.Bytes- schema = Tagged S.Bytes-instance ToAvro BL.ByteString where- toAvro = T.Bytes . BL.toStrict- schema = Tagged S.Bytes-instance (ToAvro a, ToAvro b) => ToAvro (Either a b) where- toAvro e =- let sch@(l:|[r]) = options (schemaOf e)- in case e of- Left a -> T.Union sch l (toAvro a)- Right b -> T.Union sch r (toAvro b)- schema = Tagged $ mkUnion (untag (schema :: Tagged a Type) :| [untag (schema :: Tagged b Type)])-instance (ToAvro a) => ToAvro (Map.Map Text a) where- toAvro = toAvro . HashMap.fromList . Map.toList- schema = wrapTag S.Map (schema :: Tagged a Type)-instance (ToAvro a) => ToAvro (HashMap.HashMap Text a) where- toAvro = T.Map . HashMap.map toAvro- schema = wrapTag S.Map (schema :: Tagged a Type)-instance (ToAvro a) => ToAvro (Map.Map TL.Text a) where- toAvro = toAvro . HashMap.fromList . map (first TL.toStrict) . Map.toList- schema = wrapTag S.Map (schema :: Tagged a Type)-instance (ToAvro a) => ToAvro (HashMap.HashMap TL.Text a) where- toAvro = toAvro . HashMap.fromList . map (first TL.toStrict) . HashMap.toList- schema = wrapTag S.Map (schema :: Tagged a Type)-instance (ToAvro a) => ToAvro (Map.Map String a) where- toAvro = toAvro . HashMap.fromList . map (first Text.pack) . Map.toList- schema = wrapTag S.Map (schema :: Tagged a Type)-instance (ToAvro a) => ToAvro (HashMap.HashMap String a) where- toAvro = toAvro . HashMap.fromList . map (first Text.pack) . HashMap.toList- schema = wrapTag S.Map (schema :: Tagged a Type)-instance (ToAvro a) => ToAvro (Maybe a) where- toAvro a =- let sch@(l:|[r]) = options (schemaOf a)- in case a of- Nothing -> T.Union sch S.Null (toAvro ())- Just v -> T.Union sch r (toAvro v)- schema = Tagged $ mkUnion (S.Null:| [untag (schema :: Tagged a Type)])-instance (ToAvro a) => ToAvro [a] where- toAvro = T.Array . V.fromList . (toAvro <$>)- schema = wrapTag S.Array (schema :: Tagged a Type)--wrapTag :: (Type -> Type) -> Tagged a Type -> Tagged b Type-wrapTag f = Tagged . f . untag-{-# INLINE wrapTag #-} -- @enumToAvro val@ will generate an Avro encoded value of enum suitable -- for serialization ('encode').
src/Data/Avro/Deriving.hs view
@@ -40,19 +40,21 @@ deriveAvro' :: Schema -> Q [Dec] deriveAvro' s = do let schemas = extractDerivables s- types <- traverse genType schemas+ types <- traverse genType schemas+ hasSchema <- traverse genHasAvroSchema schemas fromAvros <- traverse genFromAvro schemas- toAvros <- traverse genToAvro schemas- pure $ join types <> join fromAvros <> join toAvros+ toAvros <- traverse genToAvro schemas+ pure $ join types <> join hasSchema <> join fromAvros <> join toAvros -- | Derives "read only" Avro from a given schema file. -- Generates data types and FromAvro. deriveFromAvro :: FilePath -> Q [Dec] deriveFromAvro p = do- schemas <- extractDerivables <$> readSchema p- types <- traverse genType schemas+ schemas <- extractDerivables <$> readSchema p+ types <- traverse genType schemas+ hasSchema <- traverse genHasAvroSchema schemas fromAvros <- traverse genFromAvro schemas- pure $ join types <> join fromAvros+ pure $ join types <> join hasSchema <> join fromAvros readSchema :: FilePath -> Q Schema readSchema p = do@@ -84,17 +86,25 @@ ) |] -genToAvro :: Schema -> Q [Dec]-genToAvro s@(Enum n _ _ _ vs _) = do- let sname = mkSchemaValueName n+genHasAvroSchema :: Schema -> Q [Dec]+genHasAvroSchema s = do+ let sname = mkSchemaValueName (name s) sdef <- schemaDef sname s- idef <- toAvroInstance sname+ idef <- hasAvroSchema sname pure (sdef <> idef) where+ hasAvroSchema sname =+ [d| instance HasAvroSchema $(conT $ mkDataTypeName (name s)) where+ schema = pure $(varE sname)+ |]++genToAvro :: Schema -> Q [Dec]+genToAvro s@(Enum n _ _ _ vs _) = do+ toAvroInstance (mkSchemaValueName n)+ where conP' = flip conP [] . mkAdtCtorName n toAvroInstance sname = [d| instance ToAvro $(conT $ mkDataTypeName n) where- schema = pure $(varE sname) toAvro = $([| \x -> let convert = AT.Enum $(varE sname) (fromEnum $([|x|])) in $(caseE [|x|] ((\v -> match (conP' v)@@ -102,16 +112,12 @@ |]) |] -genToAvro s@(Record n _ _ _ _ fs) = do- let sname = mkSchemaValueName n- sdef <- schemaDef sname s- idef <- toAvroInstance sname- pure (sdef <> idef)+genToAvro s@(Record n _ _ _ _ fs) =+ toAvroInstance (mkSchemaValueName n) where toAvroInstance sname = [d| instance ToAvro $(conT $ mkDataTypeName n) where toAvro = $(genToAvroFieldsExp sname)- schema = pure $(varE sname) |] genToAvroFieldsExp sname = [| \r -> record $(varE sname) $(let assign fld = [| T.pack $(mkTextLit (fldName fld)) .= $(varE $ mkFieldTextName n fld) r |]
+ src/Data/Avro/FromAvro.hs view
@@ -0,0 +1,101 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE MultiWayIf #-}+module Data.Avro.FromAvro++where++import Control.Arrow (first)+import Data.Avro.HasAvroSchema+import qualified Data.Avro.Encode as E+import Data.Avro.Schema as S+import Data.Avro.Types as T+import qualified Data.ByteString as B+import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Lazy as BL+import Data.Foldable (toList)+import qualified Data.HashMap.Strict as HashMap+import Data.Int+import Data.List.NonEmpty (NonEmpty(..))+import qualified Data.Map as Map+import Data.Monoid ((<>))+import Data.Text (Text)+import qualified Data.Text as Text+import qualified Data.Text.Lazy as TL+import Data.Tagged+import qualified Data.Vector as V+import Data.Word++class HasAvroSchema a => FromAvro a where+ fromAvro :: Value Type -> Result a++-- instance FromAvro (Value Type) where+-- fromAvro = pure++(.:) :: FromAvro a => HashMap.HashMap Text (Value Type) -> Text -> Result a+(.:) obj key =+ case HashMap.lookup key obj of+ Nothing -> fail $ "Requested field not available: " <> show key+ Just v -> fromAvro v++instance (FromAvro a, FromAvro b) => FromAvro (Either a b) where+ fromAvro e@(T.Union _ v x) =+ if | v == untag (schema :: Tagged a Type) -> Left <$> fromAvro x+ | v == untag (schema :: Tagged b Type) -> Right <$> fromAvro x+ | otherwise -> badValue e "either"+ fromAvro x = badValue x "either"+instance FromAvro Bool where+ fromAvro (T.Boolean b) = pure b+ fromAvro v = badValue v "Bool"+instance FromAvro B.ByteString where+ fromAvro (T.Bytes b) = pure b+ fromAvro v = badValue v "ByteString"+instance FromAvro BL.ByteString where+ fromAvro (T.Bytes b) = pure (BL.fromStrict b)+ fromAvro v = badValue v "Lazy ByteString"+instance FromAvro Int where+ fromAvro (T.Int i) | (fromIntegral i :: Integer) < fromIntegral (maxBound :: Int)+ = pure (fromIntegral i)+ fromAvro (T.Long i) | (fromIntegral i :: Integer) < fromIntegral (maxBound :: Int)+ = pure (fromIntegral i)+ fromAvro v = badValue v "Int"+instance FromAvro Int32 where+ fromAvro (T.Int i) = pure (fromIntegral i)+ fromAvro v = badValue v "Int32"+instance FromAvro Int64 where+ fromAvro (T.Long i) = pure i+ fromAvro (T.Int i) = pure (fromIntegral i)+ fromAvro v = badValue v "Int64"+instance FromAvro Double where+ fromAvro (T.Double d) = pure d+ fromAvro v = badValue v "Double"+instance FromAvro a => FromAvro (Maybe a) where+ fromAvro (T.Union (S.Null :| [_]) _ T.Null) = pure Nothing+ fromAvro (T.Union (S.Null :| [_]) _ v) = Just <$> fromAvro v+ fromAvro v = badValue v "Maybe a"++instance FromAvro a => FromAvro [a] where+ fromAvro (T.Array vec) = mapM fromAvro $ toList vec+ fromAvro v = badValue v "[a]"++instance FromAvro Text where+ fromAvro (T.String txt) = pure txt+ fromAvro v = badValue v "Text"++instance FromAvro TL.Text where+ fromAvro (T.String txt) = pure (TL.fromStrict txt)+ fromAvro v = badValue v "Lazy Text"++instance (FromAvro a) => FromAvro (Map.Map Text a) where+ fromAvro (T.Record _ mp) = mapM fromAvro $ Map.fromList (HashMap.toList mp)+ fromAvro (T.Map mp) = mapM fromAvro $ Map.fromList (HashMap.toList mp)+ fromAvro v = badValue v "Map Text a"++instance (FromAvro a) => FromAvro (HashMap.HashMap Text a) where+ fromAvro (T.Record _ mp) = mapM fromAvro mp+ fromAvro (T.Map mp) = mapM fromAvro mp+ fromAvro v = badValue v "HashMap Text a"++badValue :: Value Type -> String -> Result a+badValue v t = fail $ "Unexpected value when decoding for '" <> t <> "': " <> show v
+ src/Data/Avro/HasAvroSchema.hs view
@@ -0,0 +1,89 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Data.Avro.HasAvroSchema where++import Data.Avro.Schema as S+import Data.Avro.Types as T+import qualified Data.ByteString as B+import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Lazy as BL+import qualified Data.HashMap.Strict as HashMap+import Data.Int+import qualified Data.Map as Map+import Data.Monoid ((<>))+import Data.Text (Text)+import qualified Data.Text as Text+import Data.List.NonEmpty (NonEmpty(..))+import qualified Data.Text.Lazy as TL+import Data.Tagged+import qualified Data.Vector as V+import Data.Word+import Data.Proxy++class HasAvroSchema a where+ schema :: Tagged a Type++schemaOf :: (HasAvroSchema a) => a -> Type+schemaOf = witness schema++instance HasAvroSchema Bool where+ schema = Tagged S.Boolean++instance HasAvroSchema () where+ schema = Tagged S.Null++instance HasAvroSchema Int where+ schema = Tagged S.Long++instance HasAvroSchema Int32 where+ schema = Tagged S.Int++instance HasAvroSchema Int64 where+ schema = Tagged S.Long++instance HasAvroSchema Double where+ schema = Tagged S.Double++instance HasAvroSchema Text.Text where+ schema = Tagged S.String++instance HasAvroSchema TL.Text where+ schema = Tagged S.String++instance HasAvroSchema B.ByteString where+ schema = Tagged S.Bytes++instance HasAvroSchema BL.ByteString where+ schema = Tagged S.Bytes++instance (HasAvroSchema a, HasAvroSchema b) => HasAvroSchema (Either a b) where+ schema = Tagged $ mkUnion (untag (schema :: Tagged a Type) :| [untag (schema :: Tagged b Type)])++instance (HasAvroSchema a) => HasAvroSchema (Map.Map Text a) where+ schema = wrapTag S.Map (schema :: Tagged a Type)++instance (HasAvroSchema a) => HasAvroSchema (HashMap.HashMap Text a) where+ schema = wrapTag S.Map (schema :: Tagged a Type)++instance (HasAvroSchema a) => HasAvroSchema (Map.Map TL.Text a) where+ schema = wrapTag S.Map (schema :: Tagged a Type)++instance (HasAvroSchema a) => HasAvroSchema (HashMap.HashMap TL.Text a) where+ schema = wrapTag S.Map (schema :: Tagged a Type)++instance (HasAvroSchema a) => HasAvroSchema (Map.Map String a) where+ schema = wrapTag S.Map (schema :: Tagged a Type)++instance (HasAvroSchema a) => HasAvroSchema (HashMap.HashMap String a) where+ schema = wrapTag S.Map (schema :: Tagged a Type)++instance (HasAvroSchema a) => HasAvroSchema (Maybe a) where+ schema = Tagged $ mkUnion (S.Null:| [untag (schema :: Tagged a Type)])++instance (HasAvroSchema a) => HasAvroSchema [a] where+ schema = wrapTag S.Array (schema :: Tagged a Type)++wrapTag :: (Type -> Type) -> Tagged a Type -> Tagged b Type+wrapTag f = Tagged . f . untag+{-# INLINE wrapTag #-}
+ src/Data/Avro/ToAvro.hs view
@@ -0,0 +1,96 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Data.Avro.ToAvro++where++import Control.Arrow (first)+import Data.Avro.HasAvroSchema+import Data.Avro.Schema as S+import Data.Avro.Types as T+import qualified Data.ByteString as B+import Data.ByteString.Lazy (ByteString)+import qualified Data.ByteString.Lazy as BL+import qualified Data.HashMap.Strict as HashMap+import Data.Int+import Data.List.NonEmpty (NonEmpty(..))+import qualified Data.Map as Map+import Data.Text (Text)+import qualified Data.Text as Text+import qualified Data.Text.Lazy as TL+import Data.Tagged+import qualified Data.Vector as V+import Data.Word++class HasAvroSchema a => ToAvro a where+ toAvro :: a -> T.Value Type++(.=) :: ToAvro a => Text -> a -> (Text,T.Value Type)+(.=) nm val = (nm,toAvro val)++instance ToAvro Bool where+ toAvro = T.Boolean++instance ToAvro () where+ toAvro _ = T.Null++instance ToAvro Int where+ toAvro = T.Long . fromIntegral++instance ToAvro Int32 where+ toAvro = T.Int++instance ToAvro Int64 where+ toAvro = T.Long++instance ToAvro Double where+ toAvro = T.Double++instance ToAvro Text.Text where+ toAvro = T.String++instance ToAvro TL.Text where+ toAvro = T.String . TL.toStrict++instance ToAvro B.ByteString where+ toAvro = T.Bytes++instance ToAvro BL.ByteString where+ toAvro = T.Bytes . BL.toStrict++instance (ToAvro a, ToAvro b) => ToAvro (Either a b) where+ toAvro e =+ let sch@(l:|[r]) = options (schemaOf e)+ in case e of+ Left a -> T.Union sch l (toAvro a)+ Right b -> T.Union sch r (toAvro b)++instance (ToAvro a) => ToAvro (Map.Map Text a) where+ toAvro = toAvro . HashMap.fromList . Map.toList++instance (ToAvro a) => ToAvro (HashMap.HashMap Text a) where+ toAvro = T.Map . HashMap.map toAvro++instance (ToAvro a) => ToAvro (Map.Map TL.Text a) where+ toAvro = toAvro . HashMap.fromList . map (first TL.toStrict) . Map.toList++instance (ToAvro a) => ToAvro (HashMap.HashMap TL.Text a) where+ toAvro = toAvro . HashMap.fromList . map (first TL.toStrict) . HashMap.toList++instance (ToAvro a) => ToAvro (Map.Map String a) where+ toAvro = toAvro . HashMap.fromList . map (first Text.pack) . Map.toList++instance (ToAvro a) => ToAvro (HashMap.HashMap String a) where+ toAvro = toAvro . HashMap.fromList . map (first Text.pack) . HashMap.toList++instance (ToAvro a) => ToAvro (Maybe a) where+ toAvro a =+ let sch@(l:|[r]) = options (schemaOf a)+ in case a of+ Nothing -> T.Union sch S.Null (toAvro ())+ Just v -> T.Union sch r (toAvro v)++instance (ToAvro a) => ToAvro [a] where+ toAvro = T.Array . V.fromList . (toAvro <$>)+
test/Avro/Codec/ArraySpec.hs view
@@ -14,8 +14,8 @@ spec :: Spec spec = describe "Avro.Codec.ArraySpec" $ do- it "list roundtip" $ Q.property $ \(xs :: [Int]) -> decode (schemaOf xs) (encode xs) == Success xs+ it "list roundtip" $ Q.property $ \(xs :: [Int]) -> decode (encode xs) == Success xs it "map roundtrip" $ Q.property $ \(xs :: Map String Int) -> let xs' = M.mapKeys T.pack xs- in decode (schemaOf xs') (encode xs') == Success xs'+ in decode (encode xs') == Success xs'
test/Avro/Codec/BoolSpec.hs view
@@ -30,11 +30,13 @@ [ fld "onlyBoolValue" Boolean Nothing ] +instance HasAvroSchema OnlyBool where+ schema = pure onlyBoolSchema+ instance ToAvro OnlyBool where toAvro sa = record onlyBoolSchema [ "onlyBoolValue" .= onlyBoolValue sa ]- schema = pure onlyBoolSchema instance FromAvro OnlyBool where fromAvro (AT.Record _ r) =@@ -42,7 +44,6 @@ spec :: Spec spec = describe "Avro.Codec.BoolSpec" $ do- let x = untag (schema :: Tagged OnlyBool Type) it "should encode True correctly" $ do let trueEncoding = BL.singleton 0x01 encode (OnlyBool True) `shouldBe` trueEncoding@@ -52,7 +53,7 @@ encode (OnlyBool False) `shouldBe` falseEncoding it "should encode then decode True correctly" $ do- decode x (encode $ OnlyBool True) `shouldBe` Success (OnlyBool True)+ decode (encode $ OnlyBool True) `shouldBe` Success (OnlyBool True) it "should encode then decode False correctly" $ do- decode x (encode $ OnlyBool False) `shouldBe` Success (OnlyBool False)+ decode (encode $ OnlyBool False) `shouldBe` Success (OnlyBool False)
test/Avro/Codec/DoubleSpec.hs view
@@ -24,10 +24,12 @@ [ fld "onlyDoubleValue" Double Nothing ] +instance HasAvroSchema OnlyDouble where+ schema = pure onlyDoubleSchema+ instance ToAvro OnlyDouble where toAvro sa = record onlyDoubleSchema [ "onlyDoubleValue" .= onlyDoubleValue sa ]- schema = pure onlyDoubleSchema instance FromAvro OnlyDouble where fromAvro (AT.Record _ r) =@@ -52,5 +54,4 @@ it "Can decode encoded Double values" $ do Q.property $ \(d :: Double) ->- let x = untag (schema :: Tagged OnlyDouble Type) in- decode x (encode (OnlyDouble d)) == Success (OnlyDouble d)+ decode (encode (OnlyDouble d)) == Success (OnlyDouble d)
test/Avro/Codec/Int64Spec.hs view
@@ -37,11 +37,13 @@ [ fld "onlyInt64Value" Long Nothing ] +instance HasAvroSchema OnlyInt64 where+ schema = pure onlyInt64Schema+ instance ToAvro OnlyInt64 where toAvro sa = record onlyInt64Schema [ "onlyInt64Value" .= onlyInt64Value sa ]- schema = pure onlyInt64Schema instance FromAvro OnlyInt64 where fromAvro (AT.Record _ r) =@@ -67,24 +69,20 @@ let value = OnlyInt64 90071992547409917 encode value `shouldBe` expectedBuffer it "Can decode 90071992547409917L correctly" $ do- let x = untag (schema :: Tagged OnlyInt64 Type) let buffer = BL.pack [0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x02] let expectedValue = OnlyInt64 90071992547409917- decode x buffer `shouldBe` Success expectedValue+ decode buffer `shouldBe` Success expectedValue it "Can decode encoded Int64 values" $ do- let x = untag (schema :: Tagged OnlyInt64 Type)- Q.property $ \(w :: Int64) -> decode x (encode (OnlyInt64 w)) == Success (OnlyInt64 w)+ Q.property $ \(w :: Int64) -> decode (encode (OnlyInt64 w)) == Success (OnlyInt64 w) it "Can decode 129L" $ do let w = 129 :: Int64- let x = untag (schema :: Tagged OnlyInt64 Type)- decode x (encode (OnlyInt64 w)) == Success (OnlyInt64 w)+ decode (encode (OnlyInt64 w)) == Success (OnlyInt64 w) it "Can decode 36028797018963968 correctly" $ do- let x = untag (schema :: Tagged OnlyInt64 Type) let buffer = BL.pack (bitStringToWord8s "10000000 10000000 10000000 10000000 10000000 10000000 10000000 10000000 00000001") let expectedValue = OnlyInt64 36028797018963968- decode x buffer `shouldBe` Success expectedValue+ decode buffer `shouldBe` Success expectedValue it "bitStringToWord8s 00000000" $ bitStringToWord8s "00000000" `shouldBe` [0x00 ] it "bitStringToWord8s 00000001" $ bitStringToWord8s "00000001" `shouldBe` [0x01 ]
test/Avro/Codec/MaybeSpec.hs view
@@ -27,11 +27,13 @@ [ fld "onlyMaybeBoolValue" (mkUnion (Null :| [Boolean])) Nothing ] +instance HasAvroSchema OnlyMaybeBool where+ schema = pure onlyMaybeBoolSchema+ instance ToAvro OnlyMaybeBool where toAvro sa = record onlyMaybeBoolSchema [ "onlyMaybeBoolValue" .= onlyMaybeBoolValue sa ]- schema = pure onlyMaybeBoolSchema instance FromAvro OnlyMaybeBool where fromAvro (AT.Record _ r) =@@ -41,5 +43,4 @@ spec = describe "Avro.Codec.MaybeSpec" $ do it "should encode then decode Maybe Bool correctly" $ do Q.property $ \(w :: Maybe Bool) ->- let x = untag (schema :: Tagged OnlyMaybeBool Type) in- decode x (encode (OnlyMaybeBool w)) `shouldBe` Success (OnlyMaybeBool w)+ decode (encode (OnlyMaybeBool w)) `shouldBe` Success (OnlyMaybeBool w)
test/Avro/Codec/NestedSpec.hs view
@@ -36,12 +36,17 @@ [ fld "parentValue1" Long Nothing , fld "parentValue2" (Array childTypeSchema) Nothing] +instance HasAvroSchema ParentType where+ schema = pure parentTypeSchema++instance HasAvroSchema ChildType where+ schema = pure childTypeSchema+ instance ToAvro ChildType where toAvro sa = record childTypeSchema [ "childValue1" .= childValue1 sa , "childValue2" .= childValue2 sa ]- schema = pure childTypeSchema instance FromAvro ChildType where fromAvro (AT.Record _ r) =@@ -54,7 +59,6 @@ [ "parentValue1" .= parentValue1 sa , "parentValue2" .= parentValue2 sa ]- schema = pure parentTypeSchema instance FromAvro ParentType where fromAvro (AT.Record _ r) =@@ -68,5 +72,5 @@ let parent = ParentType 0 [ChildType 1 2, ChildType 3 4] let parentEncoded = encode parent - let parentDecoded = decode parentTypeSchema parentEncoded+ let parentDecoded = decode parentEncoded parentDecoded `shouldBe` Success parent
test/Avro/Codec/TextSpec.hs view
@@ -24,10 +24,12 @@ [ fld "onlyTextValue" String Nothing ] +instance HasAvroSchema OnlyText where+ schema = pure onlyTextSchema+ instance ToAvro OnlyText where toAvro sa = record onlyTextSchema [ "onlyTextValue" .= onlyTextValue sa ]- schema = pure onlyTextSchema instance FromAvro OnlyText where fromAvro (AT.Record _ r) =@@ -43,5 +45,4 @@ it "Can decode encoded Text values" $ do Q.property $ \(t :: String) ->- let x = untag (schema :: Tagged OnlyText Type) in- decode x (encode (OnlyText (pack t))) == Success (OnlyText (pack t))+ decode (encode (OnlyText (pack t))) == Success (OnlyText (pack t))
test/Avro/THSimpleSpec.hs view
@@ -37,6 +37,6 @@ it "should do full round trip" $ forM_ msgs $ \msg -> do let encoded = encode msg- let decoded = decode (schemaOf msg) encoded+ let decoded = decode encoded pure msg `shouldBe` decoded
test/Avro/ToAvroSpec.hs view
@@ -39,6 +39,9 @@ , fld "attraction" Double Nothing ] +instance HasAvroSchema TypesTestMessage where+ schema = pure tmSchema+ instance ToAvro TypesTestMessage where toAvro m = record tmSchema [ "id" .= tmId m@@ -48,7 +51,6 @@ , "competence" .= tmCompetence m , "attraction" .= tmAttraction m ]- schema = pure tmSchema instance FromAvro TypesTestMessage where fromAvro (AT.Record _ r) =