avro 0.4.1.1 → 0.4.1.2
raw patch · 7 files changed
+82/−11 lines, 7 filesdep +tf-randomdep −entropyPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
Dependencies added: tf-random
Dependencies removed: entropy
API changes (from Hackage documentation)
+ Data.Avro.Schema: parseFullname :: Text -> TypeName
+ Data.Avro.Schema: primitiveType :: Text -> Maybe Type
Files
- ChangeLog.md +4/−0
- avro.cabal +8/−7
- src/Data/Avro/Encode.hs +3/−2
- src/Data/Avro/JSON.hs +5/−2
- src/Data/Avro/Schema.hs +23/−0
- test/Avro/JSONSpec.hs +15/−0
- test/data/unions-no-namespace.avsc +24/−0
ChangeLog.md view
@@ -1,5 +1,9 @@ # Revision history for avro +## HEAD++- Replace `entropy` library with `tf-random`, which is easier to use with ghcjs+ ## 0.4.1.1 - Fixed bugs in handling of namespaces when parsing and printing avro types
avro.cabal view
@@ -4,15 +4,15 @@ -- -- see: https://github.com/sol/hpack ----- hash: 0368e22fa6552aa4d9b3ada7a95e8210af8b40090f3244fe99d68ca30f606e8d+-- hash: ca29cdadb7a7a9edda357686a62ea84b9122a6bedb7fe04890a5d1fcc8719127 name: avro-version: 0.4.1.1+version: 0.4.1.2 synopsis: Avro serialization support for Haskell description: Avro serialization and deserialization support for Haskell category: Data-homepage: https://github.com/GaloisInc/avro#readme-bug-reports: https://github.com/GaloisInc/avro/issues+homepage: https://github.com/haskell-works/avro#readme+bug-reports: https://github.com/haskell-works/avro/issues author: Thomas M. DuBuisson maintainer: Alexey Raga <alexey.raga@gmail.com> license: BSD3@@ -29,6 +29,7 @@ test/data/record.avsc test/data/reused.avsc test/data/small.avsc+ test/data/unions-no-namespace.avsc test/data/unions.avsc test/data/enums-object.json test/data/namespace-inference.json@@ -42,7 +43,7 @@ source-repository head type: git- location: https://github.com/GaloisInc/avro+ location: https://github.com/haskell-works/avro flag dev description: Use development GHC flags@@ -98,7 +99,6 @@ , bytestring , containers , data-binary-ieee754- , entropy , fail , hashable , mtl@@ -107,6 +107,7 @@ , semigroups , tagged , text+ , tf-random , unordered-containers , vector if flag(templatehaskell)@@ -169,7 +170,6 @@ , bytestring , containers , directory- , entropy , extra , fail , hashable@@ -182,6 +182,7 @@ , semigroups , tagged , text+ , tf-random , transformers , unordered-containers , vector
src/Data/Avro/Encode.hs view
@@ -52,8 +52,9 @@ import qualified Data.Vector as V import qualified Data.Vector.Unboxed as U import Data.Word+import System.Random.TF.Init (initTFGen)+import System.Random.TF.Instances (randoms) import Prelude as P-import System.Entropy (getEntropy) import Data.Avro.EncodeRaw import Data.Avro.HasAvroSchema@@ -67,7 +68,7 @@ -- | Generates a new synchronization marker for encoding Avro containers newSyncBytes :: IO BL.ByteString-newSyncBytes = BL.fromStrict <$> getEntropy 16+newSyncBytes = BL.pack . DL.take 16 . randoms <$> initTFGen -- |Encode chunks of objects into a container, using 16 random bytes for -- the synchronization markers.
src/Data/Avro/JSON.hs view
@@ -96,11 +96,14 @@ fail "Invalid encoding of union: object with too many fields." | otherwise = let+ canonicalize name+ | Just _ <- Schema.primitiveType name = name+ | otherwise = Schema.renderFullname $ Schema.parseFullname name branch =- head (HashMap.keys obj)+ head $ HashMap.keys obj names = HashMap.fromList [(Schema.typeName t, t) | t <- NE.toList schemas]- in case HashMap.lookup branch names of+ in case HashMap.lookup (canonicalize branch) names of Just t -> do nested <- parseAvroJSON union env t (obj ! branch) return (Avro.Union schemas t nested)
src/Data/Avro/Schema.hs view
@@ -22,10 +22,12 @@ , Field(..), Order(..) , TypeName(..) , renderFullname+ , parseFullname , mkEnum, mkUnion , validateSchema -- * Lower level utilities , typeName+ , primitiveType , buildTypeEnvironment , extractBindings @@ -294,6 +296,27 @@ NamedType name -> renderFullname name Union (x:|_) _ -> typeName x _ -> renderFullname $ name bt++-- | If the given string is the name of a primitive type, return the+-- type, otherwise return 'Nothing'.+--+-- @+-- λ> primitiveType "string"+-- Just String+-- λ> primitiveType "foo"+-- Nothing+-- @+primitiveType :: Text -> Maybe Type+primitiveType = \case+ "null" -> Just Null+ "boolean" -> Just Boolean+ "int" -> Just Int+ "long" -> Just Long+ "float" -> Just Float+ "double" -> Just Double+ "bytes" -> Just Bytes+ "string" -> Just String+ _ -> Nothing data Field = Field { fldName :: Text , fldAliases :: [Text]
test/Avro/JSONSpec.hs view
@@ -24,6 +24,7 @@ deriveAvro "test/data/reused.avsc" deriveAvro "test/data/small.avsc" deriveAvro "test/data/unions.avsc"+deriveAvro "test/data/unions-no-namespace.avsc" spec :: Spec spec = describe "Avro.JSONSpec: JSON serialization/parsing" $ do@@ -95,6 +96,20 @@ it "should parse (unions)" $ do parseJSON unionsJsonA `shouldBe` pure unionsExampleA parseJSON unionsJsonB `shouldBe` pure unionsExampleB++ let unionsNoNamespaceA = UnionsNoNamespace (Left TypeA)+ unionsNoNamespaceB = UnionsNoNamespace (Right TypeB)+ it "should roundtrip (unions-no-namespace)" $ do+ parseJSON (Aeson.encode (toJSON unionsNoNamespaceA)) `shouldBe`+ pure unionsNoNamespaceA+ parseJSON (Aeson.encode (toJSON unionsNoNamespaceB)) `shouldBe`+ pure unionsNoNamespaceB+ let noNamespace = "test/data/unions-no-namespace-object.json"+ objectA = "{ \"unionField\" : { \"TypeA\" : {} } }"+ objectB = "{ \"unionField\" : { \"TypeB\" : {} } }"+ it "should parse (unions-no-namespace)" $ do+ parseJSON objectA `shouldBe` pure unionsNoNamespaceA+ parseJSON objectB `shouldBe` pure unionsNoNamespaceB getFileName :: FilePath -> IO FilePath getFileName p = do
+ test/data/unions-no-namespace.avsc view
@@ -0,0 +1,24 @@+{+ "type" : "record",+ "name" : "UnionsNoNamespace",+ "doc" : "An example schema that has a union whose components are types with no namespace. This was causing problems with our JSON parsing code.",+ "fields" : [+ {+ "name" : "unionField",+ "type" : [+ {+ "type" : "record",+ "name" : "TypeA",+ "doc" : "TypeA is in the null namespace but has no leading dot in the schema.",+ "fields" : []+ },+ {+ "type" : "record",+ "name" : ".TypeB",+ "doc" : "Note the leading dot—semantically this is the same as having no namespace, but it caused parsing issues in the past.",+ "fields" : []+ }+ ]+ }+ ]+}