packages feed

avro 0.4.1.2 → 0.4.2.0

raw patch · 9 files changed

+130/−129 lines, 9 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Data.Avro.Schema: primitiveType :: Text -> Maybe Type

Files

avro.cabal view
@@ -1,13 +1,7 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.31.1.------ see: https://github.com/sol/hpack------ hash: ca29cdadb7a7a9edda357686a62ea84b9122a6bedb7fe04890a5d1fcc8719127- name:           avro-version:        0.4.1.2+version:        0.4.2.0 synopsis:       Avro serialization support for Haskell description:    Avro serialization and deserialization support for Haskell category:       Data@@ -88,7 +82,6 @@   hs-source-dirs:       src   other-extensions: OverloadedStrings-  ghc-options: -O2   build-depends:       aeson     , array
src/Data/Avro/Deriving.hs view
@@ -32,41 +32,41 @@ ) where -import           Control.Monad                      (join)-import           Data.Aeson                         (eitherDecode)-import qualified Data.Aeson                         as J-import           Data.Avro                          hiding (decode, encode)-import           Data.Avro.Schema                   as S-import qualified Data.Avro.Types                    as AT-import           Data.ByteString                    (ByteString)-import qualified Data.ByteString                    as B-import           Data.Char                          (isAlphaNum)+import           Control.Monad      (join)+import           Data.Aeson         (eitherDecode)+import qualified Data.Aeson         as J+import           Data.Avro          hiding (decode, encode)+import           Data.Avro.Schema   as S+import qualified Data.Avro.Types    as AT+import           Data.ByteString    (ByteString)+import qualified Data.ByteString    as B+import           Data.Char          (isAlphaNum) import           Data.Int-import           Data.List.NonEmpty                 (NonEmpty ((:|)))-import qualified Data.List.NonEmpty                 as NE-import           Data.Map                           (Map)-import           Data.Maybe                         (fromMaybe)-import           Data.Semigroup                     ((<>))-import qualified Data.Text                          as Text+import           Data.List.NonEmpty (NonEmpty ((:|)))+import qualified Data.List.NonEmpty as NE+import           Data.Map           (Map)+import           Data.Maybe         (fromMaybe)+import           Data.Semigroup     ((<>))+import qualified Data.Text          as Text  -import           GHC.Generics                       (Generic)+import GHC.Generics (Generic) -import           Language.Haskell.TH                as TH hiding (notStrict)-import           Language.Haskell.TH.Lib            as TH hiding (notStrict)-import           Language.Haskell.TH.Syntax+import Language.Haskell.TH        as TH hiding (notStrict)+import Language.Haskell.TH.Lib    as TH hiding (notStrict)+import Language.Haskell.TH.Syntax -import           Data.Avro.Deriving.NormSchema-import           Data.Avro.EitherN+import Data.Avro.Deriving.NormSchema+import Data.Avro.EitherN -import qualified Data.ByteString                    as BS-import qualified Data.ByteString.Lazy               as LBS-import qualified Data.ByteString.Lazy.Char8         as LBSC8-import qualified Data.HashMap.Strict                as HM-import qualified Data.Set                           as S-import           Data.Text                          (Text)-import qualified Data.Text                          as T-import qualified Data.Vector                        as V+import qualified Data.ByteString            as BS+import qualified Data.ByteString.Lazy       as LBS+import qualified Data.ByteString.Lazy.Char8 as LBSC8+import qualified Data.HashMap.Strict        as HM+import qualified Data.Set                   as S+import           Data.Text                  (Text)+import qualified Data.Text                  as T+import qualified Data.Vector                as V  import           Data.Avro.Decode.Lazy.FromLazyAvro import qualified Data.Avro.Decode.Lazy.LazyValue    as LV@@ -110,14 +110,14 @@   { -- | How to build field names for generated data types. The first     -- argument is the type name to use as a prefix, rendered     -- according to the 'namespaceBehavior' setting.-    fieldNameBuilder :: Text -> Field -> T.Text+    fieldNameBuilder    :: Text -> Field -> T.Text      -- | Determines field representation of generated data types-  , fieldRepresentation  :: TypeName -> Field -> (FieldStrictness, FieldUnpackedness)+  , fieldRepresentation :: TypeName -> Field -> (FieldStrictness, FieldUnpackedness)      -- | Controls how we handle namespaces when defining Haskell type     -- and field names.-  , namespaceBehavior :: NamespaceBehavior+  , namespaceBehavior   :: NamespaceBehavior   } deriving Generic  -- | Default deriving options@@ -672,10 +672,10 @@   pure $ NewtypeD [] dn [] Nothing ctor ders #else genNewtype dn = do-  [ConT eq, ConT sh] <- sequenceA [[t|Eq|], [t|Show|], [t|Generic|]]+  [ConT eq, ConT sh, ConT gen] <- sequenceA [[t|Eq|], [t|Show|], [t|Generic|]]   fldType <- [t|ByteString|]   let ctor = RecC dn [(mkName ("un" ++ nameBase dn), notStrict, fldType)]-  pure $ NewtypeD [] dn [] ctor [eq, sh]+  pure $ NewtypeD [] dn [] ctor [eq, sh, gen] #endif  genEnum :: Name -> [Name] -> Q Dec@@ -689,8 +689,8 @@   pure $ DataD [] dn [] Nothing ((\n -> NormalC n []) <$> vs) ders #else genEnum dn vs = do-  [ConT eq, ConT sh, ConT or, ConT en] <- sequenceA [[t|Eq|], [t|Show|], [t|Ord|], [t|Enum|], [t|Generic|]]-  pure $ DataD [] dn [] ((\n -> NormalC n []) <$> vs) [eq, sh, or, en]+  [ConT eq, ConT sh, ConT or, ConT en, ConT gen] <- sequenceA [[t|Eq|], [t|Show|], [t|Ord|], [t|Enum|], [t|Generic|]]+  pure $ DataD [] dn [] ((\n -> NormalC n []) <$> vs) [eq, sh, or, en, gen] #endif  genDataType :: Name -> [VarStrictType] -> Q Dec@@ -704,8 +704,8 @@   pure $ DataD [] dn [] Nothing [RecC dn flds] ders #else genDataType dn flds = do-  [ConT eq, ConT sh] <- sequenceA [[t|Eq|], [t|Show|], [t|Generic|]]-  pure $ DataD [] dn [] [RecC dn flds] [eq, sh]+  [ConT eq, ConT sh, ConT gen] <- sequenceA [[t|Eq|], [t|Show|], [t|Generic|]]+  pure $ DataD [] dn [] [RecC dn flds] [eq, sh, gen] #endif  notStrict :: Strict
src/Data/Avro/JSON.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE OverloadedStrings   #-} {-# LANGUAGE ScopedTypeVariables #-} -- | Avro supports a JSON representation of Avro objects alongside the -- Avro binary format. An Avro schema can be used to generate and@@ -97,8 +98,8 @@       | otherwise      =           let             canonicalize name-              | Just _ <- Schema.primitiveType name = name-              | otherwise = Schema.renderFullname $ Schema.parseFullname name+              | isBuiltIn name = name+              | otherwise      = Schema.renderFullname $ Schema.parseFullname name             branch =               head $ HashMap.keys obj             names =@@ -112,6 +113,9 @@       Avro.Error "Invalid JSON representation for union: has to be a JSON object with exactly one field."     union _ _ =       error "Impossible: function given non-union schema."++    isBuiltIn name = name `elem` [ "null", "boolean", "int", "long", "float"+                                 , "double", "bytes", "string", "array", "map" ]  -- | Convert a 'Aeson.Value' into a type that has an Avro schema. The -- schema is used to validate the JSON and will return an 'Error' if
src/Data/Avro/Schema.hs view
@@ -27,7 +27,6 @@   , validateSchema   -- * Lower level utilities   , typeName-  , primitiveType   , buildTypeEnvironment   , extractBindings @@ -51,34 +50,33 @@ import qualified Control.Monad.Fail         as MF import           Control.Monad.State.Strict -import           Data.Aeson                 (FromJSON (..), ToJSON (..), object,-                                             (.!=), (.:), (.:!), (.:?), (.=))-import qualified Data.Aeson                 as A-import           Data.Aeson.Types           (Parser, typeMismatch)-import qualified Data.Avro.Types            as Ty-import qualified Data.ByteString            as B-import qualified Data.ByteString.Base16     as Base16-import qualified Data.Char                  as Char-import           Data.Function              (on)+import           Data.Aeson             (FromJSON (..), ToJSON (..), object, (.!=), (.:), (.:!), (.:?), (.=))+import qualified Data.Aeson             as A+import           Data.Aeson.Types       (Parser, typeMismatch)+import qualified Data.Avro.Types        as Ty+import qualified Data.ByteString        as B+import qualified Data.ByteString.Base16 as Base16+import qualified Data.Char              as Char+import           Data.Function          (on) import           Data.Hashable-import qualified Data.HashMap.Strict        as HashMap+import qualified Data.HashMap.Strict    as HashMap import           Data.Int-import qualified Data.IntMap                as IM-import qualified Data.List                  as L-import           Data.List.NonEmpty         (NonEmpty (..))-import qualified Data.List.NonEmpty         as NE-import           Data.Maybe                 (catMaybes, fromMaybe, isJust)-import           Data.Monoid                (First (..))+import qualified Data.IntMap            as IM+import qualified Data.List              as L+import           Data.List.NonEmpty     (NonEmpty (..))+import qualified Data.List.NonEmpty     as NE+import           Data.Maybe             (catMaybes, fromMaybe, isJust)+import           Data.Monoid            (First (..)) import           Data.Semigroup-import qualified Data.Set                   as S+import qualified Data.Set               as S import           Data.String-import           Data.Text                  (Text)-import qualified Data.Text                  as T-import           Data.Text.Encoding         as T-import qualified Data.Vector                as V-import           Prelude                    as P+import           Data.Text              (Text)+import qualified Data.Text              as T+import           Data.Text.Encoding     as T+import qualified Data.Vector            as V+import           Prelude                as P -import           Text.Show.Functions        ()+import Text.Show.Functions ()  -- |An Avro schema is either -- * A "JSON object in the form `{"type":"typeName" ...`@@ -297,27 +295,6 @@     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]                    , fldDoc     :: Maybe Text@@ -565,6 +542,7 @@   (<>) = mplus instance Monoid (Result a) where   mempty = fail "Empty Result"+  mappend = (<>) instance Foldable Result where   foldMap _ (Error _)   = mempty   foldMap f (Success y) = f y
test/Avro/JSONSpec.hs view
@@ -8,6 +8,7 @@  import qualified Data.Aeson           as Aeson import qualified Data.ByteString.Lazy as LBS+import qualified Data.Map             as Map  import           Data.Avro.Deriving import           Data.Avro.EitherN@@ -69,24 +70,26 @@     let expected = EnumWrapper 37 "blarg" EnumReasonInstead     parseJSON enumsExampleJSON `shouldBe` pure expected   let unionsExampleA = Unions-        { unionsScalars    = Left "blarg"-        , unionsNullable   = Nothing-        , unionsRecords    = Left $ Foo { fooStuff = "stuff" }-        , unionsSameFields = Left $ Foo { fooStuff = "foo stuff" }-        , unionsThree      = E3_1 37-        , unionsFour       = E4_2 "foo"-        , unionsFive       = E5_4 $ Foo { fooStuff = "foo stuff" }+        { unionsScalars     = Left "blarg"+        , unionsNullable    = Nothing+        , unionsRecords     = Left $ Foo { fooStuff = "stuff" }+        , unionsSameFields  = Left $ Foo { fooStuff = "foo stuff" }+        , unionsArrayAndMap = Left ["foo"]+        , unionsThree       = E3_1 37+        , unionsFour        = E4_2 "foo"+        , unionsFive        = E5_4 $ Foo { fooStuff = "foo stuff" }         }       unionsExampleB = Unions-        { unionsScalars    = Right 37-        , unionsNullable   = Just 42-        , unionsRecords    = Right $ Bar { barStuff = "stuff"-                                      , barThings = Foo "things"-                                      }-        , unionsSameFields = Right $ NotFoo { notFooStuff = "not foo stuff" }-        , unionsThree      = E3_3 37-        , unionsFour       = E4_4 $ Foo { fooStuff = "foo stuff" }-        , unionsFive       = E5_5 $ NotFoo { notFooStuff = "not foo stuff" }+        { unionsScalars     = Right 37+        , unionsNullable    = Just 42+        , unionsRecords     = Right $ Bar { barStuff = "stuff"+                                          , barThings = Foo "things"+                                          }+        , unionsSameFields  = Right $ NotFoo { notFooStuff = "not foo stuff" }+        , unionsArrayAndMap = Right $ Map.fromList [("a", 5)]+        , unionsThree       = E3_3 37+        , unionsFour        = E4_4 $ Foo { fooStuff = "foo stuff" }+        , unionsFive        = E5_5 $ NotFoo { notFooStuff = "not foo stuff" }         }   it "should roundtrip (unions)" $ do     forM_ [unionsExampleA, unionsExampleB] $ \ msg ->
test/Avro/THUnionSpec.hs view
@@ -14,6 +14,7 @@ import qualified Data.Avro.Schema     as Schema import qualified Data.Avro.Types      as Avro import qualified Data.ByteString.Lazy as LBS+import qualified Data.Map             as Map  import           System.Directory     (doesFileExist) @@ -26,24 +27,26 @@ spec :: Spec spec = describe "Avro.THUnionSpec: Schema with unions." $ do   let objA = Unions-        { unionsScalars    = Left "foo"-        , unionsNullable   = Nothing-        , unionsRecords    = Left $ Foo { fooStuff = "stuff" }-        , unionsSameFields = Left $ Foo { fooStuff = "more stuff" }-        , unionsThree      = E3_1 37-        , unionsFour       = E4_2 "foo"-        , unionsFive       = E5_4 $ Foo { fooStuff = "foo stuff" }+        { unionsScalars     = Left "foo"+        , unionsNullable    = Nothing+        , unionsRecords     = Left $ Foo { fooStuff = "stuff" }+        , unionsSameFields  = Left $ Foo { fooStuff = "more stuff" }+        , unionsArrayAndMap = Left ["foo"]+        , unionsThree       = E3_1 37+        , unionsFour        = E4_2 "foo"+        , unionsFive        = E5_4 $ Foo { fooStuff = "foo stuff" }         }       objB = Unions-        { unionsScalars    = Right 42-        , unionsNullable   = Just 37-        , unionsRecords    = Right $ Bar { barStuff  = "stuff"-                                         , barThings = Foo { fooStuff = "things" }-                                       }-        , unionsSameFields = Right $ NotFoo { notFooStuff = "different from Foo" }-        , unionsThree      = E3_3 37-        , unionsFour       = E4_4 $ Foo { fooStuff = "foo stuff" }-        , unionsFive       = E5_5 $ NotFoo { notFooStuff = "not foo stuff" }+        { unionsScalars     = Right 42+        , unionsNullable    = Just 37+        , unionsRecords     = Right $ Bar { barStuff  = "stuff"+                                          , barThings = Foo { fooStuff = "things" }+                                          }+        , unionsSameFields  = Right $ NotFoo { notFooStuff = "different from Foo" }+        , unionsArrayAndMap = Right $ Map.fromList [("a", 5)]+        , unionsThree       = E3_3 37+        , unionsFour        = E4_4 $ Foo { fooStuff = "foo stuff" }+        , unionsFive        = E5_5 $ NotFoo { notFooStuff = "not foo stuff" }         }        field name schema def = Schema.Field name [] Nothing (Just Schema.Ascending) schema def@@ -54,10 +57,11 @@       foo    = named "haskell.avro.example.Foo"       notFoo = named "haskell.avro.example.NotFoo"       expectedSchema = record "haskell.avro.example.Unions"-        [ field "scalars"    (Schema.mkUnion (NE.fromList [Schema.String, Schema.Long])) scalarsDefault-        , field "nullable"   (Schema.mkUnion (NE.fromList [Schema.Null, Schema.Int]))    nullableDefault-        , field "records"    (Schema.mkUnion (NE.fromList [fooSchema, barSchema]))       Nothing-        , field "sameFields" (Schema.mkUnion (NE.fromList [foo, notFooSchema]))          Nothing+        [ field "scalars"     (Schema.mkUnion (NE.fromList [Schema.String, Schema.Long])) scalarsDefault+        , field "nullable"    (Schema.mkUnion (NE.fromList [Schema.Null, Schema.Int]))    nullableDefault+        , field "records"     (Schema.mkUnion (NE.fromList [fooSchema, barSchema]))       Nothing+        , field "sameFields"  (Schema.mkUnion (NE.fromList [foo, notFooSchema]))          Nothing+        , field "arrayAndMap" (Schema.mkUnion (NE.fromList [array, map]))                 Nothing          , field "three" (Schema.mkUnion (NE.fromList [Schema.Int, Schema.String, Schema.Long]))              Nothing         , field "four"  (Schema.mkUnion (NE.fromList [Schema.Int, Schema.String, Schema.Long, foo]))         Nothing@@ -72,6 +76,9 @@         , field "things" (named "haskell.avro.example.Foo") Nothing         ]       notFooSchema = record "haskell.avro.example.NotFoo" [field "stuff" Schema.String Nothing]++      array = Schema.Array { Schema.item = Schema.String }+      map   = Schema.Map { Schema.values = Schema.Long }    unionsSchemaFile <- runIO $ getFileName "test/data/unions.avsc" >>= LBS.readFile   let Just unionsSchemaFromJSON = Aeson.decode unionsSchemaFile
test/data/unions-object-a.json view
@@ -13,6 +13,9 @@       "stuff": "foo stuff"     }   },+  "arrayAndMap" : {+    "array" : ["foo"]+  },   "three": { "int": 37 },   "four": { "string": "foo" },   "five": {
test/data/unions-object-b.json view
@@ -18,6 +18,9 @@       "stuff": "not foo stuff"     }   },+  "arrayAndMap" : {+    "map" : { "a" : 5 }+  },   "three": { "long": 37 },   "four": {     "haskell.avro.example.Foo": { "stuff" : "foo stuff" }
test/data/unions.avsc view
@@ -44,6 +44,16 @@         }       ]     },+    { "name" : "arrayAndMap",+      "type" : [+        { "type" : "array",+          "items" : "string"+        },+        { "type" : "map",+          "values" : "long"+        }+      ]+    },     { "name" : "three", "type" : ["int", "string", "long"] },     { "name" : "four", "type" : ["int", "string", "long", "Foo"] },     { "name" : "five", "type" : ["int", "string", "long", "Foo", "NotFoo"] }