packages feed

avro 0.3.6.0 → 0.3.6.1

raw patch · 4 files changed

+143/−19 lines, 4 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ Data.Avro.Schema: extractBindings :: Type -> HashMap TypeName Type

Files

avro.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 227dce7b3b510a3f986c3dd8ba7a73b2e32ef06ef0d81005408e20f9c8eadc2d+-- hash: 686c91bf89cf070fdd57de52066edac6394a61472b3927e5c8fab77a5c009ba1  name:           avro-version:        0.3.6.0+version:        0.3.6.1 synopsis:       Avro serialization support for Haskell description:    Avro serialization and deserialization support for Haskell category:       Data@@ -23,6 +23,7 @@     test/data/deconflict/writer.avsc     test/data/enums-object.json     test/data/enums.avsc+    test/data/internal-bindings.avsc     test/data/karma.avsc     test/data/logical.avsc     test/data/maybe.avsc
src/Data/Avro/Schema.hs view
@@ -27,6 +27,7 @@   -- * Lower level utilities   , typeName   , buildTypeEnvironment+  , extractBindings   , Result(..)   , resultToEither @@ -709,22 +710,16 @@ -- Types declared implicitly in record field definitions are also included. No distinction -- is made between aliases and normal names. extractBindings :: Type -> HashMap.HashMap TypeName Type-extractBindings = typeBindings HashMap.empty-  where-    insertAll :: (Eq k, Hashable k) => [k] -> v -> HashMap.HashMap k v -> HashMap.HashMap k v-    insertAll keys value table = foldl (\hashmap key -> HashMap.insert key value hashmap) table keys--    fieldBindings :: HashMap.HashMap TypeName Type -> Field -> HashMap.HashMap TypeName Type-    fieldBindings table Field{..} = typeBindings table fldType--    typeBindings :: HashMap.HashMap TypeName Type -> Type -> HashMap.HashMap TypeName Type-    typeBindings table t@Record{..} =-      let withRecord = insertAll (name : aliases) t table-      in HashMap.unions $ map (fieldBindings withRecord) fields-    typeBindings table e@Enum{..}  = insertAll (name : aliases) e table-    typeBindings table Union{..}   = HashMap.unions $ NE.toList $ NE.map (typeBindings table) options-    typeBindings table f@Fixed{..} = insertAll (name : aliases) f table-    typeBindings table _           = table+extractBindings = \case+  t@Record{..} ->+    let withRecord = HashMap.fromList $ (name : aliases) `zip` repeat t+    in HashMap.unions $ withRecord : (extractBindings . fldType <$> fields)+  e@Enum{..}   -> HashMap.fromList $ (name : aliases) `zip` repeat e+  Union{..}    -> HashMap.unions $ NE.toList $ extractBindings <$> options+  f@Fixed{..}  -> HashMap.fromList $ (name : aliases) `zip` repeat f+  Array{..}    -> extractBindings item+  Map{..}      -> extractBindings values+  _            -> HashMap.empty  -- | Merge two schemas to produce a third. -- Specifically, @overlay schema reference@ fills in 'NamedTypes' in 'schema' using any matching definitions from 'reference'.
test/Avro/SchemaSpec.hs view
@@ -1,13 +1,17 @@ {-# LANGUAGE DeriveGeneric       #-}+{-# LANGUAGE OverloadedLists     #-} {-# LANGUAGE OverloadedStrings   #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell     #-} module Avro.SchemaSpec where +import qualified Data.HashMap.Lazy  as HashMap+import qualified Data.HashSet       as HashSet+ import           Data.Avro import           Data.Avro.Deriving (makeSchema)-import           Data.Avro.Schema   (overlay, matches)+import           Data.Avro.Schema   (extractBindings, matches, overlay)  import           Test.Hspec @@ -15,6 +19,25 @@  spec :: Spec spec = describe "Avro.SchemaSpec" $ do+  describe "extractBindings" $+    it "should extract bindings for all internal types" $ do+    let schema = $(makeSchema "test/data/internal-bindings.avsc")+        bindings = extractBindings schema+        expected =+          [ "InternalBindings"+          , "InField"+          , "NestedInField"+          , "AliasNestedInField"+          , "NestedEnum"+          , "NestedFixed"+          , "InArray"+          , "NestedInArray"+          , "InMap"+          , "NestedInMap"+          , "InUnionA"+          , "InUnionB"+          ]+    HashSet.fromMap (() <$ bindings) == expected   describe "overlay" $     it "should support merging multiple schemas" $ do       let expected   = $(makeSchema "test/data/overlay/expectation.avsc")
+ test/data/internal-bindings.avsc view
@@ -0,0 +1,105 @@+{+  "name" : "InternalBindings",+  "type" : "record",+  "doc" : "A test record that includes subdefinitions nested in different ways.",+  "fields" : [+    {+      "name" : "inField",+      "doc" : "A record definition nested in a field of a record.",+      "type" : {+        "name" : "InField",+        "type" : "record",+        "fields" : [+          {+            "name" : "nestedInField",+            "doc" : "A record definition nested in two other records.",+            "type" : {+              "name" : "NestedInField",+              "type" : "record",+              "aliases" : ["AliasNestedInField"],+              "fields" : []+            }+          },+          {+            "name" : "nestedEnum",+            "doc" : "An enum definition nested in a nested record.",+            "type" : {+              "type" : "enum",+              "name" : "NestedEnum",+              "symbols" : ["Foo", "Bar"]+            }+          },+          {+            "name" : "nestedFixed",+            "doc" : "A fixed definition nested in a nested record.",+            "type" : {+              "type" : "fixed",+              "size" : 42,+              "name" : "NestedFixed"+            }+          }+        ]+      }+    },+    {+      "name" : "inArray",+      "doc" : "A record definition nested in an array type.",+      "type" : {+        "type" : "array",+        "items" : {+          "name" : "InArray",+          "type" : "record",+          "fields" : [+            {+              "name" : "nestedInArray",+              "doc" : "A record definition nested inside a record defined in an array.",+              "type" : {+                "name" : "NestedInArray",+                "type" : "record",+                "fields" : []+              }+            }+          ]+        }+      }+    },+    {+      "name" : "inMap",+      "doc" : "A record definition nested in a map type.",+      "type" : {+        "type" : "map",+        "values" : {+          "name" : "InMap",+          "type" : "record",+          "fields" : [+            {+              "name" : "nestedInMap",+              "doc" : "A record definition nested inside a record defined in a map.",+              "type" : {+                "name" : "NestedInMap",+                "type" : "record",+                "fields" : []+              }+            }+          ]+        }+      }+    },+    {+      "name" : "inUnion",+      "doc" : "Record definitions nested in a union.",+      "type" : [+        {+          "name" : "InUnionA",+          "type" : "record",+          "fields" : []+        },+        {+          "name" : "InUnionB",+          "type" : "record",+          "fields" : []+        }+      ]+    }+  ]+}