avro 0.3.0.4 → 0.3.0.5
raw patch · 5 files changed
+96/−26 lines, 5 files
Files
- avro.cabal +5/−2
- src/Data/Avro/Schema.hs +29/−24
- test/Avro/THLogicalTypeSpec.hs +42/−0
- test/data/logical.avsc +12/−0
- test/data/record.avsc +8/−0
avro.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 2b77c4a4ff781ee32d8fcf7764aee0064f08ceefccd8579cfa2fc8a2d6c1ecf3+-- hash: 86dacf38d4a96f044259ea81c7afc0a5aec901f34480f50e90d4c98b05834e43 name: avro-version: 0.3.0.4+version: 0.3.0.5 synopsis: Avro serialization support for Haskell description: Avro serialization and deserialization support for Haskell category: Data@@ -24,7 +24,9 @@ test/data/enums-object.json test/data/enums.avsc test/data/karma.avsc+ test/data/logical.avsc test/data/maybe.avsc+ test/data/record.avsc test/data/reused.avsc test/data/small.avsc test/data/unions-object-a.json@@ -120,6 +122,7 @@ Avro.NormSchemaSpec Avro.THEncodeContainerSpec Avro.THEnumSpec+ Avro.THLogicalTypeSpec Avro.THReusedSpec Avro.THSimpleSpec Avro.THUnionSpec
src/Data/Avro/Schema.hs view
@@ -207,30 +207,35 @@ "bytes" -> return Bytes "string" -> return String somename -> return (NamedType (TN somename))- parseJSON (A.Object o) =- do ty <- o .: ("type" :: Text)- case ty of- "map" -> Map <$> o .: ("values" :: Text)- "array" -> Array <$> o .: ("items" :: Text)- "record" ->- Record <$> o .: ("name" :: Text)- <*> o .:? ("namespace" :: Text)- <*> o .:? ("aliases" :: Text) .!= []- <*> o .:? ("doc" :: Text)- <*> o .:? ("order" :: Text) .!= Just Ascending- <*> o .: ("fields" :: Text)- "enum" ->- mkEnum <$> o .: ("name" :: Text)- <*> o .:? ("aliases" :: Text) .!= []- <*> o .:? ("namespace" :: Text)- <*> o .:? ("doc" :: Text)- <*> o .: ("symbols" :: Text)- "fixed" ->- Fixed <$> o .: ("name" :: Text)- <*> o .:? ("namespace" :: Text)- <*> o .:? ("aliases" :: Text) .!= []- <*> o .: ("size" :: Text)- s -> fail $ "Unrecognized object type: " <> s+ parseJSON (A.Object o) = do+ mbLogicalType <- o .:? ("logicalType" :: Text) :: Parser (Maybe Text)+ ty <- o .: ("type" :: Text)++ case mbLogicalType of+ Just _ -> parseJSON (A.String ty)+ Nothing ->+ case ty of+ "map" -> Map <$> o .: ("values" :: Text)+ "array" -> Array <$> o .: ("items" :: Text)+ "record" ->+ Record <$> o .: ("name" :: Text)+ <*> o .:? ("namespace" :: Text)+ <*> o .:? ("aliases" :: Text) .!= []+ <*> o .:? ("doc" :: Text)+ <*> o .:? ("order" :: Text) .!= Just Ascending+ <*> o .: ("fields" :: Text)+ "enum" ->+ mkEnum <$> o .: ("name" :: Text)+ <*> o .:? ("aliases" :: Text) .!= []+ <*> o .:? ("namespace" :: Text)+ <*> o .:? ("doc" :: Text)+ <*> o .: ("symbols" :: Text)+ "fixed" ->+ Fixed <$> o .: ("name" :: Text)+ <*> o .:? ("namespace" :: Text)+ <*> o .:? ("aliases" :: Text) .!= []+ <*> o .: ("size" :: Text)+ s -> fail $ "Unrecognized object type: " <> T.unpack s parseJSON (A.Array arr) | V.length arr > 0 = mkUnion . NE.fromList <$> mapM parseJSON (V.toList arr) parseJSON foo = typeMismatch "Invalid JSON for Avro Schema" foo
+ test/Avro/THLogicalTypeSpec.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+module Avro.THLogicalTypeSpec+where++import Control.Lens+import Control.Monad++import qualified Data.Aeson as J+import Data.Aeson.Lens+import qualified Data.ByteString as B+import qualified Data.Char as Char+import Data.Monoid ((<>))+import Data.Text (Text)+import qualified Data.Text as T++import Test.Hspec++import Data.Avro+import Data.Avro.Deriving+import Data.Avro.Schema++deriveAvro "test/data/logical.avsc"++spec :: Spec+spec = describe "Avro.THSpec: Logical Type Schema" $ do+ let msgs =+ [ Logical 12345+ , Logical 67890+ ]++ it "should do roundtrip" $+ forM_ msgs $ \msg ->+ fromAvro (toAvro msg) `shouldBe` pure msg++ it "should do full round trip" $+ forM_ msgs $ \msg -> do+ let encoded = encode msg+ let decoded = decode encoded++ decoded `shouldBe` pure msg
+ test/data/logical.avsc view
@@ -0,0 +1,12 @@+{+ "name": "Logical",+ "type": "record",+ "fields": [{+ "name": "timestamp",+ "type":+ {+ "logicalType": "timestamp-millis",+ "type": "long"+ }+ }]+}
+ test/data/record.avsc view
@@ -0,0 +1,8 @@+{+ "type" : "record",+ "name" : "Thing",+ "fields" : [ {+ "name" : "value",+ "type" : "int"+ } ]+}