packages feed

avro 0.4.0.0 → 0.4.1.0

raw patch · 14 files changed

+652/−123 lines, 14 filesdep +bifunctorsPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: bifunctors

API changes (from Hackage documentation)

- Data.Avro.FromAvro: badValue :: Value Type -> String -> Result a
+ Data.Avro.Decode.Lazy: (.~:) :: FromLazyAvro a => HashMap Text (LazyValue Type) -> Text -> Result a
+ Data.Avro.Decode.Lazy: Array :: Vector (LazyValue f) -> LazyValue f
+ Data.Avro.Decode.Lazy: Boolean :: Bool -> LazyValue f
+ Data.Avro.Decode.Lazy: Bytes :: ByteString -> LazyValue f
+ Data.Avro.Decode.Lazy: Double :: Double -> LazyValue f
+ Data.Avro.Decode.Lazy: Enum :: f -> Int -> Text -> LazyValue f
+ Data.Avro.Decode.Lazy: Error :: !String -> LazyValue f
+ Data.Avro.Decode.Lazy: Fixed :: f -> ByteString -> LazyValue f
+ Data.Avro.Decode.Lazy: Float :: Float -> LazyValue f
+ Data.Avro.Decode.Lazy: Int :: Int32 -> LazyValue f
+ Data.Avro.Decode.Lazy: Long :: Int64 -> LazyValue f
+ Data.Avro.Decode.Lazy: Map :: HashMap Text (LazyValue f) -> LazyValue f
+ Data.Avro.Decode.Lazy: Null :: LazyValue f
+ Data.Avro.Decode.Lazy: Record :: f -> HashMap Text (LazyValue f) -> LazyValue f
+ Data.Avro.Decode.Lazy: String :: Text -> LazyValue f
+ Data.Avro.Decode.Lazy: Union :: NonEmpty f -> f -> LazyValue f -> LazyValue f
+ Data.Avro.Decode.Lazy: badValue :: Show t => t -> String -> Result a
+ Data.Avro.Decode.Lazy: class HasAvroSchema a => FromLazyAvro a
+ Data.Avro.Decode.Lazy: data LazyValue f
+ Data.Avro.Decode.Lazy: fromLazyAvro :: FromLazyAvro a => LazyValue Type -> Result a
+ Data.Avro.Decode.Lazy.FromLazyAvro: (.~:) :: FromLazyAvro a => HashMap Text (LazyValue Type) -> Text -> Result a
+ Data.Avro.Decode.Lazy.FromLazyAvro: class HasAvroSchema a => FromLazyAvro a
+ Data.Avro.Decode.Lazy.FromLazyAvro: fromLazyAvro :: FromLazyAvro a => LazyValue Type -> Result a
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance (Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro a, Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro b) => Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro (Data.Either.Either a b)
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance (Data.Vector.Unboxed.Base.Unbox a, Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro a) => Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro (Data.Vector.Unboxed.Base.Vector a)
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro Data.ByteString.Internal.ByteString
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro Data.ByteString.Lazy.Internal.ByteString
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro Data.Text.Internal.Lazy.Text
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro Data.Text.Internal.Text
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro GHC.Int.Int32
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro GHC.Int.Int64
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro GHC.Types.Bool
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro GHC.Types.Double
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro GHC.Types.Float
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro GHC.Types.Int
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro a => Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro (Data.HashMap.Base.HashMap Data.Text.Internal.Text a)
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro a => Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro (Data.Map.Internal.Map Data.Text.Internal.Text a)
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro a => Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro (Data.Vector.Vector a)
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro a => Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro (GHC.Maybe.Maybe a)
+ Data.Avro.Decode.Lazy.FromLazyAvro: instance Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro a => Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro [a]
+ Data.Avro.EitherN: instance (Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro a, Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro b, Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro c) => Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro (Data.Avro.EitherN.Either3 a b c)
+ Data.Avro.EitherN: instance (Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro a, Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro b, Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro c, Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro d) => Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro (Data.Avro.EitherN.Either4 a b c d)
+ Data.Avro.EitherN: instance (Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro a, Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro b, Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro c, Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro d, Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro e) => Data.Avro.Decode.Lazy.FromLazyAvro.FromLazyAvro (Data.Avro.EitherN.Either5 a b c d e)
+ Data.Avro.EitherN: instance Data.Bifoldable.Bifoldable (Data.Avro.EitherN.Either3 a)
+ Data.Avro.EitherN: instance Data.Bifoldable.Bifoldable (Data.Avro.EitherN.Either4 a b)
+ Data.Avro.EitherN: instance Data.Bifoldable.Bifoldable (Data.Avro.EitherN.Either5 a b c)
+ Data.Avro.EitherN: instance Data.Bifunctor.Bifunctor (Data.Avro.EitherN.Either3 a)
+ Data.Avro.EitherN: instance Data.Bifunctor.Bifunctor (Data.Avro.EitherN.Either4 a b)
+ Data.Avro.EitherN: instance Data.Bifunctor.Bifunctor (Data.Avro.EitherN.Either5 a b c)
+ Data.Avro.EitherN: instance Data.Bitraversable.Bitraversable (Data.Avro.EitherN.Either3 a)
+ Data.Avro.EitherN: instance Data.Bitraversable.Bitraversable (Data.Avro.EitherN.Either4 a b)
+ Data.Avro.EitherN: instance Data.Bitraversable.Bitraversable (Data.Avro.EitherN.Either5 a b c)
+ Data.Avro.EitherN: instance Data.Foldable.Foldable (Data.Avro.EitherN.Either3 a b)
+ Data.Avro.EitherN: instance Data.Foldable.Foldable (Data.Avro.EitherN.Either4 a b c)
+ Data.Avro.EitherN: instance Data.Foldable.Foldable (Data.Avro.EitherN.Either5 a b c d)
+ Data.Avro.EitherN: instance Data.Traversable.Traversable (Data.Avro.EitherN.Either3 a b)
+ Data.Avro.EitherN: instance Data.Traversable.Traversable (Data.Avro.EitherN.Either4 a b c)
+ Data.Avro.EitherN: instance Data.Traversable.Traversable (Data.Avro.EitherN.Either5 a b c d)
+ Data.Avro.EitherN: instance GHC.Base.Applicative (Data.Avro.EitherN.Either3 a b)
+ Data.Avro.EitherN: instance GHC.Base.Applicative (Data.Avro.EitherN.Either4 a b c)
+ Data.Avro.EitherN: instance GHC.Base.Applicative (Data.Avro.EitherN.Either5 a b c d)
+ Data.Avro.EitherN: instance GHC.Base.Functor (Data.Avro.EitherN.Either3 a b)
+ Data.Avro.EitherN: instance GHC.Base.Functor (Data.Avro.EitherN.Either4 a b c)
+ Data.Avro.EitherN: instance GHC.Base.Functor (Data.Avro.EitherN.Either5 a b c d)
+ Data.Avro.EitherN: instance GHC.Base.Monad (Data.Avro.EitherN.Either3 a b)
+ Data.Avro.EitherN: instance GHC.Base.Monad (Data.Avro.EitherN.Either4 a b c)
+ Data.Avro.EitherN: instance GHC.Base.Monad (Data.Avro.EitherN.Either5 a b c d)
+ Data.Avro.Schema: badValue :: Show t => t -> String -> Result a
- Data.Avro: badValue :: Value Type -> String -> Result a
+ Data.Avro: badValue :: Show t => t -> String -> Result a
- Data.Avro.Decode.Lazy: decodeContainer :: forall a. FromAvro a => ByteString -> [Either String a]
+ Data.Avro.Decode.Lazy: decodeContainer :: forall a. FromLazyAvro a => ByteString -> [Either String a]
- Data.Avro.Decode.Lazy: decodeContainer' :: forall a. FromAvro a => ByteString -> Either String [[Either String a]]
+ Data.Avro.Decode.Lazy: decodeContainer' :: forall a. FromLazyAvro a => ByteString -> Either String [[Either String a]]
- Data.Avro.Decode.Lazy: decodeContainerWithSchema :: FromAvro a => Schema -> ByteString -> [Either String a]
+ Data.Avro.Decode.Lazy: decodeContainerWithSchema :: FromLazyAvro a => Schema -> ByteString -> [Either String a]
- Data.Avro.Decode.Lazy: decodeContainerWithSchema' :: FromAvro a => Schema -> ByteString -> Either String [[Either String a]]
+ Data.Avro.Decode.Lazy: decodeContainerWithSchema' :: FromLazyAvro a => Schema -> ByteString -> Either String [[Either String a]]
- Data.Avro.Deriving: mkAsIsFieldName :: TypeName -> Field -> Text
+ Data.Avro.Deriving: mkAsIsFieldName :: Text -> Field -> Text

Files

ChangeLog.md view
@@ -1,5 +1,9 @@ # Revision history for avro +## HEAD  -- 2018-11-07++* Fixed an omitted data fixture from the cabal sdist+ ## 0.1.0.0  -- YYYY-mm-dd  * First version. Released on an unsuspecting world.
avro.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: fcff216c51da7f4f507714e81688ee3d9c149e101ffbe1b7051f4559eb2feebb+-- hash: e0011cbcce3a1d5f4de5830d2b9f6acb6f32dcacc90e79bf61dbec2530bbf88d  name:           avro-version:        0.4.0.0+version:        0.4.1.0 synopsis:       Avro serialization support for Haskell description:    Avro serialization and deserialization support for Haskell category:       Data@@ -21,17 +21,21 @@     ChangeLog.md     test/data/deconflict/reader.avsc     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+    test/data/namespace-inference.json     test/data/overlay/composite.avsc     test/data/overlay/expectation.avsc     test/data/overlay/primitives.avsc     test/data/record.avsc     test/data/reused.avsc     test/data/small.avsc+    test/data/unions-object-a.json+    test/data/unions-object-b.json     test/data/unions.avsc  source-repository head@@ -56,6 +60,7 @@       Data.Avro.Decode.Lazy       Data.Avro.Decode.Lazy.Convert       Data.Avro.Decode.Lazy.Deconflict+      Data.Avro.Decode.Lazy.FromLazyAvro       Data.Avro.Decode.Lazy.LazyValue       Data.Avro.Decode.Strict       Data.Avro.Decode.Strict.Internal@@ -86,6 +91,7 @@     , array     , base >=4.8 && <5.0     , base16-bytestring+    , bifunctors     , binary     , bytestring     , containers@@ -156,6 +162,7 @@     , avro     , base >=4.6 && <5     , base16-bytestring+    , bifunctors     , binary     , bytestring     , containers
src/Data/Avro/Decode.hs view
@@ -14,38 +14,38 @@   , GetAvro(..)   ) where -import qualified Codec.Compression.Zlib     as Z-import           Control.Monad              (replicateM, when)-import qualified Data.Aeson                 as A-import qualified Data.Array                 as Array-import           Data.Binary.Get            (Get, runGetOrFail)-import qualified Data.Binary.Get            as G-import           Data.Binary.IEEE754        as IEEE+import qualified Codec.Compression.Zlib           as Z+import           Control.Monad                    (replicateM, when)+import qualified Data.Aeson                       as A+import qualified Data.Array                       as Array+import           Data.Binary.Get                  (Get, runGetOrFail)+import qualified Data.Binary.Get                  as G+import           Data.Binary.IEEE754              as IEEE import           Data.Bits-import           Data.ByteString            (ByteString)-import qualified Data.ByteString.Lazy       as BL-import qualified Data.ByteString.Lazy.Char8 as BC-import qualified Data.HashMap.Strict        as HashMap+import           Data.ByteString                  (ByteString)+import qualified Data.ByteString.Lazy             as BL+import qualified Data.ByteString.Lazy.Char8       as BC+import qualified Data.HashMap.Strict              as HashMap import           Data.Int-import           Data.List                  (foldl')-import qualified Data.List.NonEmpty         as NE-import qualified Data.Map                   as Map+import           Data.List                        (foldl')+import qualified Data.List.NonEmpty               as NE+import qualified Data.Map                         as Map import           Data.Maybe-import           Data.Monoid                ((<>))-import qualified Data.Set                   as Set-import           Data.Text                  (Text)-import qualified Data.Text                  as Text-import qualified Data.Text.Encoding         as Text-import qualified Data.Vector                as V-import           Prelude                    as P+import           Data.Monoid                      ((<>))+import qualified Data.Set                         as Set+import           Data.Text                        (Text)+import qualified Data.Text                        as Text+import qualified Data.Text.Encoding               as Text+import qualified Data.Vector                      as V+import           Prelude                          as P  import           Data.Avro.Decode.Get import           Data.Avro.DecodeRaw-import           Data.Avro.Schema     as S-import qualified Data.Avro.Types      as T+import           Data.Avro.Schema                 as S+import qualified Data.Avro.Types                  as T import           Data.Avro.Zag -import Data.Avro.Decode.Strict.Internal+import           Data.Avro.Decode.Strict.Internal  -- |Decode bytes into a 'Value' as described by Schema. decodeAvro :: Schema -> BL.ByteString -> Either String (T.Value Type)
src/Data/Avro/Decode/Lazy.hs view
@@ -23,6 +23,10 @@   , getContainerValuesBytes'   , getAvroOf   , GetAvro(..)+  , FromLazyAvro(..)+  , (.~:)+  , T.LazyValue(..)+  , badValue   ) where  import qualified Codec.Compression.Zlib     as Z@@ -62,12 +66,11 @@ import qualified Data.Avro.Decode.Strict.Internal as DecodeStrict  import Data.Avro.Decode.Get-import Data.Avro.Decode.Lazy.Convert    (toStrictValue)-import Data.Avro.Decode.Lazy.Deconflict as C+import Data.Avro.Decode.Lazy.Convert      (toStrictValue)+import Data.Avro.Decode.Lazy.Deconflict   as C+import Data.Avro.Decode.Lazy.FromLazyAvro import Data.Avro.FromAvro -import Debug.Trace- -- | Decodes the container as a lazy list of values of the requested type. -- -- The schema for the requested type will be de-conflicted with the schema@@ -77,7 +80,7 @@ -- error. This means that the consumer will get all the "good" content from -- the container until the error is detected, then this error and then the list -- is finished.-decodeContainer :: forall a. FromAvro a => BL.ByteString -> [Either String a]+decodeContainer :: forall a. FromLazyAvro a => BL.ByteString -> [Either String a] decodeContainer bs =   let vals = either (\err -> [Left err]) concat (decodeContainer' bs)   in takeWhileInclusive isRight vals@@ -102,7 +105,7 @@ -- continue after errors (most likely it will not be correct). -- -- 'decodeContainer' function makes a choice to stop after the first error.-decodeContainer' :: forall a. FromAvro a => BL.ByteString -> Either String [[Either String a]]+decodeContainer' :: forall a. FromLazyAvro a => BL.ByteString -> Either String [[Either String a]] decodeContainer' = decodeContainerWithSchema' (untag (schema :: Tagged a Schema))  -- | Same as 'decodeContainer' but uses provided schema as a reader schema for the container@@ -110,7 +113,7 @@ -- -- It is up to the user to make sure that the provided schema is compatible with 'a' -- and with the container's writer schema.-decodeContainerWithSchema :: FromAvro a => Schema -> BL.ByteString -> [Either String a]+decodeContainerWithSchema :: FromLazyAvro a => Schema -> BL.ByteString -> [Either String a] decodeContainerWithSchema s bs =   either (\err -> [Left err]) concat (decodeContainerWithSchema' s bs) @@ -119,12 +122,12 @@ -- -- It is up to the user to make sure that the provided schema is compatible with 'a' -- and with the container's writer schema.-decodeContainerWithSchema' :: FromAvro a => Schema -> BL.ByteString -> Either String [[Either String a]]+decodeContainerWithSchema' :: FromLazyAvro a => Schema -> BL.ByteString -> Either String [[Either String a]] decodeContainerWithSchema' readerSchema bs = do   (writerSchema, vals) <- getContainerValues bs   pure $ (fmap . fmap) (convertValue writerSchema) vals   where-    convertValue w v = toStrictValue (C.deconflict w readerSchema v) >>= (resultToEither . fromAvro)+    convertValue w v = resultToEither $ fromLazyAvro (C.deconflict w readerSchema v) -- >>= (resultToEither . fromLazyAvro)  -- |Decode bytes into a 'Value' as described by Schema. decodeAvro :: Schema -> BL.ByteString -> T.LazyValue Type@@ -200,7 +203,7 @@     checkMarker sync bs =       case BL.splitAt nrSyncBytes bs of         (marker, _) | marker /= sync -> Left "Invalid marker, does not match sync bytes."-        (_, rest)   -> Right rest+        (_, rest)                    -> Right rest  getContainerValuesWith :: (Schema -> BL.ByteString -> (BL.ByteString, T.LazyValue Type))                  -> BL.ByteString
+ src/Data/Avro/Decode/Lazy/FromLazyAvro.hs view
@@ -0,0 +1,125 @@+{-# LANGUAGE ConstraintKinds     #-}+{-# LANGUAGE FlexibleInstances   #-}+{-# LANGUAGE MultiWayIf          #-}+{-# LANGUAGE ScopedTypeVariables #-}+module Data.Avro.Decode.Lazy.FromLazyAvro++where++import           Control.Arrow                   (first)+import           Data.Avro.Decode.Lazy.LazyValue as T+import qualified Data.Avro.Encode                as E+import           Data.Avro.HasAvroSchema+import           Data.Avro.Schema                as S+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.Tagged+import           Data.Text                       (Text)+import qualified Data.Text                       as Text+import qualified Data.Text.Lazy                  as TL+import qualified Data.Vector                     as V+import qualified Data.Vector.Unboxed             as U+import           Data.Word++-- |  'FromLazyAvro' is a clone of 'FromAvro' except that+-- it works for lazy values ('LazyValue').+--+-- Decoding from 'LazyValue` directly+-- without converting to strict `Value` and then 'FromAvro'+-- can be very beneficial from the performance point of view.+class HasAvroSchema a => FromLazyAvro a where+  fromLazyAvro :: LazyValue Type -> Result a++--  | Same as '(.:)' but works on `LazyValue`.+(.~:) :: FromLazyAvro a => HashMap.HashMap Text (LazyValue Type) -> Text -> Result a+(.~:) obj key =+  case HashMap.lookup key obj of+    Nothing -> fail $ "Requested field not available: " <> show key+    Just v  -> fromLazyAvro v++instance (FromLazyAvro a, FromLazyAvro b) => FromLazyAvro (Either a b) where+  fromLazyAvro e@(T.Union _ branch x)+    | S.matches branch schemaA = Left  <$> fromLazyAvro x+    | S.matches branch schemaB = Right <$> fromLazyAvro x+    | otherwise              = badValue e "Either"+    where Tagged schemaA = schema :: Tagged a Type+          Tagged schemaB = schema :: Tagged b Type+  fromLazyAvro x = badValue x "Either"++instance FromLazyAvro Bool where+  fromLazyAvro (T.Boolean b) = pure b+  fromLazyAvro v             = badValue v "Bool"++instance FromLazyAvro B.ByteString where+  fromLazyAvro (T.Bytes b) = pure b+  fromLazyAvro v           = badValue v "ByteString"++instance FromLazyAvro BL.ByteString where+  fromLazyAvro (T.Bytes b) = pure (BL.fromStrict b)+  fromLazyAvro v           = badValue v "Lazy ByteString"++instance FromLazyAvro Int where+  fromLazyAvro (T.Int i) | (fromIntegral i :: Integer) < fromIntegral (maxBound :: Int)+                      = pure (fromIntegral i)+  fromLazyAvro (T.Long i) | (fromIntegral i :: Integer) < fromIntegral (maxBound :: Int)+                      = pure (fromIntegral i)+  fromLazyAvro v          = badValue v "Int"++instance FromLazyAvro Int32 where+  fromLazyAvro (T.Int i) = pure (fromIntegral i)+  fromLazyAvro v         = badValue v "Int32"++instance FromLazyAvro Int64 where+  fromLazyAvro (T.Long i) = pure i+  fromLazyAvro (T.Int i)  = pure (fromIntegral i)+  fromLazyAvro v          = badValue v "Int64"++instance FromLazyAvro Double where+  fromLazyAvro (T.Double d) = pure d+  fromLazyAvro v            = badValue v "Double"++instance FromLazyAvro Float where+  fromLazyAvro (T.Float f) = pure f+  fromLazyAvro v           = badValue v "Float"++instance FromLazyAvro a => FromLazyAvro (Maybe a) where+  fromLazyAvro (T.Union (S.Null :| [_])  _ T.Null) = pure Nothing+  fromLazyAvro (T.Union (S.Null :| [_]) _ v)       = Just <$> fromLazyAvro v+  fromLazyAvro v                                   = badValue v "Maybe a"++instance FromLazyAvro a => FromLazyAvro [a] where+  fromLazyAvro (T.Array vec) = mapM fromLazyAvro $ toList vec+  fromLazyAvro v             = badValue v "[a]"++instance FromLazyAvro a => FromLazyAvro (V.Vector a) where+  fromLazyAvro (T.Array vec) = mapM fromLazyAvro vec+  fromLazyAvro v             = badValue v "Vector a"++instance (U.Unbox a, FromLazyAvro a) => FromLazyAvro (U.Vector a) where+  fromLazyAvro (T.Array vec) = U.convert <$> mapM fromLazyAvro vec+  fromLazyAvro v             = badValue v "Unboxed Vector a"++instance FromLazyAvro Text where+  fromLazyAvro (T.String txt) = pure txt+  fromLazyAvro v              = badValue v "Text"++instance FromLazyAvro TL.Text where+  fromLazyAvro (T.String txt) = pure (TL.fromStrict txt)+  fromLazyAvro v              = badValue v "Lazy Text"++instance (FromLazyAvro a) => FromLazyAvro (Map.Map Text a) where+  fromLazyAvro (T.Record _ mp) = mapM fromLazyAvro $ Map.fromList (HashMap.toList mp)+  fromLazyAvro (T.Map mp)      = mapM fromLazyAvro $ Map.fromList (HashMap.toList mp)+  fromLazyAvro v               = badValue v "Map Text a"++instance (FromLazyAvro a) => FromLazyAvro (HashMap.HashMap Text a) where+  fromLazyAvro (T.Record _ mp) = mapM fromLazyAvro mp+  fromLazyAvro (T.Map mp)      = mapM fromLazyAvro mp+  fromLazyAvro v               = badValue v "HashMap Text a"
src/Data/Avro/Deriving.hs view
@@ -32,42 +32,45 @@ ) 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                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 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+ -- | How to treat Avro namespaces in the generated Haskell types. data NamespaceBehavior =     IgnoreNamespaces@@ -185,7 +188,7 @@ -- Person { firstName :: Text } -- @ -- You may want to enable 'DuplicateRecordFields' if you want to use this method.-mkAsIsFieldName :: TypeName -> Field -> Text+mkAsIsFieldName :: Text -> Field -> Text mkAsIsFieldName _ = sanitiseName . updateFirst T.toLower . fldName  -- | Derives Haskell types from the given Avro schema file. These@@ -233,8 +236,9 @@   types     <- traverse (genType o) schemas   hasSchema <- traverse (genHasAvroSchema $ namespaceBehavior o) schemas   fromAvros <- traverse (genFromAvro $ namespaceBehavior o) schemas+  fromLazyAvros <- traverse (genFromLazyAvro $ namespaceBehavior o) schemas   toAvros   <- traverse (genToAvro o) schemas-  pure $ join types <> join hasSchema <> join fromAvros <> join toAvros+  pure $ join types <> join hasSchema <> join fromAvros <> join fromLazyAvros <> join toAvros  -- | Derives "read only" Avro from a given schema file. For a schema -- with a top-level definition @com.example.Foo@, this generates:@@ -265,7 +269,8 @@   types     <- traverse (genType o) schemas   hasSchema <- traverse (genHasAvroSchema $ namespaceBehavior o) schemas   fromAvros <- traverse (genFromAvro $ namespaceBehavior o) schemas-  pure $ join types <> join hasSchema <> join fromAvros+  fromLazyAvros <- traverse (genFromLazyAvro $ namespaceBehavior o) schemas+  pure $ join types <> join hasSchema <> join fromAvros <> join fromLazyAvros  -- | Same as 'deriveAvroWithOptions' but uses 'defaultDeriveOptions' --@@ -318,6 +323,8 @@     Left err  -> fail $ "Unable to generate AVRO for " <> p <> ": " <> err     Right sch -> pure sch +---------------------------- FromAvro -----------------------------------------+ genFromAvro :: NamespaceBehavior -> Schema -> Q [Dec] genFromAvro namespaceBehavior (S.Enum n _ _ _ _) =   [d| instance FromAvro $(conT $ mkDataTypeName namespaceBehavior n) where@@ -348,6 +355,39 @@      )   |] +-------------------------------- FromLazyAvro ---------------------------------+genFromLazyAvro :: NamespaceBehavior -> Schema -> Q [Dec]+genFromLazyAvro namespaceBehavior (S.Enum n _ _ _ _) =+  [d| instance FromLazyAvro $(conT $ mkDataTypeName namespaceBehavior n) where+        fromLazyAvro (LV.Enum _ i _) = $([| pure . toEnum|]) i+        fromLazyAvro value           = $( [|\v -> badValue v $(mkTextLit $ S.renderFullname n)|] ) value+  |]+genFromLazyAvro namespaceBehavior (S.Record n _ _ _ fs) =+  [d| instance FromLazyAvro $(conT $ mkDataTypeName namespaceBehavior n) where+        fromLazyAvro (LV.Record _ r) =+           $(genFromLazyAvroFieldsExp (mkDataTypeName namespaceBehavior n) fs) r+        fromLazyAvro value           = $( [|\v -> badValue v $(mkTextLit $ S.renderFullname n)|] ) value+  |]+genFromLazyAvro namespaceBehavior (S.Fixed n _ s) =+  [d| instance FromLazyAvro $(conT $ mkDataTypeName namespaceBehavior n) where+        fromLazyAvro (LV.Fixed _ v)+          | BS.length v == s = pure $ $(conE (mkDataTypeName namespaceBehavior n)) v+        fromLazyAvro value = $( [|\v -> badValue v $(mkTextLit $ S.renderFullname n)|] ) value+  |]+genFromLazyAvro _ _                             = pure []++genFromLazyAvroFieldsExp :: Name -> [Field] -> Q Exp+genFromLazyAvroFieldsExp n []     = [| (return . return) $(conE n) |]+genFromLazyAvroFieldsExp n (x:xs) =+  [| \r ->+    $(let extract fld = [| r .~: T.pack $(mkTextLit (fldName fld))|]+          ctor = [| $(conE n) <$> $(extract x) |]+      in foldl (\expr fld -> [| $expr <*> $(extract fld) |]) ctor xs+     )+  |]++----------------------- HasAvroSchema ----------------------------------------+ genHasAvroSchema :: NamespaceBehavior -> Schema -> Q [Dec] genHasAvroSchema namespaceBehavior s = do   let sname = mkSchemaValueName namespaceBehavior (name s)@@ -367,8 +407,10 @@          -> Q [Name] newNames base n = sequence [newName (base ++ show i) | i <- [1..n]] +------------------------- ToAvro ----------------------------------------------+ genToAvro :: DeriveOptions -> Schema -> Q [Dec]-genToAvro opts s@(Enum n _ _ vs _) =+genToAvro opts s@(S.Enum n _ _ vs _) =   toAvroInstance (mkSchemaValueName (namespaceBehavior opts) n)   where     conP' = flip conP [] . mkAdtCtorName (namespaceBehavior opts) n@@ -380,7 +422,7 @@                                (normalB [| convert (T.pack $(mkTextLit v))|]) []) <$> vs))               |])       |]-genToAvro opts s@(Record n _ _ _ fs) =+genToAvro opts s@(S.Record n _ _ _ fs) =   toAvroInstance (mkSchemaValueName (namespaceBehavior opts) n)   where     toAvroInstance sname =@@ -397,7 +439,7 @@                 )             |] -genToAvro opts s@(Fixed n _ size) =+genToAvro opts s@(S.Fixed n _ size) =   toAvroInstance (mkSchemaValueName (namespaceBehavior opts) n)   where     toAvroInstance sname =
src/Data/Avro/EitherN.hs view
@@ -1,21 +1,118 @@-{-# LANGUAGE DeriveGeneric  #-}-{-# LANGUAGE ScopedTypeVariables  #-}+{-# LANGUAGE DeriveFoldable      #-}+{-# LANGUAGE DeriveFunctor       #-}+{-# LANGUAGE DeriveGeneric       #-}+{-# LANGUAGE DeriveTraversable   #-}+{-# LANGUAGE ScopedTypeVariables #-}  module Data.Avro.EitherN where  import           Data.Avro+import           Data.Avro.Decode.Lazy as AL import           Data.Avro.Schema-import qualified Data.Avro.Types    as T-import           Data.Tagged+import qualified Data.Avro.Types       as T+import           Data.Bifoldable       (Bifoldable (..))+import           Data.Bifunctor        (Bifunctor (..))+import           Data.Bitraversable    (Bitraversable (..)) import           Data.List.NonEmpty-import           GHC.Generics       (Generic)+import           Data.Tagged+import           GHC.Generics          (Generic) -data Either3 a b c = E3_1 a | E3_2 b | E3_3 c deriving (Eq, Ord, Show, Generic)+data Either3 a b c = E3_1 a | E3_2 b | E3_3 c deriving (Eq, Ord, Show, Generic, Functor, Foldable, Traversable) -data Either4 a b c d = E4_1 a | E4_2 b | E4_3 c | E4_4 d deriving (Eq, Ord, Show, Generic)+data Either4 a b c d = E4_1 a | E4_2 b | E4_3 c | E4_4 d deriving (Eq, Ord, Show, Generic, Functor, Foldable, Traversable) -data Either5 a b c d e = E5_1 a | E5_2 b | E5_3 c | E5_4 d | E5_5 e deriving (Eq, Ord, Show, Generic)+data Either5 a b c d e = E5_1 a | E5_2 b | E5_3 c | E5_4 d | E5_5 e deriving (Eq, Ord, Show, Generic, Functor, Foldable, Traversable) +instance Applicative (Either3 a b) where+  pure = E3_3+  E3_1 a <*> _ = E3_1 a+  E3_2 a <*> _ = E3_2 a+  E3_3 f <*> r = fmap f r++instance Applicative (Either4 a b c) where+  pure = E4_4+  E4_1 a <*> _ = E4_1 a+  E4_2 a <*> _ = E4_2 a+  E4_3 a <*> _ = E4_3 a+  E4_4 f <*> r = fmap f r++instance Applicative (Either5 a b c d) where+  pure = E5_5+  E5_1 a <*> _ = E5_1 a+  E5_2 a <*> _ = E5_2 a+  E5_3 a <*> _ = E5_3 a+  E5_4 a <*> _ = E5_4 a+  E5_5 f <*> r = fmap f r++instance Bifunctor (Either3 a) where+  bimap _ _ (E3_1 a) = E3_1 a+  bimap f _ (E3_2 a) = E3_2 (f a)+  bimap _ g (E3_3 a) = E3_3 (g a)++instance Bifunctor (Either4 a b) where+  bimap _ _ (E4_1 a) = E4_1 a+  bimap _ _ (E4_2 a) = E4_2 a+  bimap f _ (E4_3 a) = E4_3 (f a)+  bimap _ g (E4_4 a) = E4_4 (g a)++instance Bifunctor (Either5 a b c) where+  bimap _ _ (E5_1 a) = E5_1 a+  bimap _ _ (E5_2 a) = E5_2 a+  bimap _ _ (E5_3 a) = E5_3 a+  bimap f _ (E5_4 a) = E5_4 (f a)+  bimap _ g (E5_5 a) = E5_5 (g a)++instance Monad (Either3 a b) where+  E3_1 a >>= _ = E3_1 a+  E3_2 a >>= _ = E3_2 a+  E3_3 a >>= f = f a++instance Monad (Either4 a b c) where+  E4_1 a >>= _ = E4_1 a+  E4_2 a >>= _ = E4_2 a+  E4_3 a >>= _ = E4_3 a+  E4_4 a >>= f = f a++instance Monad (Either5 a b c d) where+  E5_1 a >>= _ = E5_1 a+  E5_2 a >>= _ = E5_2 a+  E5_3 a >>= _ = E5_3 a+  E5_4 a >>= _ = E5_4 a+  E5_5 a >>= f = f a++instance Bifoldable (Either3 a) where+  bifoldMap f _ (E3_2 a) = f a+  bifoldMap _ g (E3_3 a) = g a+  bifoldMap _ _ _        = mempty++instance Bifoldable (Either4 a b) where+  bifoldMap f _ (E4_3 a) = f a+  bifoldMap _ g (E4_4 a) = g a+  bifoldMap _ _ _        = mempty++instance Bifoldable (Either5 a b c) where+  bifoldMap f _ (E5_4 a) = f a+  bifoldMap _ g (E5_5 a) = g a+  bifoldMap _ _ _        = mempty++instance Bitraversable (Either3 a) where+  bitraverse _ _ (E3_1 a) = pure (E3_1 a)+  bitraverse f _ (E3_2 a) = E3_2 <$> f a+  bitraverse _ g (E3_3 a) = E3_3 <$> g a++instance Bitraversable (Either4 a b) where+  bitraverse _ _ (E4_1 a) = pure (E4_1 a)+  bitraverse _ _ (E4_2 a) = pure (E4_2 a)+  bitraverse f _ (E4_3 a) = E4_3 <$> f a+  bitraverse _ g (E4_4 a) = E4_4 <$> g a++instance Bitraversable (Either5 a b c) where+  bitraverse _ _ (E5_1 a) = pure (E5_1 a)+  bitraverse _ _ (E5_2 a) = pure (E5_2 a)+  bitraverse _ _ (E5_3 a) = pure (E5_3 a)+  bitraverse f _ (E5_4 a) = E5_4 <$> f a+  bitraverse _ g (E5_5 a) = E5_5 <$> g a+ instance (HasAvroSchema a, HasAvroSchema b, HasAvroSchema c) => HasAvroSchema (Either3 a b c) where   schema = Tagged $ mkUnion (untag (schema :: Tagged a Type) :| [                              untag (schema :: Tagged b Type),@@ -42,11 +139,11 @@     | matches branch schemaA = E3_1 <$> fromAvro x     | matches branch schemaB = E3_2 <$> fromAvro x     | matches branch schemaC = E3_3 <$> fromAvro x-    | otherwise              = badValue e "either3"+    | otherwise              = badValue e "Either3"     where Tagged schemaA = schema :: Tagged a Type           Tagged schemaB = schema :: Tagged b Type           Tagged schemaC = schema :: Tagged c Type-  fromAvro x = badValue x "either3"+  fromAvro x = badValue x "Either3"  instance (FromAvro a, FromAvro b, FromAvro c, FromAvro d) => FromAvro (Either4 a b c d) where   fromAvro e@(T.Union _ branch x)@@ -54,12 +151,12 @@     | matches branch schemaB = E4_2 <$> fromAvro x     | matches branch schemaC = E4_3 <$> fromAvro x     | matches branch schemaD = E4_4 <$> fromAvro x-    | otherwise              = badValue e "either4"+    | otherwise              = badValue e "Either4"     where Tagged schemaA = schema :: Tagged a Type           Tagged schemaB = schema :: Tagged b Type           Tagged schemaC = schema :: Tagged c Type           Tagged schemaD = schema :: Tagged d Type-  fromAvro x = badValue x "either4"+  fromAvro x = badValue x "Either4"  instance (FromAvro a, FromAvro b, FromAvro c, FromAvro d, FromAvro e) => FromAvro (Either5 a b c d e) where   fromAvro e@(T.Union _ branch x)@@ -68,13 +165,52 @@     | matches branch schemaC = E5_3 <$> fromAvro x     | matches branch schemaD = E5_4 <$> fromAvro x     | matches branch schemaE = E5_5 <$> fromAvro x-    | otherwise              = badValue e "either5"+    | otherwise              = badValue e "Either5"     where Tagged schemaA = schema :: Tagged a Type           Tagged schemaB = schema :: Tagged b Type           Tagged schemaC = schema :: Tagged c Type           Tagged schemaD = schema :: Tagged d Type           Tagged schemaE = schema :: Tagged e Type-  fromAvro x = badValue x "either5"+  fromAvro x = badValue x "Either5"++instance (FromLazyAvro a, FromLazyAvro b, FromLazyAvro c) => FromLazyAvro (Either3 a b c) where+  fromLazyAvro e@(AL.Union _ branch x)+    | matches branch schemaA = E3_1 <$> fromLazyAvro x+    | matches branch schemaB = E3_2 <$> fromLazyAvro x+    | matches branch schemaC = E3_3 <$> fromLazyAvro x+    | otherwise              = badValue e "Either3"+    where Tagged schemaA = schema :: Tagged a Type+          Tagged schemaB = schema :: Tagged b Type+          Tagged schemaC = schema :: Tagged c Type+  fromLazyAvro x = badValue x "Either3"++instance (FromLazyAvro a, FromLazyAvro b, FromLazyAvro c, FromLazyAvro d) => FromLazyAvro (Either4 a b c d) where+  fromLazyAvro e@(AL.Union _ branch x)+    | matches branch schemaA = E4_1 <$> fromLazyAvro x+    | matches branch schemaB = E4_2 <$> fromLazyAvro x+    | matches branch schemaC = E4_3 <$> fromLazyAvro x+    | matches branch schemaD = E4_4 <$> fromLazyAvro x+    | otherwise              = badValue e "Either4"+    where Tagged schemaA = schema :: Tagged a Type+          Tagged schemaB = schema :: Tagged b Type+          Tagged schemaC = schema :: Tagged c Type+          Tagged schemaD = schema :: Tagged d Type+  fromLazyAvro x = badValue x "Either4"++instance (FromLazyAvro a, FromLazyAvro b, FromLazyAvro c, FromLazyAvro d, FromLazyAvro e) => FromLazyAvro (Either5 a b c d e) where+  fromLazyAvro e@(AL.Union _ branch x)+    | matches branch schemaA = E5_1 <$> fromLazyAvro x+    | matches branch schemaB = E5_2 <$> fromLazyAvro x+    | matches branch schemaC = E5_3 <$> fromLazyAvro x+    | matches branch schemaD = E5_4 <$> fromLazyAvro x+    | matches branch schemaE = E5_5 <$> fromLazyAvro x+    | otherwise              = badValue e "Either5"+    where Tagged schemaA = schema :: Tagged a Type+          Tagged schemaB = schema :: Tagged b Type+          Tagged schemaC = schema :: Tagged c Type+          Tagged schemaD = schema :: Tagged d Type+          Tagged schemaE = schema :: Tagged e Type+  fromLazyAvro x = badValue x "Either5"  instance (ToAvro a, ToAvro b, ToAvro c) => ToAvro (Either3 a b c) where   toAvro e =
src/Data/Avro/FromAvro.hs view
@@ -1,39 +1,37 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE ConstraintKinds     #-}+{-# LANGUAGE FlexibleInstances   #-}+{-# LANGUAGE MultiWayIf          #-}+{-# LANGUAGE OverloadedStrings   #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE MultiWayIf #-} module Data.Avro.FromAvro  where -import           Control.Arrow        (first)+import           Control.Arrow           (first)+import qualified Data.Avro.Encode        as E 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.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.List.NonEmpty      (NonEmpty (..))+import qualified Data.Map                as Map+import           Data.Monoid             ((<>)) import           Data.Tagged-import qualified Data.Vector          as V-import qualified Data.Vector.Unboxed  as U+import           Data.Text               (Text)+import qualified Data.Text               as Text+import qualified Data.Text.Lazy          as TL+import qualified Data.Vector             as V+import qualified Data.Vector.Unboxed     as U 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@@ -44,32 +42,39 @@   fromAvro e@(T.Union _ branch x)     | S.matches branch schemaA = Left  <$> fromAvro x     | S.matches branch schemaB = Right <$> fromAvro x-    | otherwise              = badValue e "either"+    | otherwise              = badValue e "Either"     where Tagged schemaA = schema :: Tagged a Type           Tagged schemaB = schema :: Tagged b Type-  fromAvro x = badValue x "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"+  fromAvro v           = badValue v "ByteString"+ instance FromAvro BL.ByteString where   fromAvro (T.Bytes b) = pure (BL.fromStrict b)-  fromAvro v          = badValue v "Lazy ByteString"+  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"+  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"+  fromAvro v          = badValue v "Int64"+ instance FromAvro Double where   fromAvro (T.Double d) = pure d   fromAvro v            = badValue v "Double"@@ -81,11 +86,11 @@ 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"+  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]"+  fromAvro v             = badValue v "[a]"  instance FromAvro a => FromAvro (V.Vector a) where   fromAvro (T.Array vec) = mapM fromAvro vec@@ -97,21 +102,19 @@  instance FromAvro Text where   fromAvro (T.String txt) = pure txt-  fromAvro v = badValue v "Text"+  fromAvro v              = badValue v "Text"  instance FromAvro TL.Text where   fromAvro (T.String txt) = pure (TL.fromStrict txt)-  fromAvro v = badValue v "Lazy Text"+  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"+  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"+  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/Schema.hs view
@@ -28,7 +28,9 @@   , typeName   , buildTypeEnvironment   , extractBindings+   , Result(..)+  , badValue   , resultToEither    , matches@@ -492,6 +494,9 @@  data Result a = Success a | Error String   deriving (Eq, Ord, Show)++badValue :: Show t => t -> String -> Result a+badValue v t = fail $ "Unexpected value for '" <> t <> "': " <> show v  resultToEither :: Result b -> Either String b resultToEither r =
test/Avro/Decode/Lazy/ContainerSpec.hs view
@@ -47,7 +47,7 @@     res <- encodeThenDecode chunks     sequence res `shouldBe` Right msgs -encodeThenDecode :: (FromAvro a, ToAvro a) => [[a]] -> IO [Either String a]+encodeThenDecode :: (FromLazyAvro a, ToAvro a) => [[a]] -> IO [Either String a] encodeThenDecode as =   DL.decodeContainer <$> A.encodeContainer as 
+ test/data/enums-object.json view
@@ -0,0 +1,1 @@+{"id":37,"name":"blarg","reason":"Instead"}
+ test/data/namespace-inference.json view
@@ -0,0 +1,154 @@+[+  {+    "type" : "record",+    "name" : "com.example.Foo",+    "aliases" : ["FooBar", "com.example.not.Bar"],+    "doc" : "An example schema to test namespace handling.",+    "order" : "ascending",+    "fields" : [+      {+        "name" : "bar",+        "aliases" : [],+        "order" : "ascending",+        "type" : {+          "type" : "record",+          "name" : "Bar",+          "order" : "ascending",+          "aliases" : ["Bar2", "com.example.not.Foo"],+          "fields" : [+            {+              "name" : "baz",+              "aliases" : [],+              "order" : "ascending",+              "type" : {+                "type" : "record",+                "order" : "ascending",+                "name" : "com.example.baz.Baz",+                "aliases" : ["com.example.Bazzy"],+                "fields" : [+                  {+                    "name"    : "baz",+                    "type"    : "Baz",+                    "aliases" : [],+                    "order"   : "ascending"+                  },+                  {+                    "name"    : "bazzy",+                    "type"    : "com.example.Bazzy",+                    "aliases" : [],+                    "order"   : "ascending"+                  }+                ]+              }+            },+            {+              "name"    : "bazzy",+              "type"    : "Bazzy",+              "aliases" : [],+              "order"   : "ascending"+            }+          ]+        }+      },+      {+        "name"    : "baz",+        "type"    : "com.example.baz.Baz",+        "aliases" : [],+        "order"   : "ascending"+      }+    ]+  },+  {+    "type" : "record",+    "name" : "Foo",+    "namespace" : "com.example",+    "aliases" : ["FooBar", "com.example.not.Bar"],+    "doc" : "An example schema to test namespace handling.",+    "fields" : [+      {+        "name" : "bar",+        "namespace" : "com.example",+        "type" : {+          "type" : "record",+          "name" : "Bar",+          "aliases" : ["Bar2", "com.example.not.Foo"],+          "fields" : [+            {+              "name" : "baz",+              "type" : {+                "type" : "record",+                "name" : "Baz",+                "namespace" : "com.example.baz",+                "aliases" : ["com.example.Bazzy"],+                "fields" : [+                  {+                    "name" : "baz",+                    "type" : "Baz"+                  },+                  {+                    "name" : "bazzy",+                    "type" : "com.example.Bazzy"+                  }+                ]+              }+            },+            {+              "name" : "bazzy",+              "type" : "Bazzy"+            }+          ]+        }+      },+      {+        "name" : "baz",+        "type" : "com.example.baz.Baz"+      }+    ]+  },+  {+    "type" : "record",+    "name" : "com.example.Foo",+    "namespace" : "should.be.ignored",+    "aliases" : ["FooBar", "com.example.not.Bar"],+    "doc" : "An example schema to test namespace handling.",+    "fields" : [+      {+        "name" : "bar",+        "type" : {+          "type" : "record",+          "name" : "Bar",+          "aliases" : ["Bar2", "com.example.not.Foo"],+          "fields" : [+            {+              "name" : "baz",+              "type" : {+                "type" : "record",+                "name" : "com.example.baz.Baz",+                "namespace" : "should.be.ignored",+                "aliases" : ["com.example.Bazzy"],+                "fields" : [+                  {+                    "name" : "baz",+                    "type" : "Baz"+                  },+                  {+                    "name" : "bazzy",+                    "type" : "com.example.Bazzy"+                  }+                ]+              }+            },+            {+              "name" : "bazzy",+              "type" : "Bazzy"+            }+          ]+        }+      },+      {+        "name" : "baz",+        "type" : "com.example.baz.Baz"+      }+    ]+  }+]
+ test/data/unions-object-a.json view
@@ -0,0 +1,21 @@+{+  "scalars": {+    "string": "blarg"+  },+  "nullable": null,+  "records": {+    "haskell.avro.example.Foo": {+      "stuff": "stuff"+    }+  },+  "sameFields": {+    "haskell.avro.example.Foo": {+      "stuff": "foo stuff"+    }+  },+  "three": { "int": 37 },+  "four": { "string": "foo" },+  "five": {+    "haskell.avro.example.Foo": { "stuff": "foo stuff" }+  }+}
+ test/data/unions-object-b.json view
@@ -0,0 +1,28 @@+{+  "scalars": {+    "long": 37+  },+  "nullable": {+    "int": 42+  },+  "records": {+    "haskell.avro.example.Bar": {+      "stuff": "stuff",+      "things": {+        "stuff": "things"+      }+    }+  },+  "sameFields": {+    "haskell.avro.example.NotFoo": {+      "stuff": "not foo stuff"+    }+  },+  "three": { "long": 37 },+  "four": {+    "haskell.avro.example.Foo": { "stuff" : "foo stuff" }+  },+  "five": {+    "haskell.avro.example.NotFoo": { "stuff": "not foo stuff" }+  }+}